async tasks

This commit is contained in:
2025-12-31 16:12:43 +01:00
parent f3a69571a2
commit 3a410775b5
6 changed files with 111 additions and 12 deletions

View File

@@ -69,6 +69,7 @@ bool egl::Context::create(ANativeWindow* window)
if (window) if (window)
{ {
m_surface = eglCreateWindowSurface(m_display, m_config, window, nullptr); m_surface = eglCreateWindowSurface(m_display, m_config, window, nullptr);
ANativeWindow_acquire(window);
m_native_window = window; m_native_window = window;
} }
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context)) if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
@@ -129,3 +130,34 @@ void egl::Context::swap()
{ {
eglSwapBuffers(m_display, m_surface); eglSwapBuffers(m_display, m_surface);
} }
bool egl::Context::make_current(ANativeWindow* window)
{
if (window == m_native_window)
{
return true;
}
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_surface != EGL_NO_SURFACE)
{
eglDestroySurface(m_display, m_surface);
m_surface = EGL_NO_SURFACE;
}
if (m_native_window)
{
ANativeWindow_release(m_native_window);
m_native_window = nullptr;
}
if (window)
{
m_surface = eglCreateWindowSurface(m_display, m_config, window, nullptr);
ANativeWindow_acquire(window);
m_native_window = window;
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
{
Logger::Log("eglMakeCurrent failed");
return false;
}
}
return true;
}

View File

@@ -20,5 +20,6 @@ public:
bool create(ANativeWindow* window = nullptr); bool create(ANativeWindow* window = nullptr);
void destroy(); void destroy();
void swap(); void swap();
bool make_current(ANativeWindow* window = nullptr);
}; };
} }

View File

@@ -30,10 +30,15 @@ void Kernel::main_loop()
while (true) while (true)
{ {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); static float angle = 0.0f;
angle += 0.1f;
glClearColor(fabs(sin(angle)), 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glFinish(); glFinish();
{
std::lock_guard _lock(m_mutex);
m_listener->onFrameAvailable(); m_listener->onFrameAvailable();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
} }
@@ -43,4 +48,12 @@ Kernel::Kernel(const std::shared_ptr<IMosisListener> &listener) : m_listener(lis
m_main_loop_thread = std::thread(&Kernel::main_loop, this); m_main_loop_thread = std::thread(&Kernel::main_loop, this);
} }
void Kernel::set_listener(const std::shared_ptr<IMosisListener> &listener)
{
std::lock_guard _lock(m_mutex);
m_listener = listener;
m_listener->onServiceInitialized(true);
m_listener->onBufferAvailable(*m_aidl_buffer);
}
Kernel::~Kernel() = default; Kernel::~Kernel() = default;

View File

@@ -14,9 +14,11 @@ class Kernel
std::unique_ptr<RenderTarget> m_render_target; std::unique_ptr<RenderTarget> m_render_target;
std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener> m_listener; std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener> m_listener;
std::unique_ptr<aidl::android::hardware::HardwareBuffer> m_aidl_buffer; std::unique_ptr<aidl::android::hardware::HardwareBuffer> m_aidl_buffer;
std::mutex m_mutex;
std::thread m_main_loop_thread; std::thread m_main_loop_thread;
void main_loop(); void main_loop();
public: public:
explicit Kernel(const std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener>& listener); explicit Kernel(const std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener>& listener);
virtual ~Kernel(); virtual ~Kernel();
void set_listener(const std::shared_ptr<aidl::com::omixlab::mosis::IMosisListener>& listener);
}; };

View File

@@ -42,6 +42,11 @@ public:
m_kernel = std::make_unique<Kernel>(listener); m_kernel = std::make_unique<Kernel>(listener);
*_aidl_return = true; *_aidl_return = true;
} }
else
{
m_kernel->set_listener(listener);
*_aidl_return = true;
}
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
}; };

View File

