Path: blob/v3_openjdk/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.c
2128 views
//1// Created by maks on 18.10.2023.2//3#include <malloc.h>4#include <string.h>5#include <environ/environ.h>6#include "osm_bridge.h"7#define TAG __FILE_NAME__8#include <log.h>910static __thread osm_render_window_t* currentBundle;11// a tiny buffer for rendering when there's nowhere t render12static char no_render_buffer[4];1314// Its not in a .h file because it is not supposed to be used outsife of this file.15void setNativeWindowSwapInterval(struct ANativeWindow* nativeWindow, int swapInterval);1617bool osm_init() {18if(!dlsym_OSMesa()) return false;19return true;20}2122osm_render_window_t* osm_get_current() {23return currentBundle;24}2526osm_render_window_t* osm_init_context(osm_render_window_t* share) {27osm_render_window_t* render_window = malloc(sizeof(osm_render_window_t));28if(render_window == NULL) return NULL;29memset(render_window, 0, sizeof(osm_render_window_t));30OSMesaContext osmesa_share = NULL;31if(share != NULL) osmesa_share = share->context;32OSMesaContext context = OSMesaCreateContext_p(GL_RGBA, osmesa_share);33if(context == NULL) {34free(render_window);35return NULL;36}37render_window->context = context;38return render_window;39}4041void osm_set_no_render_buffer(ANativeWindow_Buffer* buffer) {42buffer->bits = &no_render_buffer;43buffer->width = 1;44buffer->height = 1;45buffer->stride = 0;46}4748void osm_swap_surfaces(osm_render_window_t* bundle) {49if(bundle->nativeSurface != NULL && bundle->newNativeSurface != bundle->nativeSurface) {50if(!bundle->disable_rendering) {51LOGI("Unlocking for cleanup...");52ANativeWindow_unlockAndPost(bundle->nativeSurface);53}54ANativeWindow_release(bundle->nativeSurface);55}56if(bundle->newNativeSurface != NULL) {57LOGI("Switching to new native surface");58bundle->nativeSurface = bundle->newNativeSurface;59bundle->newNativeSurface = NULL;60ANativeWindow_acquire(bundle->nativeSurface);61ANativeWindow_setBuffersGeometry(bundle->nativeSurface, 0, 0, WINDOW_FORMAT_RGBX_8888);62bundle->disable_rendering = false;63return;64}else {65LOGI("No new native surface, switching to dummy framebuffer");66bundle->nativeSurface = NULL;67osm_set_no_render_buffer(&bundle->buffer);68bundle->disable_rendering = true;69}7071}7273void osm_release_window() {74currentBundle->newNativeSurface = NULL;75osm_swap_surfaces(currentBundle);76}7778void osm_apply_current_ll() {79ANativeWindow_Buffer* buffer = ¤tBundle->buffer;80OSMesaMakeCurrent_p(currentBundle->context, buffer->bits, GL_UNSIGNED_BYTE, buffer->width, buffer->height);81if(buffer->stride != currentBundle->last_stride)82OSMesaPixelStore_p(OSMESA_ROW_LENGTH, buffer->stride);83currentBundle->last_stride = buffer->stride;84}8586void osm_make_current(osm_render_window_t* bundle) {87if(bundle == NULL) {88//technically this does nothing as its not possible to unbind a context in OSMesa89OSMesaMakeCurrent_p(NULL, NULL, 0, 0, 0);90currentBundle = NULL;91return;92}93bool hasSetMainWindow = false;94currentBundle = bundle;95if(pojav_environ->mainWindowBundle == NULL) {96pojav_environ->mainWindowBundle = (basic_render_window_t*) bundle;97LOGI("Main window bundle is now %p", pojav_environ->mainWindowBundle);98pojav_environ->mainWindowBundle->newNativeSurface = pojav_environ->pojavWindow;99hasSetMainWindow = true;100}101if(bundle->nativeSurface == NULL) {102//prepare the buffer for our first render!103osm_swap_surfaces(bundle);104if(hasSetMainWindow) pojav_environ->mainWindowBundle->state = STATE_RENDERER_ALIVE;105}106osm_set_no_render_buffer(&bundle->buffer);107osm_apply_current_ll();108OSMesaPixelStore_p(OSMESA_Y_UP,0);109}110111void osm_swap_buffers() {112if(currentBundle->state == STATE_RENDERER_NEW_WINDOW) {113osm_swap_surfaces(currentBundle);114currentBundle->state = STATE_RENDERER_ALIVE;115}116117if(currentBundle->nativeSurface != NULL && !currentBundle->disable_rendering)118if(ANativeWindow_lock(currentBundle->nativeSurface, ¤tBundle->buffer, NULL) != 0)119osm_release_window();120121osm_apply_current_ll();122glFinish_p(); // this will force osmesa to write the last rendered image into the buffer123124if(currentBundle->nativeSurface != NULL && !currentBundle->disable_rendering)125if(ANativeWindow_unlockAndPost(currentBundle->nativeSurface) != 0)126osm_release_window();127}128129void osm_setup_window() {130if(pojav_environ->mainWindowBundle != NULL) {131LOGI("Main window bundle is not NULL, changing state");132pojav_environ->mainWindowBundle->state = STATE_RENDERER_NEW_WINDOW;133pojav_environ->mainWindowBundle->newNativeSurface = pojav_environ->pojavWindow;134}135}136137void osm_swap_interval(int swapInterval) {138if(pojav_environ->mainWindowBundle != NULL && pojav_environ->mainWindowBundle->nativeSurface != NULL) {139setNativeWindowSwapInterval(pojav_environ->mainWindowBundle->nativeSurface, swapInterval);140}141}142143