integrate RMLUI library
This commit is contained in:
@@ -9,6 +9,12 @@ set(BINDER_DIR "${ANDROID_SDK}/platforms/android-36/optional/libbinder_ndk_cpp")
|
||||
|
||||
find_package(RmlUi CONFIG REQUIRED)
|
||||
|
||||
#get_cmake_property(_variableNames VARIABLES)
|
||||
#list(SORT _variableNames)
|
||||
#foreach(_variableName ${_variableNames})
|
||||
# message(STATUS "${_variableName}=${${_variableName}}")
|
||||
#endforeach()
|
||||
|
||||
add_library(mosis-service SHARED
|
||||
mosis-service.cpp
|
||||
com/omixlab/mosis/IMosisService.cpp
|
||||
@@ -23,6 +29,11 @@ add_library(mosis-service SHARED
|
||||
kernel.cpp
|
||||
glad/src/egl.c
|
||||
glad/src/gles2.c
|
||||
RmlUi_Renderer_GL3.cpp
|
||||
)
|
||||
target_compile_definitions(mosis-service PUBLIC
|
||||
RMLUI_NUM_MSAA_SAMPLES=2
|
||||
RMLUI_GL3_CUSTOM_LOADER=<glad/gles2.h>
|
||||
)
|
||||
target_include_directories(mosis-service PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
@@ -44,7 +55,6 @@ add_library(mosis-test SHARED
|
||||
quad.cpp
|
||||
egl_context.cpp
|
||||
render_target.cpp
|
||||
kernel.cpp
|
||||
logger.cpp
|
||||
glad/src/egl.c
|
||||
glad/src/gles2.c
|
||||
|
||||
2195
src/main/cpp/RmlUi_Renderer_GL3.cpp
Normal file
2195
src/main/cpp/RmlUi_Renderer_GL3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
241
src/main/cpp/RmlUi_Renderer_GL3.h
Normal file
241
src/main/cpp/RmlUi_Renderer_GL3.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* This source file is part of RmlUi, the HTML/CSS Interface Middleware
|
||||
*
|
||||
* For the latest information, see http://github.com/mikke89/RmlUi
|
||||
*
|
||||
* Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
|
||||
* Copyright (c) 2019-2023 The RmlUi Team, and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RMLUI_BACKENDS_RENDERER_GL3_H
|
||||
#define RMLUI_BACKENDS_RENDERER_GL3_H
|
||||
|
||||
#include <RmlUi/Core/RenderInterface.h>
|
||||
#include <RmlUi/Core/Types.h>
|
||||
#include <bitset>
|
||||
|
||||
enum class ProgramId;
|
||||
enum class UniformId;
|
||||
class RenderLayerStack;
|
||||
namespace Gfx {
|
||||
struct ProgramData;
|
||||
struct FramebufferData;
|
||||
} // namespace Gfx
|
||||
|
||||
class RenderInterface_GL3 : public Rml::RenderInterface {
|
||||
public:
|
||||
RenderInterface_GL3();
|
||||
~RenderInterface_GL3();
|
||||
|
||||
// Returns true if the renderer was successfully constructed.
|
||||
explicit operator bool() const { return static_cast<bool>(program_data); }
|
||||
|
||||
// The viewport should be updated whenever the window size changes.
|
||||
void SetViewport(int viewport_width, int viewport_height, int viewport_offset_x = 0, int viewport_offset_y = 0);
|
||||
|
||||
// Sets up OpenGL states for taking rendering commands from RmlUi.
|
||||
void BeginFrame();
|
||||
// Draws the result to the backbuffer and restores OpenGL state.
|
||||
void EndFrame(unsigned int fb0);
|
||||
|
||||
// Optional, can be used to clear the active framebuffer.
|
||||
void Clear();
|
||||
|
||||
// -- Inherited from Rml::RenderInterface --
|
||||
|
||||
Rml::CompiledGeometryHandle CompileGeometry(Rml::Span<const Rml::Vertex> vertices, Rml::Span<const int> indices) override;
|
||||
void RenderGeometry(Rml::CompiledGeometryHandle handle, Rml::Vector2f translation, Rml::TextureHandle texture) override;
|
||||
void ReleaseGeometry(Rml::CompiledGeometryHandle handle) override;
|
||||
|
||||
Rml::TextureHandle LoadTexture(Rml::Vector2i& texture_dimensions, const Rml::String& source) override;
|
||||
Rml::TextureHandle GenerateTexture(Rml::Span<const Rml::byte> source_data, Rml::Vector2i source_dimensions) override;
|
||||
void ReleaseTexture(Rml::TextureHandle texture_handle) override;
|
||||
|
||||
void EnableScissorRegion(bool enable) override;
|
||||
void SetScissorRegion(Rml::Rectanglei region) override;
|
||||
|
||||
void EnableClipMask(bool enable) override;
|
||||
void RenderToClipMask(Rml::ClipMaskOperation mask_operation, Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation) override;
|
||||
|
||||
void SetTransform(const Rml::Matrix4f* transform) override;
|
||||
|
||||
Rml::LayerHandle PushLayer() override;
|
||||
void CompositeLayers(Rml::LayerHandle source, Rml::LayerHandle destination, Rml::BlendMode blend_mode,
|
||||
Rml::Span<const Rml::CompiledFilterHandle> filters) override;
|
||||
void PopLayer() override;
|
||||
|
||||
Rml::TextureHandle SaveLayerAsTexture() override;
|
||||
|
||||
Rml::CompiledFilterHandle SaveLayerAsMaskImage() override;
|
||||
|
||||
Rml::CompiledFilterHandle CompileFilter(const Rml::String& name, const Rml::Dictionary& parameters) override;
|
||||
void ReleaseFilter(Rml::CompiledFilterHandle filter) override;
|
||||
|
||||
Rml::CompiledShaderHandle CompileShader(const Rml::String& name, const Rml::Dictionary& parameters) override;
|
||||
void RenderShader(Rml::CompiledShaderHandle shader_handle, Rml::CompiledGeometryHandle geometry_handle, Rml::Vector2f translation,
|
||||
Rml::TextureHandle texture) override;
|
||||
void ReleaseShader(Rml::CompiledShaderHandle effect_handle) override;
|
||||
|
||||
// Can be passed to RenderGeometry() to enable texture rendering without changing the bound texture.
|
||||
static constexpr Rml::TextureHandle TextureEnableWithoutBinding = Rml::TextureHandle(-1);
|
||||
// Can be passed to RenderGeometry() to leave the bound texture and used program unchanged.
|
||||
static constexpr Rml::TextureHandle TexturePostprocess = Rml::TextureHandle(-2);
|
||||
|
||||
// -- Utility functions for clients --
|
||||
|
||||
const Rml::Matrix4f& GetTransform() const;
|
||||
void ResetProgram();
|
||||
|
||||
private:
|
||||
void UseProgram(ProgramId program_id);
|
||||
int GetUniformLocation(UniformId uniform_id) const;
|
||||
void SubmitTransformUniform(Rml::Vector2f translation);
|
||||
|
||||
void BlitLayerToPostprocessPrimary(Rml::LayerHandle layer_handle);
|
||||
void RenderFilters(Rml::Span<const Rml::CompiledFilterHandle> filter_handles);
|
||||
|
||||
void SetScissor(Rml::Rectanglei region, bool vertically_flip = false);
|
||||
|
||||
void DrawFullscreenQuad();
|
||||
void DrawFullscreenQuad(Rml::Vector2f uv_offset, Rml::Vector2f uv_scaling = Rml::Vector2f(1.f));
|
||||
|
||||
void RenderBlur(float sigma, const Gfx::FramebufferData& source_destination, const Gfx::FramebufferData& temp, Rml::Rectanglei window_flipped);
|
||||
|
||||
static constexpr size_t MaxNumPrograms = 32;
|
||||
std::bitset<MaxNumPrograms> program_transform_dirty;
|
||||
|
||||
Rml::Matrix4f transform;
|
||||
Rml::Matrix4f projection;
|
||||
|
||||
ProgramId active_program = {};
|
||||
Rml::Rectanglei scissor_state;
|
||||
|
||||
int viewport_width = 0;
|
||||
int viewport_height = 0;
|
||||
int viewport_offset_x = 0;
|
||||
int viewport_offset_y = 0;
|
||||
|
||||
Rml::CompiledGeometryHandle fullscreen_quad_geometry = {};
|
||||
|
||||
Rml::UniquePtr<const Gfx::ProgramData> program_data;
|
||||
|
||||
/*
|
||||
Manages render targets, including the layer stack and postprocessing framebuffers.
|
||||
|
||||
Layers can be pushed and popped, creating new framebuffers as needed. Typically, geometry is rendered to the top
|
||||
layer. The layer framebuffers may have MSAA enabled.
|
||||
|
||||
Postprocessing framebuffers are separate from the layers, and are commonly used to apply texture-wide effects
|
||||
such as filters. They are used both as input and output during rendering, and do not use MSAA.
|
||||
*/
|
||||
class RenderLayerStack {
|
||||
public:
|
||||
RenderLayerStack();
|
||||
~RenderLayerStack();
|
||||
|
||||
// Push a new layer. All references to previously retrieved layers are invalidated.
|
||||
Rml::LayerHandle PushLayer();
|
||||
|
||||
// Pop the top layer. All references to previously retrieved layers are invalidated.
|
||||
void PopLayer();
|
||||
|
||||
const Gfx::FramebufferData& GetLayer(Rml::LayerHandle layer) const;
|
||||
const Gfx::FramebufferData& GetTopLayer() const;
|
||||
Rml::LayerHandle GetTopLayerHandle() const;
|
||||
|
||||
const Gfx::FramebufferData& GetPostprocessPrimary() { return EnsureFramebufferPostprocess(0); }
|
||||
const Gfx::FramebufferData& GetPostprocessSecondary() { return EnsureFramebufferPostprocess(1); }
|
||||
const Gfx::FramebufferData& GetPostprocessTertiary() { return EnsureFramebufferPostprocess(2); }
|
||||
const Gfx::FramebufferData& GetBlendMask() { return EnsureFramebufferPostprocess(3); }
|
||||
|
||||
void SwapPostprocessPrimarySecondary();
|
||||
|
||||
void BeginFrame(int new_width, int new_height);
|
||||
void EndFrame();
|
||||
|
||||
private:
|
||||
void DestroyFramebuffers();
|
||||
const Gfx::FramebufferData& EnsureFramebufferPostprocess(int index);
|
||||
|
||||
int width = 0, height = 0;
|
||||
|
||||
// The number of active layers is manually tracked since we re-use the framebuffers stored in the fb_layers stack.
|
||||
int layers_size = 0;
|
||||
|
||||
Rml::Vector<Gfx::FramebufferData> fb_layers;
|
||||
Rml::Vector<Gfx::FramebufferData> fb_postprocess;
|
||||
};
|
||||
|
||||
RenderLayerStack render_layers;
|
||||
|
||||
struct GLStateBackup {
|
||||
bool enable_cull_face;
|
||||
bool enable_blend;
|
||||
bool enable_stencil_test;
|
||||
bool enable_scissor_test;
|
||||
bool enable_depth_test;
|
||||
|
||||
int viewport[4];
|
||||
int scissor[4];
|
||||
|
||||
int active_texture;
|
||||
|
||||
int stencil_clear_value;
|
||||
float color_clear_value[4];
|
||||
unsigned char color_writemask[4];
|
||||
|
||||
int blend_equation_rgb;
|
||||
int blend_equation_alpha;
|
||||
int blend_src_rgb;
|
||||
int blend_dst_rgb;
|
||||
int blend_src_alpha;
|
||||
int blend_dst_alpha;
|
||||
|
||||
struct Stencil {
|
||||
int func;
|
||||
int ref;
|
||||
int value_mask;
|
||||
int writemask;
|
||||
int fail;
|
||||
int pass_depth_fail;
|
||||
int pass_depth_pass;
|
||||
};
|
||||
Stencil stencil_front;
|
||||
Stencil stencil_back;
|
||||
};
|
||||
GLStateBackup glstate_backup = {};
|
||||
};
|
||||
|
||||
/**
|
||||
Helper functions for the OpenGL 3 renderer.
|
||||
*/
|
||||
namespace RmlGL3 {
|
||||
|
||||
// Loads OpenGL functions. Optionally, the out message describes the loaded GL version or an error message on failure.
|
||||
bool Initialize(Rml::String* out_message = nullptr);
|
||||
|
||||
// Unloads OpenGL functions.
|
||||
void Shutdown();
|
||||
|
||||
} // namespace RmlGL3
|
||||
|
||||
#endif
|
||||
@@ -19,3 +19,8 @@ std::vector<uint8_t> AssetsManager::ReadAll(const std::string &filename)
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AAssetManager *AssetsManager::Native()
|
||||
{
|
||||
return m_asset_manager;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <vector>
|
||||
|
||||
struct AAssetManager;
|
||||
struct AAsset;
|
||||
|
||||
class AssetsManager
|
||||
{
|
||||
@@ -9,4 +10,5 @@ class AssetsManager
|
||||
public:
|
||||
static void Init(AAssetManager* asset_manager);
|
||||
static std::vector<uint8_t> ReadAll(const std::string& filename);
|
||||
static AAssetManager* Native();
|
||||
};
|
||||
|
||||
@@ -33,12 +33,12 @@ void ExternalTexture::destroy()
|
||||
|
||||
void ExternalTexture::bind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
|
||||
}
|
||||
|
||||
void ExternalTexture::unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
}
|
||||
|
||||
GLuint ExternalTexture::texture_id() const
|
||||
|
||||
@@ -2,12 +2,89 @@
|
||||
#include "egl_context.h"
|
||||
#include "render_target.h"
|
||||
#include "logger.h"
|
||||
#include "assets_manager.h"
|
||||
#include "aidl/com/omixlab/mosis/IMosisListener.h"
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <RmlUi/Core.h>
|
||||
#include "RmlUi_Renderer_GL3.h"
|
||||
#include <ranges>
|
||||
#include <span>
|
||||
|
||||
using namespace aidl::com::omixlab::mosis;
|
||||
using namespace aidl::android::hardware;
|
||||
|
||||
class AssetFilesInterface : public Rml::FileInterface
|
||||
{
|
||||
public:
|
||||
static AssetFilesInterface& Instance()
|
||||
{
|
||||
static AssetFilesInterface instance;
|
||||
return instance;
|
||||
}
|
||||
Rml::FileHandle Open(const Rml::String &path) override
|
||||
{
|
||||
AAssetManager* am = AssetsManager::Native();
|
||||
AAsset* asset = AAssetManager_open(am, path.c_str(), AASSET_MODE_BUFFER);
|
||||
return reinterpret_cast<Rml::FileHandle>(asset);
|
||||
}
|
||||
void Close(Rml::FileHandle file) override
|
||||
{
|
||||
AAsset* asset = reinterpret_cast<AAsset*>(file);
|
||||
AAsset_close(asset);
|
||||
}
|
||||
size_t Read(void *buffer, size_t size, Rml::FileHandle file) override
|
||||
{
|
||||
AAsset* asset = reinterpret_cast<AAsset*>(file);
|
||||
return AAsset_read(asset, buffer, size);
|
||||
}
|
||||
bool Seek(Rml::FileHandle file, long offset, int origin) override
|
||||
{
|
||||
AAsset* asset = reinterpret_cast<AAsset*>(file);
|
||||
off_t new_cursor = AAsset_seek(asset, offset, origin);
|
||||
return new_cursor != -1;
|
||||
}
|
||||
size_t Tell(Rml::FileHandle file) override
|
||||
{
|
||||
AAsset* asset = reinterpret_cast<AAsset*>(file);
|
||||
return AAsset_seek(asset, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
size_t Length(Rml::FileHandle file) override
|
||||
{
|
||||
AAsset* asset = reinterpret_cast<AAsset*>(file);
|
||||
return AAsset_getLength(asset);
|
||||
}
|
||||
|
||||
bool LoadFile(const Rml::String &path, Rml::String &out_data) override
|
||||
{
|
||||
AAssetManager* am = AssetsManager::Native();
|
||||
AAsset* asset = AAssetManager_open(am, path.c_str(), AASSET_MODE_BUFFER);
|
||||
if (!asset)
|
||||
return false;
|
||||
out_data.resize(AAsset_getLength(asset));
|
||||
auto data_ptr = static_cast<const char*>(AAsset_getBuffer(asset));
|
||||
std::span data = std::span(data_ptr, out_data.size());
|
||||
std::ranges::copy(data, out_data.begin());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SystemInterface : public Rml::SystemInterface
|
||||
{
|
||||
public:
|
||||
static SystemInterface& Instance()
|
||||
{
|
||||
static SystemInterface instance;
|
||||
return instance;
|
||||
}
|
||||
bool LogMessage(Rml::Log::Type type, const Rml::String &message) override
|
||||
{
|
||||
Logger::Log(std::format("RMLUI: {}", message));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void Kernel::main_loop()
|
||||
{
|
||||
m_egl_context = std::make_unique<egl::Context>();
|
||||
@@ -30,12 +107,45 @@ void Kernel::main_loop()
|
||||
for (const auto& [pid, l] : m_listeners)
|
||||
l->onBufferAvailable(*m_aidl_buffer);
|
||||
|
||||
RenderInterface_GL3 rmlui_render_interface;
|
||||
if (!rmlui_render_interface)
|
||||
{
|
||||
Logger::Log("failed to create render interface");
|
||||
return;
|
||||
}
|
||||
Rml::SetRenderInterface(&rmlui_render_interface);
|
||||
Rml::SetFileInterface(&AssetFilesInterface::Instance());
|
||||
Rml::SetSystemInterface(&SystemInterface::Instance());
|
||||
Rml::Initialise();
|
||||
Rml::Context* context = Rml::CreateContext("default", Rml::Vector2i(1024, 1024));
|
||||
if (!context)
|
||||
{
|
||||
Logger::Log("RMLUI failed to create a context");
|
||||
Rml::Shutdown();
|
||||
return;
|
||||
}
|
||||
Rml::LoadFontFace("Roboto/static/Roboto_Condensed-Regular.ttf");
|
||||
Rml::LoadFontFace("LatoLatin-Regular.ttf");
|
||||
|
||||
// Now we are ready to load our document.
|
||||
Rml::ElementDocument* document = context->LoadDocument("demo.rml");
|
||||
document->Show();
|
||||
|
||||
while (true)
|
||||
{
|
||||
static float angle = 0.0f;
|
||||
angle += 0.1f;
|
||||
m_render_target->bind();
|
||||
glClearColor(fabs(sin(angle)), 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, 1024, 1024);
|
||||
|
||||
context->Update();
|
||||
rmlui_render_interface.SetViewport(1024, 1024);
|
||||
rmlui_render_interface.BeginFrame();
|
||||
context->Render();
|
||||
rmlui_render_interface.EndFrame(m_render_target->framebuffer());
|
||||
|
||||
glFinish();
|
||||
{
|
||||
std::lock_guard _lock(m_mutex);
|
||||
@@ -44,6 +154,7 @@ void Kernel::main_loop()
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
Rml::Shutdown();
|
||||
}
|
||||
|
||||
Kernel::Kernel(const std::shared_ptr<IMosisListener> &listener)
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
#include <aidl/com/omixlab/mosis/BnMosisListener.h>
|
||||
#include "logger.h"
|
||||
#include "kernel.h"
|
||||
#include "assets_manager.h"
|
||||
#include <glad/egl.h>
|
||||
#include <glad/gles2.h>
|
||||
#include <thread>
|
||||
#include <android/asset_manager_jni.h>
|
||||
|
||||
using namespace aidl::com::omixlab::mosis;
|
||||
using namespace aidl::android::hardware;
|
||||
@@ -58,3 +60,11 @@ Java_com_omixlab_mosis_NativeService_getBinderNative(JNIEnv *env, jobject thiz)
|
||||
static std::shared_ptr<NativeService> g_service = ndk::SharedRefBase::make<NativeService>();
|
||||
return AIBinder_toJavaBinder(env, g_service->asBinder().get());
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_omixlab_mosis_NativeService_setAssetManager(JNIEnv *env, jobject thiz,
|
||||
jobject asset_manager)
|
||||
{
|
||||
AssetsManager::Init(AAssetManager_fromJava(env, asset_manager));
|
||||
}
|
||||
@@ -87,3 +87,8 @@ void RenderTarget::destroy()
|
||||
glDeleteTextures(1, &texture);
|
||||
glDeleteFramebuffers(1, &m_framebuffer);
|
||||
}
|
||||
|
||||
GLuint RenderTarget::framebuffer() const
|
||||
{
|
||||
return m_framebuffer;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public:
|
||||
bool create(uint32_t width, uint32_t height);
|
||||
bool create_exported(uint32_t width, uint32_t height);
|
||||
[[nodiscard]] AHardwareBuffer* hardware_buffer();
|
||||
[[nodiscard]] GLuint framebuffer() const;
|
||||
void bind();
|
||||
void unbind();
|
||||
void destroy();
|
||||
|
||||
Reference in New Issue
Block a user