已经介绍了如何加载EGL和OpenGL具体软硬件实现,其中system\lib\libEGL.so是加载具体实现的桥梁。下面分析java层的OpenGL相关类是如何和底层库联系起来的?不难猜测,肯定是通过JNI联系起来的。

package android.opengl

java层关于opengl的第一个包为,

package android.opengl;

代码路径在frameworks\base\opengl\java\android\opengl,其中的java文件有,

├── EGL14.java├── EGLConfig.java├── EGLContext.java├── EGLDisplay.java├── EGLExt.java├── EGLLogWrapper.java├── EGLObjectHandle.java├── EGLSurface.java├── ETC1.java├── ETC1Util.java├── GLDebugHelper.java├── GLErrorWrapper.java├── GLES10Ext.java├── GLES10.java├── GLES11Ext.java├── GLES11.java├── GLES20.java├── GLES30.java├── GLException.java├── GLLogWrapper.java├── GLSurfaceView.java├── GLU.java├── GLUtils.java├── GLWallpaperService.java├── GLWrapperBase.java├── ManagedEGLContext.java├── Matrix.java├── package.html└── Visibility.java

里面包含了EGL、GLES 1.0、1.1、1.1 Ext、2.0、3.0。

javax.microedition.khronos.opengles

java层关于opengl的另外一个包为,

package javax.microedition.khronos.opengles;

代码路径为frameworks\base\opengl\java\javax\microedition\khronos\opengles,其中的java类包括,

├── egl
│?? ├── EGL10.java│?? ├── EGL11.java│?? ├── EGLConfig.java│?? ├── EGLContext.java│?? ├── EGLDisplay.java│?? ├── EGL.java│?? └── EGLSurface.java└── opengles
├── GL10Ext.java
├── GL10.java
├── GL11ExtensionPack.java
├── GL11Ext.java
├── GL11.java
├── GL.java
└── package.html

其中,包含了EGL 1.0、1.1,GLES 1.0、1.0 Ext、1.1、1.1 Ext。

JNI调用关系

以package android.opengl中的GLSurfaceView.java为例,该类为上层专门为方便使用opengl提供的。EglHelper类是个辅助类,为EGL搭建本地环境等。

/**
* An EGL helper class.
*/

private static class EglHelper {


/**
* Initialize EGL for a given configuration spec.
* @param configSpec
*/
public void start() { if (LOG_EGL) {
Log.w("EglHelper", "start() tid=" + Thread.currentThread().getId());
} //返回com.google.android.gles_jni.EGLImpl,
/*
* Get an EGL instance
*/
mEgl = (EGL10) EGLContext.getEGL(); //调用EGLImpl的eglGetDisplay
/*
* Get to the default display.
*/
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { throw new RuntimeException("eglGetDisplay failed");
}
}public abstract class EGLContext{
private static final EGL EGL_INSTANCE = new com.google.android.gles_jni.EGLImpl(); public static EGL getEGL() { return EGL_INSTANCE;
} public abstract GL getGL();
}



}

eglGetDisplay函数最终会去调用native函数_eglGetDisplay,

/* frameworks\base\opengl\java\com\google\android\gles_jni\EGLImpl.java */
public synchronized EGLDisplay eglGetDisplay(Object native_display) { int value = _eglGetDisplay(native_display); if (value == 0) { return EGL10.EGL_NO_DISPLAY;
} if (mDisplay.mEGLDisplay != value)
mDisplay = new EGLDisplayImpl(value); return mDisplay;
}private native int _eglGetDisplay(Object native_display);

根据包名、类名找到JNI实现frameworks\base\core\jni\com_google_android_gles_jni_EGLImpl.cpp,

{"_eglGetDisplay",   "(" OBJECT ")I", (void*)jni_eglGetDisplay },

实际调用的是eglGetDisplay函数,

static jint jni_eglGetDisplay(JNIEnv *_env, jobject _this, jobject native_display) {
return (jint)eglGetDisplay(EGL_DEFAULT_DISPLAY);
}

那么这个eglGetDisplay是在哪实现的?怎么找?当然是从头文件和makefile中。

在frameworks\base\core\jni\com_google_android_gles_jni_EGLImpl.cpp中,

#include#include#include

而在com_google_android_gles_jni_EGLImpl.cpp所在的makefile中,

//会去加载system\lib\libEGL.so库,桥梁加载了LOCAL_SHARED_LIBRARIES := \
libui \
libgui \
libinput \
libcamera_client \
libcamera_metadata \
libskia \
libsqlite \
libEGL \
libGLESv1_CM \
libGLESv2 \
libETC1 \

LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/android/graphics \
$(LOCAL_PATH)/../../libs/hwui \
$(LOCAL_PATH)/../../../native/opengl/libs \
$(call include-path-for, bluedroid) \
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
$(TOP)/frameworks/av/include \
$(TOP)/system/media/camera/include \
external/skia/src/core \
external/skia/src/pdf \
external/skia/src/images \
external/skia/include/utils \
external/sqlite/dist \
external/sqlite/android \
external/expat/lib \
external/openssl/include \
external/tremor/Tremor \
external/icu4c/i18n \
external/icu4c/common \
external/jpeg \
external/harfbuzz_ng/src \
external/zlib \
frameworks/opt/emoji \
libcore/include


ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SHARED_LIBRARIES += libhwui
endif//这里的这些jni文件很重要,生成libandroid_runtime库LOCAL_MODULE:= libandroid_runtime

include $(BUILD_SHARED_LIBRARY)

从上面的makefile中我们能看到,会去加载库system\lib\libEGL.so,也就是加载EGL和OpenGL实现的桥梁,这样就将java层的EGL、OpenGL同底层实现的库联系起来。