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);
{
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
+ DRAW_NATIVE
};
Type type{}; ///< Type of the draw call
uint32_t drawCount;
uint32_t stride;
} drawIndexedIndirect;
+
+ struct
+ {
+ Graphics::DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
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;
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;
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,
/*
- * 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.
#include "gles-graphics-render-pass.h"
#include "gles-graphics-render-target.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <map>
+
namespace Dali::Graphics::GLES
{
struct Context::Impl
{
- Impl(EglGraphicsController& controller)
+ explicit Impl(EglGraphicsController& controller)
: mController(controller)
{
}
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)
mImpl = std::make_unique<Impl>(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)
{
}
}
+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<EGLConfig> 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<EGLint> 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
#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.
*/
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);