@@ -17,6 +17,8 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <future>
#include <functional>
using namespace aidl::com::omixlab::mosis; using namespace aidl::com::omixlab::mosis;
using namespace aidl::android::hardware; using namespace aidl::android::hardware;
@@ -28,6 +30,8 @@ class Renderer : public BnMosisListener
std::unique_ptr<Shader> m_quad_shader; std::unique_ptr<Shader> m_quad_shader;
std::unique_ptr<Quad> m_quad; std::unique_ptr<Quad> m_quad;
AHardwareBuffer* m_hwbuffer = nullptr; AHardwareBuffer* m_hwbuffer = nullptr;
std::vector<std::function<void()>> m_task_queue;
std::mutex m_task_mutex;
std::thread m_render_loop; std::thread m_render_loop;
bool m_active = false; bool m_active = false;
void render_loop(ANativeWindow* window) void render_loop(ANativeWindow* window)
@@ -39,14 +43,7 @@ class Renderer : public BnMosisListener
m_active = true; m_active = true;
while (m_active) while (m_active)
{ {
if (m_hwbuffer && !m_texture) process_tasks();
{
m_texture = std::make_unique<ExternalTexture>();
if (!m_texture->create(m_hwbuffer))
{
Logger::Log("Failed to create texture");
}
}
render_frame(); render_frame();
} }
} }
@@ -62,9 +59,18 @@ class Renderer : public BnMosisListener
m_quad = std::make_unique<Quad>(); m_quad = std::make_unique<Quad>();
m_quad->create(); m_quad->create();
} }
void process_tasks()
{
std::lock_guard _lock(m_task_mutex);
for (auto& task : m_task_queue)
{
task();
}
m_task_queue.clear();
}
void render_frame() void render_frame()
{ {
glClearColor(0.f, 0.5f, 0.5f, 1.0f); glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
if (m_texture) if (m_texture)
{ {
@@ -88,9 +94,37 @@ public:
m_active = false; m_active = false;
if (m_render_loop.joinable()) if (m_render_loop.joinable())
m_render_loop.join(); m_render_loop.join();
if (m_egl_context)
m_egl_context->destroy(); m_egl_context->destroy();
m_egl_context.reset(); m_egl_context.reset();
} }
template<typename T>
[[nodiscard]] std::future<void> exec(T&& lambda)
{
std::lock_guard _lock(m_task_mutex);
auto promise = std::make_shared<std::promise<void>>();
auto future = promise->get_future();
m_task_queue.emplace_back(
[l=std::forward<T>(lambda),p=std::move(promise)]
{
l();
p->set_value();
}
);
return future;
}
template<typename T>
void exec_async(T&& lambda)
{
std::lock_guard _lock(m_task_mutex);
m_task_queue.emplace_back(std::forward<T>(lambda));
}
void update_surface(ANativeWindow* window)
{
exec_async([this, window]{
m_egl_context->make_current(window);
});
}
ndk::ScopedAStatus onServiceInitialized(bool in_success) override ndk::ScopedAStatus onServiceInitialized(bool in_success) override
{ {
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
@@ -104,6 +138,13 @@ public:
{ {
m_hwbuffer = in_buffer.get(); m_hwbuffer = in_buffer.get();
AHardwareBuffer_acquire(m_hwbuffer); AHardwareBuffer_acquire(m_hwbuffer);
exec_async([this]{
m_texture = std::make_unique<ExternalTexture>();
if (!m_texture->create(m_hwbuffer))
{
Logger::Log("Failed to create texture");
}
});
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
}; };
@@ -144,6 +185,10 @@ Java_com_omixlab_mosis_MainActivity_setSurface(JNIEnv *env, jobject thiz,
g_renderer = ndk::SharedRefBase::make<Renderer>(); g_renderer = ndk::SharedRefBase::make<Renderer>();
g_renderer->create(ANativeWindow_fromSurface(env, surface)); g_renderer->create(ANativeWindow_fromSurface(env, surface));
} }
else
{
g_renderer->update_surface(ANativeWindow_fromSurface(env, surface));
}
} }
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
@@ -153,6 +198,7 @@ Java_com_omixlab_mosis_MainActivity_destroySurface(JNIEnv *env, jobject thiz)
if (g_renderer) if (g_renderer)
{ {
g_renderer->destroy(); g_renderer->destroy();
g_renderer.reset();
} }
} }