Commit 8f3f8b4d923d212df56b700b58b4fb69a4860d58
1 parent
9845d6a6
Changed DirectRendering demo to use UNSAFE_DIRECT_RENDERING mode by default.
Switch to different mode due to issues with context fighting on some hardware. New env var: UNSAFE_MODE, default: 1 (enabled) - uses UNSAFE_DIRECT_RENDERING backend. This backend automatically disables threading and offscreen rendering. Change-Id: Ide462e95187dd5a2ace505efc5702515a36d8125
Showing
3 changed files
with
94 additions
and
12 deletions
examples/direct-rendering/README.md
0 → 100644
| 1 | +# Direct Rendering Example | ||
| 2 | + | ||
| 3 | +This is an example showing how to use a Direct Rendering feature of DALi. | ||
| 4 | + | ||
| 5 | +Direct Rendering (DR) allows injecting native drawing calls using GL API into | ||
| 6 | +DALi rendering pipeline so developers can execute custom code. Demo shows a bunch | ||
| 7 | +of cubes rendered by the custom GL code. | ||
| 8 | + | ||
| 9 | +Environmental variables that can be used with the demo: | ||
| 10 | + | ||
| 11 | +EGL_ENABLED (default: 0) - old rendering method using EGL native image as an offscreen | ||
| 12 | + | ||
| 13 | +UNSAFE_MODE (default: 1) - direct rendering 'unsafe' mode which executes calls on the | ||
| 14 | +same GL context as DALi rendering (hence is unsafe if not properly cleaned up). If set to 0, | ||
| 15 | +demo will create isolated GL context for custom rendering. | ||
| 16 | + | ||
| 17 | +DR_THREAD_ENABLED (default: 0) - threaded rendering. Runs custom rendering code on a separate | ||
| 18 | +thread. This method implicitly creates an offscreen buffer to render into. | ||
| 19 | + | ||
| 20 | +MAX_CUBES - allows change number of cubes to render | ||
| 0 | \ No newline at end of file | 21 | \ No newline at end of file |
examples/direct-rendering/direct-rendering-example.cpp
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023 Samsung Electronics Co., Ltd. | 2 | + * Copyright (c) 2024 Samsung Electronics Co., Ltd. |
| 3 | * | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
| @@ -17,9 +17,11 @@ | @@ -17,9 +17,11 @@ | ||
| 17 | 17 | ||
| 18 | #include <dali-toolkit/dali-toolkit.h> | 18 | #include <dali-toolkit/dali-toolkit.h> |
| 19 | #include "native-renderer.h" | 19 | #include "native-renderer.h" |
| 20 | +#include <dali/integration-api/debug.h> | ||
| 20 | 21 | ||
| 22 | +#include <dali/public-api/render-tasks/render-task-list.h> | ||
| 21 | using namespace Dali; | 23 | using namespace Dali; |
| 22 | - | 24 | +using namespace Dali::Toolkit; |
| 23 | namespace | 25 | namespace |
| 24 | { | 26 | { |
| 25 | /** | 27 | /** |
| @@ -44,8 +46,13 @@ const uint32_t DR_THREAD_ENABLED = GetEnvInt("DR_THREAD_ENABLED", 0); | @@ -44,8 +46,13 @@ const uint32_t DR_THREAD_ENABLED = GetEnvInt("DR_THREAD_ENABLED", 0); | ||
| 44 | * | 46 | * |
| 45 | * When set to 1 the native image is used for direct rendering (rendering is parallel by default). | 47 | * When set to 1 the native image is used for direct rendering (rendering is parallel by default). |
| 46 | */ | 48 | */ |
| 47 | -const Toolkit::GlView::BackendMode BACKEND_MODE = | ||
| 48 | - Toolkit::GlView::BackendMode(GetEnvInt("EGL_ENABLED", 0)); | 49 | + |
| 50 | +/** | ||
| 51 | + * Environment variable: UNSAFE_MODE (default: 1) | ||
| 52 | + * | ||
| 53 | + * Enables/disables rendering within GL window context rather than creating isolated context | ||
| 54 | + */ | ||
| 55 | + | ||
| 49 | } // namespace | 56 | } // namespace |
| 50 | 57 | ||
| 51 | /** | 58 | /** |
| @@ -63,6 +70,7 @@ struct RenderView | @@ -63,6 +70,7 @@ struct RenderView | ||
| 63 | auto w = mWindow.GetSize().GetWidth(); | 70 | auto w = mWindow.GetSize().GetWidth(); |
| 64 | auto h = mWindow.GetSize().GetHeight(); | 71 | auto h = mWindow.GetSize().GetHeight(); |
| 65 | 72 | ||
| 73 | + mWindow.SetBackgroundColor(Color::BLUE); | ||
| 66 | NativeRenderer::CreateInfo info{}; | 74 | NativeRenderer::CreateInfo info{}; |
| 67 | info.clearColor = {0, 0, 0, 0}; | 75 | info.clearColor = {0, 0, 0, 0}; |
| 68 | info.name = "DR"; | 76 | info.name = "DR"; |
| @@ -73,6 +81,15 @@ struct RenderView | @@ -73,6 +81,15 @@ struct RenderView | ||
| 73 | info.height = h; | 81 | info.height = h; |
| 74 | info.threaded = (mode != Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING) && (DR_THREAD_ENABLED); | 82 | info.threaded = (mode != Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING) && (DR_THREAD_ENABLED); |
| 75 | 83 | ||
| 84 | + // turn off threaded mode if rendering is direct | ||
| 85 | + if(mode == Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING) | ||
| 86 | + { | ||
| 87 | + DALI_LOG_RELEASE_INFO("Threaded and offscreen rendering modes cannot be used with UNSAFE_RENDERING_DIRECT backend!\n"); | ||
| 88 | + DALI_LOG_RELEASE_INFO("Setting threading and offscreen to false!\n"); | ||
| 89 | + info.threaded = false; | ||
| 90 | + info.offscreen = false; | ||
| 91 | + } | ||
| 92 | + | ||
| 76 | // Enable threaded rendering | 93 | // Enable threaded rendering |
| 77 | if(info.threaded && mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING) | 94 | if(info.threaded && mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING) |
| 78 | { | 95 | { |
| @@ -96,6 +113,30 @@ struct RenderView | @@ -96,6 +113,30 @@ struct RenderView | ||
| 96 | glView.SetProperty(Actor::Property::SIZE, Size(w, h)); | 113 | glView.SetProperty(Actor::Property::SIZE, Size(w, h)); |
| 97 | glView.SetProperty(Actor::Property::POSITION, pos); | 114 | glView.SetProperty(Actor::Property::POSITION, pos); |
| 98 | glView.SetRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS); | 115 | glView.SetRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS); |
| 116 | + | ||
| 117 | + std::string strMode = "Backend: Unknown"; // shouldn't happen | ||
| 118 | + if(mode == Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING) | ||
| 119 | + { | ||
| 120 | + strMode = "Backend: UNSAFE_DIRECT_RENDERING"; | ||
| 121 | + } | ||
| 122 | + else if(mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING) | ||
| 123 | + { | ||
| 124 | + strMode = "Backend: DIRECT_RENDERING (isolated context)"; | ||
| 125 | + } | ||
| 126 | + else if(mode == Dali::Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING) | ||
| 127 | + { | ||
| 128 | + strMode = "Backend: EGL_IMAGE_OFFSCREEN_RENDERING"; | ||
| 129 | + } | ||
| 130 | + strMode += ", threaded = " + std::to_string(info.threaded) + ", offscreen = " + std::to_string(info.offscreen); | ||
| 131 | + | ||
| 132 | + TextLabel textLabel = TextLabel::New(strMode); | ||
| 133 | + textLabel.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE); | ||
| 134 | + textLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); | ||
| 135 | + textLabel.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER); | ||
| 136 | + textLabel.SetProperty(Dali::Actor::Property::NAME, "label"); | ||
| 137 | + textLabel.SetProperty(Dali::Actor::Property::POSITION, Vector2(0, 0)); | ||
| 138 | + glView.Add(textLabel); | ||
| 139 | + | ||
| 99 | mWindow.Add(glView); | 140 | mWindow.Add(glView); |
| 100 | 141 | ||
| 101 | mGlView = glView; | 142 | mGlView = glView; |
| @@ -137,7 +178,21 @@ public: | @@ -137,7 +178,21 @@ public: | ||
| 137 | window.GetRootLayer().TouchedSignal().Connect(this, &DirectRenderingExampleController::OnTouch); | 178 | window.GetRootLayer().TouchedSignal().Connect(this, &DirectRenderingExampleController::OnTouch); |
| 138 | 179 | ||
| 139 | mDRView = std::make_unique<RenderView>(window); | 180 | mDRView = std::make_unique<RenderView>(window); |
| 140 | - mDRView->Create(Vector2::ZERO, BACKEND_MODE); | 181 | + |
| 182 | + bool eglMode = GetEnvInt("EGL_ENABLED", 0); | ||
| 183 | + bool glDirectMode = GetEnvInt("UNSAFE_MODE", 1); | ||
| 184 | + | ||
| 185 | + Toolkit::GlView::BackendMode mode(Dali::Toolkit::GlView::BackendMode::UNSAFE_DIRECT_RENDERING); | ||
| 186 | + if(eglMode) | ||
| 187 | + { | ||
| 188 | + mode = Dali::Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING; | ||
| 189 | + } | ||
| 190 | + else if(!glDirectMode) | ||
| 191 | + { | ||
| 192 | + mode = Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + mDRView->Create(Vector2::ZERO, mode); | ||
| 141 | } | 196 | } |
| 142 | 197 | ||
| 143 | bool OnTouch(Actor actor, const TouchEvent& touch) | 198 | bool OnTouch(Actor actor, const TouchEvent& touch) |
examples/direct-rendering/native-renderer.cpp
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2023 Samsung Electronics Co., Ltd. | 2 | + * Copyright (c) 2024 Samsung Electronics Co., Ltd. |
| 3 | * | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
| @@ -372,18 +372,25 @@ void NativeRenderer::RenderCube(const Dali::RenderCallbackInput& input) | @@ -372,18 +372,25 @@ void NativeRenderer::RenderCube(const Dali::RenderCallbackInput& input) | ||
| 372 | mCreateInfo.clearColor[2], | 372 | mCreateInfo.clearColor[2], |
| 373 | mCreateInfo.clearColor[3])); | 373 | mCreateInfo.clearColor[3])); |
| 374 | { | 374 | { |
| 375 | - GL(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); | 375 | + GL(glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT)); |
| 376 | } | 376 | } |
| 377 | GL(glUseProgram(mProgramId)); | 377 | GL(glUseProgram(mProgramId)); |
| 378 | - GL(glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES)); | ||
| 379 | - GL(glEnableVertexAttribArray(mVertexLocation)); | ||
| 380 | - GL(glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS)); | ||
| 381 | - GL(glEnableVertexAttribArray(mVertexColourLocation)); | ||
| 382 | - | 378 | + // unbind VAO |
| 379 | + GL(glBindVertexArray(0)); | ||
| 383 | srand(10); | 380 | srand(10); |
| 384 | 381 | ||
| 385 | const auto maxCubes = int(MAX_CUBES); | 382 | const auto maxCubes = int(MAX_CUBES); |
| 383 | + GL(glBindBuffer(GL_ARRAY_BUFFER, 0)); | ||
| 384 | + GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); | ||
| 385 | + GL(glBindBuffer(GL_COPY_READ_BUFFER, 0)); | ||
| 386 | + GL(glBindBuffer(GL_COPY_WRITE_BUFFER, 0)); | ||
| 387 | + | ||
| 386 | 388 | ||
| 389 | + | ||
| 390 | + GL(glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES)); | ||
| 391 | + GL(glEnableVertexAttribArray(mVertexLocation)); | ||
| 392 | + GL(glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS)); | ||
| 393 | + GL(glEnableVertexAttribArray(mVertexColourLocation)); | ||
| 387 | for(int i = 0; i < int(maxCubes); ++i) | 394 | for(int i = 0; i < int(maxCubes); ++i) |
| 388 | { | 395 | { |
| 389 | GL(matrixIdentityFunction(mModelViewMatrix)); | 396 | GL(matrixIdentityFunction(mModelViewMatrix)); |