83 lines
2.5 KiB
C++
83 lines
2.5 KiB
C++
|
|
#include <jni.h>
|
||
|
|
#include <android/native_window_jni.h>
|
||
|
|
#include <android/native_window.h>
|
||
|
|
#include <android/log.h>
|
||
|
|
|
||
|
|
#define LOG_TAG "NativeRenderer"
|
||
|
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||
|
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||
|
|
|
||
|
|
static ANativeWindow* window = nullptr;
|
||
|
|
|
||
|
|
extern "C" JNIEXPORT void JNICALL
|
||
|
|
Java_bums_lunatic_launcher_wall_NativeRenderer_nativeInit(JNIEnv* env, jobject, jobject surface) {
|
||
|
|
if (window != nullptr) {
|
||
|
|
ANativeWindow_release(window);
|
||
|
|
window = nullptr;
|
||
|
|
}
|
||
|
|
window = ANativeWindow_fromSurface(env, surface);
|
||
|
|
LOGI("Native window initialized");
|
||
|
|
}
|
||
|
|
|
||
|
|
extern "C" JNIEXPORT void JNICALL
|
||
|
|
Java_bums_lunatic_launcher_wall_NativeRenderer_nativeRender(
|
||
|
|
JNIEnv* env, jobject, jintArray pixels, jint width, jint height,
|
||
|
|
jfloat offsetX, jfloat offsetY, jfloat fadeAlpha) {
|
||
|
|
|
||
|
|
if (!window) return;
|
||
|
|
|
||
|
|
ANativeWindow_Buffer buffer;
|
||
|
|
if (ANativeWindow_lock(window, &buffer, nullptr) < 0) {
|
||
|
|
LOGE("Failed to lock native window");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
jint* srcPixels = env->GetIntArrayElements(pixels, nullptr);
|
||
|
|
if (!srcPixels) {
|
||
|
|
ANativeWindow_unlockAndPost(window);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32_t* dstPixels = (uint32_t*)buffer.bits;
|
||
|
|
int stride = buffer.stride;
|
||
|
|
|
||
|
|
int offsetXInt = static_cast<int>(offsetX);
|
||
|
|
int offsetYInt = static_cast<int>(offsetY);
|
||
|
|
|
||
|
|
for (int y = 0; y < buffer.height; y++) {
|
||
|
|
int srcY = y - offsetYInt;
|
||
|
|
if (srcY < 0 || srcY >= height) continue;
|
||
|
|
|
||
|
|
for (int x = 0; x < buffer.width; x++) {
|
||
|
|
int srcX = x - offsetXInt;
|
||
|
|
if (srcX < 0 || srcX >= width) continue;
|
||
|
|
|
||
|
|
uint32_t pixel = srcPixels[srcY * width + srcX];
|
||
|
|
|
||
|
|
uint8_t alpha = static_cast<uint8_t>(fadeAlpha * 255);
|
||
|
|
uint8_t r = (pixel >> 16) & 0xFF;
|
||
|
|
uint8_t g = (pixel >> 8) & 0xFF;
|
||
|
|
uint8_t b = pixel & 0xFF;
|
||
|
|
|
||
|
|
r = (r * alpha) / 255;
|
||
|
|
g = (g * alpha) / 255;
|
||
|
|
b = (b * alpha) / 255;
|
||
|
|
|
||
|
|
dstPixels[y * stride + x] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
env->ReleaseIntArrayElements(pixels, srcPixels, JNI_ABORT);
|
||
|
|
|
||
|
|
ANativeWindow_unlockAndPost(window);
|
||
|
|
}
|
||
|
|
|
||
|
|
extern "C" JNIEXPORT void JNICALL
|
||
|
|
Java_bums_lunatic_launcher_wall_NativeRenderer_nativeDestroy(JNIEnv*, jobject) {
|
||
|
|
if (window) {
|
||
|
|
ANativeWindow_release(window);
|
||
|
|
window = nullptr;
|
||
|
|
LOGI("Native window released");
|
||
|
|
}
|
||
|
|
}
|