Bug 1255628 - Replace and/or remove some graphics-related calls in AndroidBridge with NDK equivalents r=jchen

This commit is contained in:
James Willcox
2016-05-25 15:07:47 -05:00
parent 0ee3adf86d
commit 3f1dd216e3
6 changed files with 13 additions and 821 deletions

View File

@@ -7,6 +7,8 @@
#include <dlfcn.h>
#include <math.h>
#include <GLES2/gl2.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
@@ -63,12 +65,6 @@ pthread_t AndroidBridge::sJavaUiThread;
static jobject sGlobalContext = nullptr;
nsDataHashtable<nsStringHashKey, nsString> AndroidBridge::sStoragePaths;
// This is a dummy class that can be used in the template for android::sp
class AndroidRefable {
void incStrong(void* thing) { }
void decStrong(void* thing) { }
};
jclass AndroidBridge::GetClassGlobalRef(JNIEnv* env, const char* className)
{
// First try the default class loader.
@@ -692,63 +688,6 @@ AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) {
return (void*)env->GetIntField(surface, jSurfacePointerField);
}
void
AndroidBridge::OpenGraphicsLibraries()
{
if (!mOpenedGraphicsLibraries) {
// Try to dlopen libjnigraphics.so for direct bitmap access on
// Android 2.2+ (API level 8)
mOpenedGraphicsLibraries = true;
mHasNativeWindowAccess = false;
mHasNativeWindowFallback = false;
mHasNativeBitmapAccess = false;
void *handle = dlopen("libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL);
if (handle) {
AndroidBitmap_getInfo = (int (*)(JNIEnv *, jobject, void *))dlsym(handle, "AndroidBitmap_getInfo");
AndroidBitmap_lockPixels = (int (*)(JNIEnv *, jobject, void **))dlsym(handle, "AndroidBitmap_lockPixels");
AndroidBitmap_unlockPixels = (int (*)(JNIEnv *, jobject))dlsym(handle, "AndroidBitmap_unlockPixels");
mHasNativeBitmapAccess = AndroidBitmap_getInfo && AndroidBitmap_lockPixels && AndroidBitmap_unlockPixels;
ALOG_BRIDGE("Successfully opened libjnigraphics.so, have native bitmap access? %d", mHasNativeBitmapAccess);
}
// Try to dlopen libandroid.so for and native window access on
// Android 2.3+ (API level 9)
handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
if (handle) {
ANativeWindow_fromSurface = (void* (*)(JNIEnv*, jobject))dlsym(handle, "ANativeWindow_fromSurface");
ANativeWindow_release = (void (*)(void*))dlsym(handle, "ANativeWindow_release");
ANativeWindow_setBuffersGeometry = (int (*)(void*, int, int, int)) dlsym(handle, "ANativeWindow_setBuffersGeometry");
ANativeWindow_getWidth = (int (*)(void*))dlsym(handle, "ANativeWindow_getWidth");
ANativeWindow_getHeight = (int (*)(void*))dlsym(handle, "ANativeWindow_getHeight");
mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release;
ALOG_BRIDGE("Successfully opened libandroid.so, have native window access? %d", mHasNativeWindowAccess);
}
if (mHasNativeWindowAccess)
return;
// Look up Surface functions, used for native window (surface) fallback
handle = dlopen("libsurfaceflinger_client.so", RTLD_LAZY);
if (handle) {
Surface_lock = (int (*)(void*, void*, void*, bool))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
Surface_unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
handle = dlopen("libui.so", RTLD_LAZY);
if (handle) {
Region_constructor = (void (*)(void*))dlsym(handle, "_ZN7android6RegionC1Ev");
Region_set = (void (*)(void*, void*))dlsym(handle, "_ZN7android6Region3setERKNS_4RectE");
mHasNativeWindowFallback = Surface_lock && Surface_unlockAndPost && Region_constructor && Region_set;
}
}
}
}
namespace mozilla {
class TracerRunnable : public Runnable{
public:
@@ -823,43 +762,7 @@ namespace mozilla {
}
}
bool
AndroidBridge::HasNativeBitmapAccess()
{
OpenGraphicsLibraries();
return mHasNativeBitmapAccess;
}
bool
AndroidBridge::ValidateBitmap(jobject bitmap, int width, int height)
{
// This structure is defined in Android API level 8's <android/bitmap.h>
// Because we can't depend on this, we get the function pointers via dlsym
// and define this struct ourselves.
struct BitmapInfo {
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t format;
uint32_t flags;
};
int err;
struct BitmapInfo info = { 0, };
JNIEnv* const env = jni::GetGeckoThreadEnv();
if ((err = AndroidBitmap_getInfo(env, bitmap, &info)) != 0) {
ALOG_BRIDGE("AndroidBitmap_getInfo failed! (error %d)", err);
return false;
}
if ((int)info.width != width || (int)info.height != height)
return false;
return true;
}
bool
AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps)
@@ -1211,78 +1114,26 @@ AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInf
env->ReleaseDoubleArrayElements(arr.Get(), info, 0);
}
void *
AndroidBridge::LockBitmap(jobject bitmap)
{
JNIEnv* const env = jni::GetGeckoThreadEnv();
int err;
void *buf;
if ((err = AndroidBitmap_lockPixels(env, bitmap, &buf)) != 0) {
ALOG_BRIDGE("AndroidBitmap_lockPixels failed! (error %d)", err);
buf = nullptr;
}
return buf;
}
void
AndroidBridge::UnlockBitmap(jobject bitmap)
{
JNIEnv* const env = jni::GetGeckoThreadEnv();
int err;
if ((err = AndroidBitmap_unlockPixels(env, bitmap)) != 0)
ALOG_BRIDGE("AndroidBitmap_unlockPixels failed! (error %d)", err);
}
bool
AndroidBridge::HasNativeWindowAccess()
{
OpenGraphicsLibraries();
// We have a fallback hack in place, so return true if that will work as well
return mHasNativeWindowAccess || mHasNativeWindowFallback;
}
void*
AndroidBridge::AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface)
{
OpenGraphicsLibraries();
if (mHasNativeWindowAccess)
return ANativeWindow_fromSurface(aEnv, aSurface);
if (mHasNativeWindowFallback)
return GetNativeSurface(aEnv, aSurface);
return nullptr;
return ANativeWindow_fromSurface(aEnv, aSurface);
}
void
AndroidBridge::ReleaseNativeWindow(void *window)
{
if (!window)
return;
if (mHasNativeWindowAccess)
ANativeWindow_release(window);
// XXX: we don't ref the pointer we get from the fallback (GetNativeSurface), so we
// have nothing to do here. We should probably ref it.
return ANativeWindow_release((ANativeWindow*)window);
}
IntSize
AndroidBridge::GetNativeWindowSize(void* window)
{
if (!window || !ANativeWindow_getWidth || !ANativeWindow_getHeight) {
return IntSize(0, 0);
}
if (!window) {
return IntSize(0, 0);
}
return IntSize(ANativeWindow_getWidth(window), ANativeWindow_getHeight(window));
return IntSize(ANativeWindow_getWidth((ANativeWindow*)window), ANativeWindow_getHeight((ANativeWindow*)window));
}
jobject