From fc33112035b326d5d3dcf576eb7a461901c79730 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Wed, 16 Mar 2022 14:24:11 +0000 Subject: [PATCH] DirectRendering: - Implemented DrawNative() command for GL - Creating individual context for native rendering (per window) Change-Id: I45e9a3d938d654c1b660370c8cf3b5f91eea9c33 --- .../test-graphics-command-buffer.h | 31 ++++++++- .../test-graphics-controller.cpp | 6 ++ .../graphics/gles-impl/egl-graphics-controller.cpp | 13 +++- dali/internal/graphics/gles-impl/gles-context.cpp | 74 +++++++++++++++++++++- dali/internal/graphics/gles-impl/gles-context.h | 21 +++++- .../gles-impl/gles-graphics-command-buffer.cpp | 7 ++ .../gles-impl/gles-graphics-command-buffer.h | 11 ++++ .../graphics/gles-impl/gles-graphics-types.h | 2 +- 8 files changed, 158 insertions(+), 7 deletions(-) diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h index 96b0021..407dade 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h @@ -65,6 +65,7 @@ enum class CommandType SET_DEPTH_COMPARE_OP = 1 << 24, SET_DEPTH_TEST_ENABLE = 1 << 25, SET_DEPTH_WRITE_ENABLE = 1 << 26, + DRAW_NATIVE = 1 << 27, }; std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op); @@ -123,7 +124,8 @@ struct DrawCallDescriptor { DRAW, DRAW_INDEXED, - DRAW_INDEXED_INDIRECT + DRAW_INDEXED_INDIRECT, + DRAW_NATIVE }; Type type{}; ///< Type of the draw call @@ -166,6 +168,11 @@ struct DrawCallDescriptor uint32_t drawCount; uint32_t stride; } drawIndexedIndirect; + + struct + { + Graphics::DrawNativeInfo drawNativeInfo; + } drawNative; }; }; @@ -265,6 +272,12 @@ struct Command data.bindUniformBuffers = rhs.data.bindUniformBuffers; break; } + case CommandType::DRAW_NATIVE: + { + data.draw.type = rhs.data.draw.type; + data.draw.drawNative = rhs.data.draw.drawNative; + break; + } case CommandType::DRAW: { data.draw.type = rhs.data.draw.type; @@ -418,6 +431,12 @@ struct Command data.bindPipeline = rhs.data.bindPipeline; break; } + case CommandType::DRAW_NATIVE: + { + data.draw.type = rhs.data.draw.type; + data.draw.drawNative = rhs.data.draw.drawNative; + break; + } case CommandType::DRAW: { data.draw.type = rhs.data.draw.type; @@ -800,6 +819,16 @@ public: mCallStack.PushCall("ExecuteCommandBuffers", ""); } + void DrawNative(const Graphics::DrawNativeInfo* drawInfo) + { + mCommands.emplace_back(); + mCommands.back().type = CommandType::DRAW_NATIVE; + auto& cmd = mCommands.back().data.draw; + cmd.type = DrawCallDescriptor::Type::DRAW_NATIVE; + cmd.drawNative.drawNativeInfo = *drawInfo; + mCallStack.PushCall("DrawNative", ""); + } + void Draw( uint32_t vertexCount, uint32_t instanceCount, diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp index bedce18..6a8eab4 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp @@ -693,6 +693,12 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com BindPipeline(currentPipeline); break; } + case CommandType::DRAW_NATIVE: + { + auto info = &cmd.data.draw.drawNative.drawNativeInfo; + CallbackBase::ExecuteReturn(*info->callback, info->userData); + break; + } case CommandType::DRAW: { if(currentPipeline) diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp index 3667844..56c5f2d 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -583,6 +583,17 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm } break; } + case GLES::CommandType::DRAW_NATIVE: + { + auto* info = &cmd.drawNative.drawNativeInfo; + + mCurrentContext->PrepareForNativeRendering(); + + CallbackBase::ExecuteReturn(*info->callback, info->userData); + + mCurrentContext->RestoreFromNativeRendering(); + break; + } } } } diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index de5e058..f38ed4a 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -28,13 +28,16 @@ #include "gles-graphics-render-pass.h" #include "gles-graphics-render-target.h" +#include +#include #include + namespace Dali::Graphics::GLES { struct Context::Impl { - Impl(EglGraphicsController& controller) + explicit Impl(EglGraphicsController& controller) : mController(controller) { } @@ -206,6 +209,12 @@ struct Context::Impl GLStateCache mGlStateCache{}; ///< GL status cache bool mGlContextCreated{false}; ///< True if the OpenGL context has been created + + EGLContext mNativeDrawContext{0u}; ///< Native rendering EGL context compatible with window context + + EGLSurface mCacheDrawReadSurface{0u}; ///< cached 'read' surface + EGLSurface mCacheDrawWriteSurface{0u}; ///< cached 'write' surface + EGLContext mCacheEGLGraphicsContext{0u}; ///< cached window context }; Context::Context(EglGraphicsController& controller) @@ -213,7 +222,15 @@ Context::Context(EglGraphicsController& controller) mImpl = std::make_unique(controller); } -Context::~Context() = default; +Context::~Context() +{ + // Destroy native rendering context if one exists + if(mImpl->mNativeDrawContext) + { + eglDestroyContext(eglGetCurrentDisplay(), mImpl->mNativeDrawContext); + mImpl->mNativeDrawContext = EGL_NO_CONTEXT; + } +} void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) { @@ -954,4 +971,55 @@ void Context::InvalidateCachedPipeline(GLES::Pipeline* pipeline) } } +void Context::PrepareForNativeRendering() +{ + // this should be pretty much constant + auto display = eglGetCurrentDisplay(); + auto drawSurface = eglGetCurrentSurface(EGL_DRAW); + auto readSurface = eglGetCurrentSurface(EGL_READ); + auto context = eglGetCurrentContext(); + + // push the surface and context data to the impl + // It's needed to restore context + if(!mImpl->mCacheEGLGraphicsContext) + { + mImpl->mCacheDrawWriteSurface = drawSurface; + mImpl->mCacheDrawReadSurface = readSurface; + mImpl->mCacheEGLGraphicsContext = context; + } + + if(!mImpl->mNativeDrawContext) + { + EGLint configId{0u}; + EGLint size{0u}; + eglGetConfigs(display, nullptr, 0, &size); + std::vector configs; + configs.resize(size); + eglGetConfigs(display, configs.data(), configs.size(), &size); + + eglQueryContext(display, context, EGL_CONFIG_ID, &configId); + + auto version = int(mImpl->mController.GetGLESVersion()); + + std::vector attribs; + attribs.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); + attribs.push_back(version / 10); + attribs.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); + attribs.push_back(version % 10); + attribs.push_back(EGL_NONE); + + mImpl->mNativeDrawContext = eglCreateContext(display, configs[configId], EGL_NO_CONTEXT, attribs.data()); + } + + eglMakeCurrent(display, drawSurface, readSurface, mImpl->mNativeDrawContext); +} + +void Context::RestoreFromNativeRendering() +{ + auto display = eglGetCurrentDisplay(); + + // bring back original context + eglMakeCurrent(display, mImpl->mCacheDrawWriteSurface, mImpl->mCacheDrawReadSurface, mImpl->mCacheEGLGraphicsContext); +} + } // namespace Dali::Graphics::GLES diff --git a/dali/internal/graphics/gles-impl/gles-context.h b/dali/internal/graphics/gles-impl/gles-context.h index a4c3c8b..12e62cd 100644 --- a/dali/internal/graphics/gles-impl/gles-context.h +++ b/dali/internal/graphics/gles-impl/gles-context.h @@ -2,7 +2,7 @@ #define DALI_GRAPHICS_GLES_CONTEXT_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -164,6 +164,25 @@ public: */ void InvalidateCachedPipeline(GLES::Pipeline* pipeline); + /** + * @brief Sets up EGL context for native rendering + * + * - The native rendering uses dedicated context + * - There is one EGL native rendering context per GLES::Context object + * - Native rendering context is compatible with the window/surface context + * - Native rendering context dies with GLES::Context object + * + * When native rendering is about to be executed, the dedicated EGL context + * is acquired (created or reused) and made current. The Window/Surface context + * is cached to be restored afterwards. + */ + void PrepareForNativeRendering(); + + /** + * @brief Restores window/surface context after native rendering. + */ + void RestoreFromNativeRendering(); + void ActiveTexture(uint32_t textureBindingIndex); void BindTexture(GLenum target, BoundTextureType textureTypeId, uint32_t textureId); void GenerateMipmap(GLenum target); diff --git a/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp b/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp index 8a4cfc9..177b6b9 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp @@ -430,6 +430,13 @@ void CommandBuffer::DrawIndexedIndirect( cmd.drawIndexedIndirect.stride = stride; } +void CommandBuffer::DrawNative(const DrawNativeInfo* drawNativeInfo) +{ + auto command = mCommandPool->AllocateCommand(CommandType::DRAW_NATIVE); + auto& cmd = command->drawNative; + memcpy(&cmd.drawNativeInfo, drawNativeInfo, sizeof(DrawNativeInfo)); +} + void CommandBuffer::Reset() { mCommandPool->Rollback(false); diff --git a/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h b/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h index 983bc9c..07c5561 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h @@ -66,6 +66,7 @@ enum class CommandType SET_DEPTH_COMPARE_OP, SET_DEPTH_TEST_ENABLE, SET_DEPTH_WRITE_ENABLE, + DRAW_NATIVE, }; /** @@ -215,6 +216,11 @@ struct Command { bool enabled; } colorMask; + + struct + { + DrawNativeInfo drawNativeInfo; + } drawNative; }; }; @@ -316,6 +322,11 @@ public: uint32_t stride) override; /** + * @copydoc Dali::Graphics::CommandBuffer::DrawNative + */ + void DrawNative(const DrawNativeInfo* drawNativeInfo) override; + + /** * @copydoc Dali::Graphics::CommandBuffer::Reset */ void Reset() override; diff --git a/dali/internal/graphics/gles-impl/gles-graphics-types.h b/dali/internal/graphics/gles-impl/gles-graphics-types.h index 18069eb..dc90a98 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-types.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-types.h @@ -1527,7 +1527,7 @@ struct DrawCallDescriptor { DRAW, DRAW_INDEXED, - DRAW_INDEXED_INDIRECT + DRAW_INDEXED_INDIRECT, }; Type type{}; ///< Type of the draw call -- 2.7.4