more refactoring

This commit is contained in:
2025-12-30 19:05:02 +01:00
parent ce19309e05
commit f3a69571a2
6 changed files with 179 additions and 131 deletions

View File

@@ -16,7 +16,9 @@ add_library(mosis-service SHARED
external_texture.cpp
quad.cpp
egl_context.cpp
render_target.cpp
logger.cpp
kernel.cpp
glad/src/egl.c
glad/src/gles2.c)
target_include_directories(mosis-service PUBLIC
@@ -33,6 +35,8 @@ add_library(mosis-test SHARED
external_texture.cpp
quad.cpp
egl_context.cpp
render_target.cpp
kernel.cpp
logger.cpp
glad/src/egl.c
glad/src/gles2.c)

46
src/main/cpp/kernel.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "kernel.h"
#include "egl_context.h"
#include "render_target.h"
#include "logger.h"
#include "aidl/com/omixlab/mosis/IMosisListener.h"
#include <android/hardware_buffer.h>
using namespace aidl::com::omixlab::mosis;
using namespace aidl::android::hardware;
void Kernel::main_loop()
{
m_egl_context = std::make_unique<egl::Context>();
if (!m_egl_context->create())
{
Logger::Log("failed to create EGL context");
return;
}
m_render_target = std::make_unique<RenderTarget>();
if (!m_render_target->create_exported(1024, 1024))
{
Logger::Log("failed to create render target");
return;
}
m_render_target->bind();
m_listener->onServiceInitialized(true);
m_aidl_buffer = std::make_unique<HardwareBuffer>();
m_aidl_buffer->reset(m_render_target->hardware_buffer());
m_listener->onBufferAvailable(*m_aidl_buffer);
while (true)
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFinish();
m_listener->onFrameAvailable();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
Kernel::Kernel(const std::shared_ptr<IMosisListener> &listener) : m_listener(listener)
{
m_main_loop_thread = std::thread(&Kernel::main_loop, this);
}
Kernel::~Kernel() = default;

22
src/main/cpp/kernel.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include <thread>
class RenderTarget;
namespace egl { class Context; }
namespace aidl::com::omixlab::mosis { class IMosisListener; }
namespace aidl::android::hardware { struct HardwareBuffer; }
class Kernel
{
std::unique_ptr<egl::Context> m_egl_context;
std::unique_ptr<RenderTarget> m_render_target;
std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener> m_listener;
std::unique_ptr<aidl::android::hardware::HardwareBuffer> m_aidl_buffer;
std::thread m_main_loop_thread;
void main_loop();
public:
explicit Kernel(const std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener>& listener);
virtual ~Kernel();
};

View File

@@ -4,8 +4,8 @@
#include <aidl/com/omixlab/mosis/BnMosisService.h>
#include <aidl/com/omixlab/mosis/IMosisListener.h>
#include <aidl/com/omixlab/mosis/BnMosisListener.h>
#include "egl_context.h"
#include "logger.h"
#include "kernel.h"
#include <glad/egl.h>
#include <glad/gles2.h>
#include <thread>
@@ -24,136 +24,6 @@ public:
}
};
class RenderTarget
{
AHardwareBuffer* hardwareBuffer = nullptr;
GLuint m_framebuffer = 0;
GLuint texture = 0;
public:
bool create(uint32_t width, uint32_t height)
{
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
bool create_exported(uint32_t width, uint32_t height)
{
AHardwareBuffer_Desc desc = {};
desc.width = width;
desc.height = height;
desc.layers = 1;
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER;
if (AHardwareBuffer_allocate(&desc, &hardwareBuffer) != 0)
{
Logger::Log("Failed to allocate hardware buffer");
return false;
}
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer);
EGLImageKHR eglImage = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, nullptr);
if (eglImage == EGL_NO_IMAGE_KHR)
{
AHardwareBuffer_release(hardwareBuffer);
Logger::Log("Failed to create EGL image");
return false;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage);
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
bool status = (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return status;
}
[[nodiscard]] AHardwareBuffer* hardware_buffer()
{
return hardwareBuffer;
}
void bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
}
void unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void destroy()
{
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &m_framebuffer);
}
};
class Kernel
{
std::unique_ptr<egl::Context> m_egl_context;
std::unique_ptr<RenderTarget> m_render_target;
std::shared_ptr<IMosisListener> m_listener;
HardwareBuffer m_aidl_buffer;
std::thread m_main_loop_thread;
void main_loop()
{
m_egl_context = std::make_unique<egl::Context>();
if (!m_egl_context->create())
{
Logger::Log("failed to create EGL context");
return;
}
m_render_target = std::make_unique<RenderTarget>();
if (!m_render_target->create_exported(1024, 1024))
{
Logger::Log("failed to create render target");
return;
}
m_render_target->bind();
m_listener->onServiceInitialized(true);
m_aidl_buffer.reset(m_render_target->hardware_buffer());
m_listener->onBufferAvailable(m_aidl_buffer);
while (true)
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFinish();
m_listener->onFrameAvailable();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
public:
Kernel(const std::shared_ptr<IMosisListener>& listener) : m_listener(listener)
{
m_main_loop_thread = std::thread(&Kernel::main_loop, this);
}
};
class NativeService : public BnMosisService
{
std::unique_ptr<Kernel> m_kernel;

View File

@@ -0,0 +1,89 @@
#include "render_target.h"
#include <android/hardware_buffer.h>
#include <glad/egl.h>
#include "logger.h"
bool RenderTarget::create(uint32_t width, uint32_t height)
{
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
bool RenderTarget::create_exported(uint32_t width, uint32_t height)
{
AHardwareBuffer_Desc desc = {};
desc.width = width;
desc.height = height;
desc.layers = 1;
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER;
if (AHardwareBuffer_allocate(&desc, &hardwareBuffer) != 0)
{
Logger::Log("Failed to allocate hardware buffer");
return false;
}
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer);
EGLImageKHR eglImage = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, nullptr);
if (eglImage == EGL_NO_IMAGE_KHR)
{
AHardwareBuffer_release(hardwareBuffer);
Logger::Log("Failed to create EGL image");
return false;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage);
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
bool status = (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return status;
}
AHardwareBuffer *RenderTarget::hardware_buffer()
{
return hardwareBuffer;
}
void RenderTarget::bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
}
void RenderTarget::unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void RenderTarget::destroy()
{
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &m_framebuffer);
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include <glad/gles2.h>
struct AHardwareBuffer;
class RenderTarget
{
AHardwareBuffer* hardwareBuffer = nullptr;
GLuint m_framebuffer = 0;
GLuint texture = 0;
public:
bool create(uint32_t width, uint32_t height);
bool create_exported(uint32_t width, uint32_t height);
[[nodiscard]] AHardwareBuffer* hardware_buffer();
void bind();
void unbind();
void destroy();
};