2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/gl-view/gl-view-impl.h>
22 #include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
23 #include <dali/devel-api/adaptor-framework/window-devel.h>
24 #include <dali/devel-api/rendering/renderer-devel.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/object/any.h>
27 #include <dali/public-api/rendering/renderer.h>
28 #include <dali/public-api/rendering/texture-set.h>
29 #include <dali/public-api/rendering/texture.h>
32 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
33 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
41 Dali::Toolkit::GlView GlView::New(Dali::Toolkit::GlView::ColorFormat colorFormat)
43 GlView* impl = new GlView(colorFormat);
44 Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
49 GlView::GlView(Dali::Toolkit::GlView::ColorFormat colorFormat)
50 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
51 mRenderThread(nullptr),
52 mNativeImageQueue(nullptr),
53 mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
54 mColorFormat(colorFormat),
65 mRenderThread->Stop();
66 mRenderThread->Join();
70 void GlView::RegisterGlCallback(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
74 mRenderThread->RegisterGlCallback(initCallback, renderFrameCallback, terminateCallback);
78 void GlView::SetResizeCallback(CallbackBase* resizeCallback)
82 mRenderThread->SetResizeCallback(resizeCallback);
86 bool GlView::SetGraphicsConfig(bool depth, bool stencil, int msaa, Dali::Toolkit::GlView::GraphicsApiVersion version)
95 if(version == Dali::Toolkit::GlView::GraphicsApiVersion::GLES_VERSION_2_0)
106 return mRenderThread->SetGraphicsConfig(depth, stencil, msaa, rVersion);
112 void GlView::SetRenderingMode(Dali::Toolkit::GlView::RenderingMode mode)
114 mRenderingMode = mode;
115 Renderer renderer = Self().GetRendererAt(0);
117 if(mRenderingMode == Dali::Toolkit::GlView::RenderingMode::ON_DEMAND)
119 renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
123 mRenderThread->SetOnDemandRenderMode(true);
128 renderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
132 mRenderThread->SetOnDemandRenderMode(false);
137 Dali::Toolkit::GlView::RenderingMode GlView::GetRenderingMode() const
139 return mRenderingMode;
142 void GlView::RenderOnce()
146 mRenderThread->RenderOnce();
150 void GlView::OnInitialize()
152 //Create NativeImageSourceQueue with the size of 1,1
153 mNativeImageQueue = Dali::NativeImageSourceQueue::New(1, 1, GetColorFormat(mColorFormat));
155 if(!mNativeImageQueue)
157 DALI_LOG_ERROR("NativeImageSourceQueue is NULL");
165 //Create a RenderThread
166 mRenderThread = std::unique_ptr<GlViewRenderThread>(new GlViewRenderThread(mNativeImageQueue));
169 DALI_LOG_ERROR("Fail to create GlView Render Thread!!!!\n");
173 //Adding VisibilityChange Signal.
174 Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &GlView::OnControlVisibilityChanged);
177 void GlView::OnSizeSet(const Vector3& targetSize)
179 Control::OnSizeSet(targetSize);
183 if(mNativeImageQueue)
185 mRenderThread->AcquireSurface();
186 mNativeImageQueue->SetSize(static_cast<uint32_t>(targetSize.x), static_cast<uint32_t>(targetSize.y));
187 mRenderThread->SetSurfaceSize(Vector2(targetSize.x, targetSize.y));
188 mRenderThread->ReleaseSurface();
193 Shader GlView::CreateShader()
195 std::string fragmentShader = std::string(SHADER_GL_VIEW_FRAG);
197 if(mNativeImageQueue)
199 mNativeImageQueue->ApplyNativeFragmentShader(fragmentShader);
202 return Shader::New(SHADER_GL_VIEW_VERT, fragmentShader);
205 void GlView::OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type)
208 if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
212 if(visible && DevelWindow::Get(self).IsVisible())
214 mRenderThread->Resume();
218 mRenderThread->Pause();
224 void GlView::OnWindowVisibilityChanged(Window window, bool visible)
228 if(visible && Self().GetProperty<bool>(Actor::Property::VISIBLE))
230 mRenderThread->Resume();
234 mRenderThread->Pause();
239 void GlView::OnSceneConnection(int depth)
241 Control::OnSceneConnection(depth);
244 Window window = DevelWindow::Get(self);
248 DevelWindow::VisibilityChangedSignal(window).Connect(this, &GlView::OnWindowVisibilityChanged);
253 if(self.GetProperty<bool>(Actor::Property::VISIBLE) && window.IsVisible())
255 mRenderThread->Resume();
260 void GlView::OnSceneDisconnection()
262 Control::OnSceneDisconnection();
265 mRenderThread->Pause();
269 Dali::Geometry GlView::CreateTexturedQuad()
273 Dali::Vector2 position;
276 static const Vertex data[] = {{Dali::Vector2(-0.5f, -0.5f)},
277 {Dali::Vector2(0.5f, -0.5f)},
278 {Dali::Vector2(-0.5f, 0.5f)},
279 {Dali::Vector2(0.5f, 0.5f)}};
281 uint32_t numberOfVertices = sizeof(data) / sizeof(Vertex);
283 Dali::VertexBuffer vertexBuffer;
284 Dali::Property::Map vertexFormat;
285 vertexFormat["aPosition"] = Dali::Property::VECTOR2;
287 //Create a vertex buffer for vertex positions and texture coordinates
288 vertexBuffer = Dali::VertexBuffer::New(vertexFormat);
289 vertexBuffer.SetData(data, numberOfVertices);
291 //Create the geometry
292 Dali::Geometry geometry = Dali::Geometry::New();
293 geometry.AddVertexBuffer(vertexBuffer);
294 geometry.SetType(Dali::Geometry::TRIANGLE_STRIP);
299 void GlView::AddRenderer()
301 if(!mNativeImageQueue)
303 DALI_LOG_ERROR("Target Surface is NULL");
308 Geometry geometry = CreateTexturedQuad();
309 Shader shader = CreateShader();
310 Renderer renderer = Renderer::New(geometry, shader);
312 Texture nativeTexture = Texture::New(*mNativeImageQueue);
313 TextureSet textureSet = TextureSet::New();
314 textureSet.SetTexture(0u, nativeTexture);
316 renderer.SetTextures(textureSet);
318 self.AddRenderer(renderer);
321 Dali::NativeImageSourceQueue::ColorFormat GlView::GetColorFormat(Dali::Toolkit::GlView::ColorFormat format)
325 case Toolkit::GlView::ColorFormat::RGBA8888:
327 return Dali::NativeImageSourceQueue::ColorFormat::RGBA8888;
330 case Toolkit::GlView::ColorFormat::RGB888:
333 return Dali::NativeImageSourceQueue::ColorFormat::RGBX8888;
338 } // namespace Internal
340 } // namespace Toolkit