extern "C" void Java_com_henrikrydgard_libnative_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { ILOG("NativeApp.displayInit()"); if (!renderer_inited) { // We default to 240 dpi and all UI code is written to assume it. (DENSITY_HIGH, like Nexus S). // Note that we don't compute dp_xscale and dp_yscale until later! This is so that NativeGetAppInfo // can change the dp resolution if it feels like it. dp_xres = pixel_xres * g_dpi_scale; dp_yres = pixel_yres * g_dpi_scale; ILOG("Calling NativeInitGraphics(): dpi = %i, dp_xres = %i, dp_yres = %i", g_dpi, dp_xres, dp_yres); NativeInitGraphics(); dp_xscale = (float)dp_xres / pixel_xres; dp_yscale = (float)dp_yres / pixel_yres; renderer_inited = true; } else { ILOG("Calling NativeDeviceLost();"); NativeDeviceLost(); ILOG("NativeDeviceLost completed.;"); } ILOG("(Re)-fetching method ID to postCommand..."); jclass cls = env->GetObjectClass(obj); postCommand = env->GetMethodID(cls, "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V"); ILOG("MethodID: %i", (int)postCommand); }
// JavaEGL extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { // Need to get the local JNI env for the graphics thread. Used later in draw_text_android. int res = javaVM->GetEnv((void **)&jniEnvGraphics, JNI_VERSION_1_6); if (res != JNI_OK) { ELOG("GetEnv failed: %d", res); } if (javaGL && !graphicsContext) { graphicsContext = new AndroidJavaEGLGraphicsContext(); } if (renderer_inited) { ILOG("NativeApp.displayInit() restoring"); NativeDeviceLost(); NativeShutdownGraphics(); NativeDeviceRestore(); NativeInitGraphics(graphicsContext); ILOG("Restored."); } else { ILOG("NativeApp.displayInit() first time"); NativeInitGraphics(graphicsContext); renderer_inited = true; renderer_ever_inited = true; } NativeMessageReceived("recreateviews", ""); }
extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayShutdown(JNIEnv *env, jobject obj) { if (renderer_inited) { NativeDeviceLost(); ILOG("NativeDeviceLost completed."); NativeShutdownGraphics(); renderer_inited = false; NativeMessageReceived("recreateviews", ""); } }
extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { ILOG("NativeApp.displayInit()"); if (!renderer_inited) { NativeInitGraphics(); renderer_inited = true; } else { NativeDeviceLost(); // ??? ILOG("displayInit: NativeDeviceLost completed."); } DLOG("(Re)-fetching method ID to postCommand..."); postCommand = env->GetMethodID(env->GetObjectClass(obj), "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V"); }
extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf); WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { ELOG("Error: Surface is null."); return false; } AndroidEGLGraphicsContext *graphicsContext = new AndroidEGLGraphicsContext(); if (!graphicsContext->Init(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format)) { ELOG("Failed to initialize graphics context."); delete graphicsContext; return false; } if (!renderer_inited) { NativeInitGraphics(graphicsContext); renderer_inited = true; } exitRenderLoop = false; renderLoopRunning = true; while (!exitRenderLoop) { static bool hasSetThreadName = false; if (!hasSetThreadName) { hasSetThreadName = true; setCurrentThreadName("AndroidRender"); } // TODO: Look into if these locks are a perf loss { lock_guard guard(input_state.lock); input_state.pad_lstick_x = left_joystick_x_async; input_state.pad_lstick_y = left_joystick_y_async; input_state.pad_rstick_x = right_joystick_x_async; input_state.pad_rstick_y = right_joystick_y_async; UpdateInputState(&input_state); } NativeUpdate(input_state); { lock_guard guard(input_state.lock); EndInputState(&input_state); } NativeRender(graphicsContext); time_update(); graphicsContext->SwapBuffers(); ProcessFrameCommands(env); } ILOG("After render loop."); g_gameInfoCache->WorkQueue()->Flush(); NativeDeviceLost(); ILOG("NativeDeviceLost completed."); NativeShutdownGraphics(); renderer_inited = false; graphicsContext->Shutdown(); renderLoopRunning = false; WLOG("Render loop function exited."); return true; }
extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf); WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { ELOG("Error: Surface is null."); return false; } cInterfaceBase *gl = HostGL_CreateGLInterface(); if (!gl) { ELOG("ERROR: Failed to create GL interface"); return false; } ILOG("EGL interface created. Desired backbuffer size: %dx%d", desiredBackbufferSizeX, desiredBackbufferSizeY); // Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect... gl->SetBackBufferDimensions(desiredBackbufferSizeX, desiredBackbufferSizeY); gl->SetMode(MODE_DETECT_ES); bool use565 = false; switch (backbuffer_format) { case 4: // PixelFormat.RGB_565 use565 = true; break; } if (!gl->Create(wnd, false, use565)) { ELOG("EGL creation failed"); // TODO: What do we do now? return false; } gl->MakeCurrent(); if (!renderer_inited) { NativeInitGraphics(); renderer_inited = true; } exitRenderLoop = false; renderLoopRunning = true; while (!exitRenderLoop) { static bool hasSetThreadName = false; if (!hasSetThreadName) { hasSetThreadName = true; setCurrentThreadName("AndroidRender"); } // TODO: Look into if these locks are a perf loss { lock_guard guard(input_state.lock); input_state.pad_lstick_x = left_joystick_x_async; input_state.pad_lstick_y = left_joystick_y_async; input_state.pad_rstick_x = right_joystick_x_async; input_state.pad_rstick_y = right_joystick_y_async; UpdateInputState(&input_state); } NativeUpdate(input_state); { lock_guard guard(input_state.lock); EndInputState(&input_state); } NativeRender(); time_update(); gl->Swap(); lock_guard guard(frameCommandLock); while (!frameCommands.empty()) { FrameCommand frameCmd; frameCmd = frameCommands.front(); frameCommands.pop(); WLOG("frameCommand! '%s' '%s'", frameCmd.command.c_str(), frameCmd.params.c_str()); jstring cmd = env->NewStringUTF(frameCmd.command.c_str()); jstring param = env->NewStringUTF(frameCmd.params.c_str()); env->CallVoidMethod(nativeActivity, postCommand, cmd, param); env->DeleteLocalRef(cmd); env->DeleteLocalRef(param); } } // Restore lost device objects. TODO: This feels like the wrong place for this. NativeDeviceLost(); ILOG("NativeDeviceLost completed."); NativeShutdownGraphics(); renderer_inited = false; gl->ClearCurrent(); delete gl; ANativeWindow_release(wnd); renderLoopRunning = false; WLOG("Render loop exited;"); return true; }
extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf); // Need to get the local JNI env for the graphics thread. Used later in draw_text_android. int res = javaVM->GetEnv((void **)&jniEnvGraphics, JNI_VERSION_1_6); if (res != JNI_OK) { ELOG("GetEnv failed: %d", res); } WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { ELOG("Error: Surface is null."); return false; } retry: bool vulkan = g_Config.iGPUBackend == GPU_BACKEND_VULKAN; int tries = 0; AndroidGraphicsContext *graphicsContext; if (vulkan) { graphicsContext = new AndroidVulkanContext(); } else { graphicsContext = new AndroidEGLGraphicsContext(); } if (!graphicsContext->Init(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { ELOG("Failed to initialize graphics context."); if (vulkan && tries < 2) { ILOG("Trying again, this time with OpenGL."); g_Config.iGPUBackend = GPU_BACKEND_OPENGL; SetGPUBackend((GPUBackend)g_Config.iGPUBackend); // Wait, why do we need a separate enum here? tries++; goto retry; } delete graphicsContext; return false; } if (!renderer_inited) { NativeInitGraphics(graphicsContext); if (renderer_ever_inited) { NativeDeviceRestore(); } renderer_inited = true; renderer_ever_inited = true; } exitRenderLoop = false; renderLoopRunning = true; while (!exitRenderLoop) { static bool hasSetThreadName = false; if (!hasSetThreadName) { hasSetThreadName = true; setCurrentThreadName("AndroidRender"); } NativeUpdate(); NativeRender(graphicsContext); time_update(); graphicsContext->SwapBuffers(); ProcessFrameCommands(env); } ILOG("After render loop."); g_gameInfoCache->WorkQueue()->Flush(); NativeDeviceLost(); renderer_inited = false; ILOG("Shutting down graphics context."); graphicsContext->Shutdown(); delete graphicsContext; graphicsContext = nullptr; renderLoopRunning = false; WLOG("Render loop function exited."); jniEnvGraphics = nullptr; return true; }
extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf); WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { ELOG("Error: Surface is null."); return false; } AndroidEGLGraphicsContext *graphicsContext = new AndroidEGLGraphicsContext(); if (!graphicsContext->Init(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format)) { ELOG("Failed to initialize graphics context."); delete graphicsContext; return false; } if (!renderer_inited) { NativeInitGraphics(graphicsContext); renderer_inited = true; } exitRenderLoop = false; renderLoopRunning = true; while (!exitRenderLoop) { static bool hasSetThreadName = false; if (!hasSetThreadName) { hasSetThreadName = true; setCurrentThreadName("AndroidRender"); } // TODO: Look into if these locks are a perf loss { lock_guard guard(input_state.lock); input_state.pad_lstick_x = left_joystick_x_async; input_state.pad_lstick_y = left_joystick_y_async; input_state.pad_rstick_x = right_joystick_x_async; input_state.pad_rstick_y = right_joystick_y_async; UpdateInputState(&input_state); } NativeUpdate(input_state); { lock_guard guard(input_state.lock); EndInputState(&input_state); } NativeRender(graphicsContext); time_update(); graphicsContext->SwapBuffers(); lock_guard guard(frameCommandLock); while (!frameCommands.empty()) { FrameCommand frameCmd; frameCmd = frameCommands.front(); frameCommands.pop(); WLOG("frameCommand! '%s' '%s'", frameCmd.command.c_str(), frameCmd.params.c_str()); jstring cmd = env->NewStringUTF(frameCmd.command.c_str()); jstring param = env->NewStringUTF(frameCmd.params.c_str()); env->CallVoidMethod(nativeActivity, postCommand, cmd, param); env->DeleteLocalRef(cmd); env->DeleteLocalRef(param); } } // Restore lost device objects. TODO: This feels like the wrong place for this. NativeDeviceLost(); ILOG("NativeDeviceLost completed."); NativeShutdownGraphics(); renderer_inited = false; graphicsContext->Shutdown(); renderLoopRunning = false; WLOG("Render loop exited;"); return true; }