2 * Copyright (c) 2024 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 auto* impl = new Dali::Toolkit::Internal::GlView(colorFormat);
44 Dali::Toolkit::GlView handle = Dali::Toolkit::GlView(*impl);
49 GlView::GlView(Dali::Toolkit::GlView::ColorFormat colorFormat)
50 : Dali::Toolkit::Internal::GlViewImpl(Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING),
51 mRenderThread(nullptr),
52 mNativeImageQueue(nullptr),
53 mRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS),
54 mColorFormat(colorFormat),
65 mRenderThread->Stop();
66 mRenderThread->Join();
70 void GlView::RegisterGlCallbacks(CallbackBase* initCallback, CallbackBase* renderFrameCallback, CallbackBase* terminateCallback)
74 mRenderThread->RegisterGlCallbacks(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::BindTextureResources(std::vector<Dali::Texture> textures)
152 // Not supported in the indirect mode
155 void GlView::OnInitialize()
157 //Create NativeImageSourceQueue with the size of 1,1
158 mNativeImageQueue = Dali::NativeImageSourceQueue::New(1, 1, GetColorFormat(mColorFormat));
160 if(!mNativeImageQueue)
162 DALI_LOG_ERROR("NativeImageSourceQueue is NULL");
170 //Create a RenderThread
171 mRenderThread = std::unique_ptr<GlViewRenderThread>(new GlViewRenderThread(mNativeImageQueue));
174 DALI_LOG_ERROR("Fail to create GlView Render Thread!!!!\n");
178 //Adding VisibilityChange Signal.
179 Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &GlView::OnControlVisibilityChanged);
182 void GlView::OnSizeSet(const Vector3& targetSize)
184 Control::OnSizeSet(targetSize);
188 if(mNativeImageQueue)
190 mRenderThread->AcquireSurface();
191 mNativeImageQueue->SetSize(static_cast<uint32_t>(targetSize.x), static_cast<uint32_t>(targetSize.y));
192 mRenderThread->SetSurfaceSize(Vector2(targetSize.x, targetSize.y));
193 mRenderThread->ReleaseSurface();
198 Shader GlView::CreateShader()
200 std::string fragmentShader = std::string(SHADER_GL_VIEW_FRAG);
202 if(mNativeImageQueue)
204 mNativeImageQueue->ApplyNativeFragmentShader(fragmentShader);
207 return Shader::New(SHADER_GL_VIEW_VERT, fragmentShader, Shader::Hint::NONE, "GL_VIEW");
210 void GlView::OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type)
213 if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
217 if(visible && DevelWindow::Get(self).IsVisible())
219 mRenderThread->Resume();
223 mRenderThread->Pause();
229 void GlView::OnWindowVisibilityChanged(Window window, bool visible)
233 if(visible && Self().GetProperty<bool>(Actor::Property::VISIBLE))
235 mRenderThread->Resume();
239 mRenderThread->Pause();
244 void GlView::OnSceneConnection(int depth)
246 Control::OnSceneConnection(depth);
249 Window window = DevelWindow::Get(self);
253 mPlacementWindow = window;
254 DevelWindow::VisibilityChangedSignal(window).Connect(this, &GlView::OnWindowVisibilityChanged);
259 if(self.GetProperty<bool>(Actor::Property::VISIBLE) && window.IsVisible())
261 mRenderThread->Resume();
266 void GlView::OnSceneDisconnection()
268 Control::OnSceneDisconnection();
271 mRenderThread->Pause();
274 Window window = mPlacementWindow.GetHandle();
277 DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &GlView::OnWindowVisibilityChanged);
278 mPlacementWindow.Reset();
282 Dali::Geometry GlView::CreateTexturedQuad()
286 Dali::Vector2 position;
289 static const Vertex data[] = {{Dali::Vector2(-0.5f, -0.5f)},
290 {Dali::Vector2(0.5f, -0.5f)},
291 {Dali::Vector2(-0.5f, 0.5f)},
292 {Dali::Vector2(0.5f, 0.5f)}};
294 uint32_t numberOfVertices = sizeof(data) / sizeof(Vertex);
296 Dali::VertexBuffer vertexBuffer;
297 Dali::Property::Map vertexFormat;
298 vertexFormat["aPosition"] = Dali::Property::VECTOR2;
300 //Create a vertex buffer for vertex positions and texture coordinates
301 vertexBuffer = Dali::VertexBuffer::New(vertexFormat);
302 vertexBuffer.SetData(data, numberOfVertices);
304 //Create the geometry
305 Dali::Geometry geometry = Dali::Geometry::New();
306 geometry.AddVertexBuffer(vertexBuffer);
307 geometry.SetType(Dali::Geometry::TRIANGLE_STRIP);
312 void GlView::AddRenderer()
314 if(!mNativeImageQueue)
316 DALI_LOG_ERROR("Target Surface is NULL");
321 Geometry geometry = CreateTexturedQuad();
322 Shader shader = CreateShader();
323 Renderer renderer = Renderer::New(geometry, shader);
325 Texture nativeTexture = Texture::New(*mNativeImageQueue);
326 TextureSet textureSet = TextureSet::New();
327 textureSet.SetTexture(0u, nativeTexture);
329 renderer.SetTextures(textureSet);
331 self.AddRenderer(renderer);
334 Dali::NativeImageSourceQueue::ColorFormat GlView::GetColorFormat(Dali::Toolkit::GlView::ColorFormat format)
338 case Toolkit::GlView::ColorFormat::RGBA8888:
340 return Dali::NativeImageSourceQueue::ColorFormat::RGBA8888;
343 case Toolkit::GlView::ColorFormat::RGB888:
346 return Dali::NativeImageSourceQueue::ColorFormat::RGBX8888;
351 } // namespace Internal
353 } // namespace Toolkit