Skip to content

Commit

Permalink
Bug 1255628 - Replace and/or remove some graphics-related calls in An…
Browse files Browse the repository at this point in the history
…droidBridge with NDK equivalents r=jchen
  • Loading branch information
snorp committed Aug 4, 2016
1 parent c7486db commit 5deea53
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 821 deletions.
2 changes: 2 additions & 0 deletions config/system-headers
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@ Math64.h
math.h
mbstring.h
#ifdef ANDROID
android/native_window.h
android/native_window_jni.h
media/AudioEffect.h
media/AudioSystem.h
media/ICrypto.h
Expand Down
165 changes: 8 additions & 157 deletions widget/android/AndroidBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
35 changes: 0 additions & 35 deletions widget/android/AndroidBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,29 +205,11 @@ class AndroidBridge final

bool GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* env = nullptr);

// These next four functions are for native Bitmap access in Android 2.2+
bool HasNativeBitmapAccess();

bool ValidateBitmap(jobject bitmap, int width, int height);

void *LockBitmap(jobject bitmap);

// Returns a global reference to the Context for Fennec's Activity. The
// caller is responsible for ensuring this doesn't leak by calling
// DeleteGlobalRef() when the context is no longer needed.
jobject GetGlobalContextRef(void);

void UnlockBitmap(jobject bitmap);

/* Copied from Android's native_window.h in newer (platform 9) NDK */
enum {
WINDOW_FORMAT_RGBA_8888 = 1,
WINDOW_FORMAT_RGBX_8888 = 2,
WINDOW_FORMAT_RGB_565 = 4
};

bool HasNativeWindowAccess();

void *AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface);
void ReleaseNativeWindow(void *window);
mozilla::gfx::IntSize GetNativeWindowSize(void* window);
Expand Down Expand Up @@ -394,23 +376,6 @@ class AndroidBridge final
jfieldID mMessageQueueMessages;
jmethodID mMessageQueueNext;

// calls we've dlopened from libjnigraphics.so
int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);

void* (*ANativeWindow_fromSurface)(JNIEnv *env, jobject surface);
void (*ANativeWindow_release)(void *window);
int (*ANativeWindow_setBuffersGeometry)(void *window, int width, int height, int format);

int (* ANativeWindow_getWidth)(void * window);
int (* ANativeWindow_getHeight)(void * window);

int (* Surface_lock)(void* surface, void* surfaceInfo, void* region, bool block);
int (* Surface_unlockAndPost)(void* surface);
void (* Region_constructor)(void* region);
void (* Region_set)(void* region, void* rect);

private:
class DelayedTask;
nsTArray<DelayedTask> mUiTaskQueue;
Expand Down
Loading

0 comments on commit 5deea53

Please sign in to comment.