• Android下基于SDL的位图渲染(二)理论篇


    理论篇

    上一篇中介绍了如何将SDL2源码应用到Android渲染中,实际上SDL本身提供的android-project实现了基于android的c运行时环境,通过上面实践篇的介绍,就是完成这个环境搭建的过程。
    这样就不需要过多关注Android的Activity框架及图像渲染机制。
    更加详细关于这部分的介绍建议参考Building SDL2 for Android
    其中最关键的部分在于org.libsdl.app.SDLActivity的实现,当然涉及视频渲染需要SurfaceView支持,所有代码位于SDLActivity.java,SDLSurface就是继承与此。我们的最终的main函数的调用时通过class SDLMain实现的。
    其基本调用流程是SDLSurface.surfaceChanged()启动SDLMain线程,SDLMain的线程函数执行SDLActivity的nativeInit()。这样就把java层的代码和渲染工作转交给c/c++层去实现,其他Android事件处理由SDL完成。
    我们看下SDLActivity.nativeInit()的代码(位于SDL2-src/src/main/android/SDL_android_main.c中)

    #include <jni.h>
    
    /* Called before SDL_main() to initialize JNI bindings in SDL library */
    extern void SDL_Android_Init(JNIEnv* env, jclass cls);
    
    /* Start up the SDL app */
    JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject array)
    {
        int i;
        int argc;
        int status;
    
        /* This interface could expand with ABI negotiation, callbacks, etc. */
        SDL_Android_Init(env, cls);
    
        SDL_SetMainReady();
    
        /* Prepare the arguments. */
    
        int len = (*env)->GetArrayLength(env, array);
        char* argv[1 + len + 1];
        argc = 0;
        /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
           https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start
         */
        argv[argc++] = SDL_strdup("app_process");
        for (i = 0; i < len; ++i) {
            const char* utf;
            char* arg = NULL;
            jstring string = (*env)->GetObjectArrayElement(env, array, i);
            if (string) {
                utf = (*env)->GetStringUTFChars(env, string, 0);
                if (utf) {
                    arg = SDL_strdup(utf);
                    (*env)->ReleaseStringUTFChars(env, string, utf);
                }
                (*env)->DeleteLocalRef(env, string);
            }
            if (!arg) {
                arg = SDL_strdup("");
            }
            argv[argc++] = arg;
        }
        argv[argc] = NULL;
    
    
        /* Run the application. */
    
        status = SDL_main(argc, argv);
    
        /* Release the arguments. */
    
        for (i = 0; i < argc; ++i) {
            SDL_free(argv[i]);
        }
    
        /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
        /* exit(status); */
    
        return status;
    }
    

    功能很简单,初始化SDL在Android下的参数,获取命令行参数,执行SDL_main()。
    也许大家会感觉比较奇怪,在main.c中命名写的main函数啊,SDL_main为何物?
    这个问题我也纠结了一段时间,直接找不到SDL_main的实现,哪就源码中全局搜索SDL_main吧。看看结果:

    sdl2/CMakeLists.txt:1146:    set(SDL_CFLAGS "${SDL_CFLAGS} -Dmain=SDL_main")
    sdl2/configure.in:3123:        SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main"
    

    其他全是关于SDL_main的调用或者声明,只有这两个靠谱点。查查GCC的命令,-Dmain=SDL_main,这个就是编译的时候定义宏,等价于:
    #define SDL_main main

    好了,到这里就搞清楚了,SDL2提供的android-project如何把Activity和c的main通过JNI串联起来的。

    最后说一点,为什么我们写的c的main函数退出了,对应的Activity也退出了呢?
    这就是SDL_Quit通过内部消息机制,主动通知Activity退出的。当然具体的实现可能涉及太多SDL内部的内容,有兴趣的可以直接查看SDL_Quit的实现部分。

    关于SDL渲染BMP的原理,我之前写过windows下的使用SDL实现BMP渲染,原理是类似的。这里不赘述了,代码也相对简单。

    附加说明

    本文主要参考以下部分:

    源码下载

    本文中涉及所有源码可以从我的git@OSC,下载之后需要切换到bmp_render的tag即可。

  • 相关阅读:
    查看gpu和cpu使用情况 linux
    Oracle通过数据文件进行 数据恢复
    LeetCodeJava题解 283. Move Zeroes
    LeetCodeJava题解 844. Backspace String Compare
    LeetCodeJava题解 27. Remove Element
    LeetCodeJava题解 367. Valid Perfect Square
    LeetCodeJava题解 26. Remove Duplicates from Sorted Array
    EasyExcel实现合并一列的多行数据
    编辑qml的工具及插件
    qml学习(Qt Quick)
  • 原文地址:https://www.cnblogs.com/tocy/p/android-sdl-bitmap-render-theory.html
Copyright © 2020-2023  润新知