--- /dev/null
+# Direct Rendering Example
+
+This is an example showing how to use a Direct Rendering feature of DALi.
+
+Direct Rendering (DR) allows injecting native drawing calls using GL API into
+DALi rendering pipeline so developers can execute custom code. Demo shows a bunch
+of cubes rendered by the custom GL code.
+
+Environmental variables that can be used with the demo:
+
+EGL_ENABLED (default: 0) - old rendering method using EGL native image as an offscreen
+
+UNSAFE_MODE (default: 1) - direct rendering 'unsafe' mode which executes calls on the
+same GL context as DALi rendering (hence is unsafe if not properly cleaned up). If set to 0,
+demo will create isolated GL context for custom rendering.
+
+DR_THREAD_ENABLED (default: 0) - threaded rendering. Runs custom rendering code on a separate
+thread. This method implicitly creates an offscreen buffer to render into.
+
+MAX_CUBES - allows change number of cubes to render
\ No newline at end of file
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
#include <dali-toolkit/dali-toolkit.h>
#include "native-renderer.h"
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/render-tasks/render-task-list.h>
using namespace Dali;
-
+using namespace Dali::Toolkit;
namespace
{
/**
*
* When set to 1 the native image is used for direct rendering (rendering is parallel by default).
*/
-const Toolkit::GlView::BackendMode BACKEND_MODE =
- Toolkit::GlView::BackendMode(GetEnvInt("EGL_ENABLED", 0));
+
+/**
+ * Environment variable: UNSAFE_MODE (default: 1)
+ *
+ * Enables/disables rendering within GL window context rather than creating isolated context
+ */
+
} // namespace
/**
auto w = mWindow.GetSize().GetWidth();
auto h = mWindow.GetSize().GetHeight();
+ mWindow.SetBackgroundColor(Color::BLUE);
NativeRenderer::CreateInfo info{};
info.clearColor = {0, 0, 0, 0};
info.name = "DR";
info.height = h;
info.threaded = (mode != Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING) && (DR_THREAD_ENABLED);
+ // turn off threaded mode if rendering is direct
+ if(mode == Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING)
+ {
+ DALI_LOG_RELEASE_INFO("Threaded and offscreen rendering modes cannot be used with UNSAFE_RENDERING_DIRECT backend!\n");
+ DALI_LOG_RELEASE_INFO("Setting threading and offscreen to false!\n");
+ info.threaded = false;
+ info.offscreen = false;
+ }
+
// Enable threaded rendering
if(info.threaded && mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING)
{
glView.SetProperty(Actor::Property::SIZE, Size(w, h));
glView.SetProperty(Actor::Property::POSITION, pos);
glView.SetRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS);
+
+ std::string strMode = "Backend: Unknown"; // shouldn't happen
+ if(mode == Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING)
+ {
+ strMode = "Backend: UNSAFE_DIRECT_RENDERING";
+ }
+ else if(mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING)
+ {
+ strMode = "Backend: DIRECT_RENDERING (isolated context)";
+ }
+ else if(mode == Dali::Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING)
+ {
+ strMode = "Backend: EGL_IMAGE_OFFSCREEN_RENDERING";
+ }
+ strMode += ", threaded = " + std::to_string(info.threaded) + ", offscreen = " + std::to_string(info.offscreen);
+
+ TextLabel textLabel = TextLabel::New(strMode);
+ textLabel.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE);
+ textLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
+ textLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
+ textLabel.SetProperty(Dali::Actor::Property::NAME, "label");
+ textLabel.SetProperty(Dali::Actor::Property::POSITION, Vector2(0, 0));
+ glView.Add(textLabel);
+
mWindow.Add(glView);
mGlView = glView;
window.GetRootLayer().TouchedSignal().Connect(this, &DirectRenderingExampleController::OnTouch);
mDRView = std::make_unique<RenderView>(window);
- mDRView->Create(Vector2::ZERO, BACKEND_MODE);
+
+ bool eglMode = GetEnvInt("EGL_ENABLED", 0);
+ bool glDirectMode = GetEnvInt("UNSAFE_MODE", 1);
+
+ Toolkit::GlView::BackendMode mode(Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING);
+ if(eglMode)
+ {
+ mode = Dali::Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING;
+ }
+ else if(!glDirectMode)
+ {
+ mode = Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING;
+ }
+
+ mDRView->Create(Vector2::ZERO, mode);
}
bool OnTouch(Actor actor, const TouchEvent& touch)
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
mCreateInfo.clearColor[2],
mCreateInfo.clearColor[3]));
{
- GL(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));
+ GL(glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT));
}
GL(glUseProgram(mProgramId));
- GL(glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES));
- GL(glEnableVertexAttribArray(mVertexLocation));
- GL(glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS));
- GL(glEnableVertexAttribArray(mVertexColourLocation));
-
+ // unbind VAO
+ GL(glBindVertexArray(0));
srand(10);
const auto maxCubes = int(MAX_CUBES);
+ GL(glBindBuffer(GL_ARRAY_BUFFER, 0));
+ GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ GL(glBindBuffer(GL_COPY_READ_BUFFER, 0));
+ GL(glBindBuffer(GL_COPY_WRITE_BUFFER, 0));
+
+
+ GL(glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES));
+ GL(glEnableVertexAttribArray(mVertexLocation));
+ GL(glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS));
+ GL(glEnableVertexAttribArray(mVertexColourLocation));
for(int i = 0; i < int(maxCubes); ++i)
{
GL(matrixIdentityFunction(mModelViewMatrix));