author | James Willcox <snorp@snorp.net> |
Wed, 25 May 2016 15:07:47 -0500 | |
changeset 308261 | 7a7aa2512bf7e53483214433de619dfbee43417d |
parent 308260 | a02925fe4ded04e2f5523fbd7e5ddfa46b190d39 |
child 308262 | 4a3775a4a1ab7ec6adef8ca6518bad4ab3f4e4bc |
push id | 31092 |
push user | cbook@mozilla.com |
push date | Fri, 05 Aug 2016 10:16:59 +0000 |
treeherder | autoland@b97dd7dd3cb9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jchen |
bugs | 1255628 |
milestone | 51.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
config/system-headers | file | annotate | diff | comparison | revisions | |
widget/android/AndroidBridge.cpp | file | annotate | diff | comparison | revisions | |
widget/android/AndroidBridge.h | file | annotate | diff | comparison | revisions | |
widget/android/AndroidDirectTexture.cpp | file | annotate | diff | comparison | revisions | |
widget/android/AndroidGraphicBuffer.cpp | file | annotate | diff | comparison | revisions | |
widget/android/moz.build | file | annotate | diff | comparison | revisions |
--- a/config/system-headers +++ b/config/system-headers @@ -711,16 +711,18 @@ mapiguid.h mapi.h mapitags.h mapiutil.h mapix.h 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 media/IOMX.h media/MediaProfiles.h media/MediaRecorderBase.h media/openmax/OMX_Audio.h media/stagefright/AACWriter.h
--- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -2,16 +2,18 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <android/log.h> #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" #include "mozilla/Hal.h" #include "nsXULAppAPI.h" #include <prthread.h> #include "nsXPCOMStrings.h" @@ -58,22 +60,16 @@ using namespace mozilla::gfx; using namespace mozilla::jni; using namespace mozilla::java; AndroidBridge* AndroidBridge::sBridge = nullptr; 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. auto classRef = Class::LocalRef::Adopt( env, env->FindClass(className)); if (!classRef && sBridge && sBridge->mClassLoader) { // If the default class loader failed but we have an app class loader, try that. @@ -687,73 +683,16 @@ AndroidBridge::GetStaticStringField(cons void* AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) { if (!env || !mHasNativeWindowFallback || !jSurfacePointerField) return nullptr; 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: TracerRunnable() { mTracerLock = new Mutex("TracerRunnable"); mTracerCondVar = new CondVar(*mTracerLock, "TracerRunnable"); mMainThread = do_GetMainThread(); @@ -818,53 +757,17 @@ namespace mozilla { void SignalTracerThread() { if (sTracerRunnable) return sTracerRunnable->Signal(); } } -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) { auto arr = GeckoAppShell::InitCameraWrapper (NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) *width, (int32_t) *height); if (!arr) @@ -1206,88 +1109,36 @@ AndroidBridge::GetCurrentNetworkInformat aNetworkInfo->type() = info[0]; aNetworkInfo->isWifi() = info[1] == 1.0f; aNetworkInfo->dhcpGateway() = info[2]; 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 AndroidBridge::GetGlobalContextRef() { if (sGlobalContext) { return sGlobalContext; }
--- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -200,39 +200,21 @@ public: void GetSystemColors(AndroidSystemColors *aColors); void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf); bool GetStaticStringField(const char *classID, const char *field, nsAString &result, JNIEnv* env = nullptr); 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); void HandleGeckoMessage(JSContext* cx, JS::HandleObject message); bool InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps); @@ -389,33 +371,16 @@ protected: jni::Object::GlobalRef mClassLoader; jmethodID mClassLoaderLoadClass; jni::Object::GlobalRef mMessageQueue; 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; mozilla::Mutex mUiTaskQueueLock; public: void PostTaskToUiThread(already_AddRefed<Runnable> aTask, int aDelayMs); int64_t RunDelayedUiThreadTasks();
deleted file mode 100644 --- a/widget/android/AndroidDirectTexture.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <unistd.h> -#include <errno.h> -#include "AndroidDirectTexture.h" -#include "nsRect.h" - -namespace mozilla { - -AndroidDirectTexture::AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage, - gfxImageFormat format) : - mLock("AndroidDirectTexture.mLock") - , mNeedFlip(false) - , mWidth(width) - , mHeight(height) - , mFormat(format) - , mPendingReallocBuffer(nullptr) -{ - mFrontBuffer = new AndroidGraphicBuffer(width, height, usage, format); - mBackBuffer = new AndroidGraphicBuffer(width, height, usage, format); -} - -AndroidDirectTexture::~AndroidDirectTexture() -{ - if (mFrontBuffer) { - delete mFrontBuffer; - mFrontBuffer = nullptr; - } - - if (mBackBuffer) { - delete mBackBuffer; - mBackBuffer = nullptr; - } -} - -void -AndroidDirectTexture::ReallocPendingBuffer() -{ - // We may have reallocated while the current back buffer was being - // used as the front buffer. If we have such a reallocation pending - // and the current back buffer is the target buffer, do it now. - // - // It is assumed that mLock is already acquired - if (mPendingReallocBuffer == mBackBuffer) { - mBackBuffer->Reallocate(mWidth, mHeight, mFormat); - mPendingReallocBuffer = nullptr; - } -} - -bool -AndroidDirectTexture::Lock(uint32_t aUsage, unsigned char **bits) -{ - nsIntRect rect(0, 0, mWidth, mHeight); - return Lock(aUsage, rect, bits); -} - -bool -AndroidDirectTexture::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits) -{ - mLock.Lock(); - ReallocPendingBuffer(); - - int result; - while ((result = mBackBuffer->Lock(aUsage, aRect, bits)) == -EBUSY) { - usleep(1000); // 1ms - } - - return result == 0; -} - -bool -AndroidDirectTexture::Unlock(bool aFlip) -{ - if (aFlip) { - mNeedFlip = true; - } - - bool result = mBackBuffer->Unlock(); - mLock.Unlock(); - - return result; -} - -bool -AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight) { - return Reallocate(aWidth, aHeight, mFormat); -} - -bool -AndroidDirectTexture::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat) -{ - MutexAutoLock lock(mLock); - - // We only reallocate the current back buffer. The front buffer is likely - // in use, so we'll reallocate it on the first Lock() after it is rotated - // to the back. - bool result = mBackBuffer->Reallocate(aWidth, aHeight, aFormat); - if (result) { - mPendingReallocBuffer = mFrontBuffer; - - mWidth = aWidth; - mHeight = aHeight; - } - - return result; -} - -bool -AndroidDirectTexture::Bind() -{ - MutexAutoLock lock(mLock); - - if (mNeedFlip) { - AndroidGraphicBuffer* tmp = mBackBuffer; - mBackBuffer = mFrontBuffer; - mFrontBuffer = tmp; - mNeedFlip = false; - } - - return mFrontBuffer->Bind(); -} - -} /* mozilla */
deleted file mode 100644 --- a/widget/android/AndroidGraphicBuffer.cpp +++ /dev/null @@ -1,501 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <dlfcn.h> -#include <android/log.h> -#include <GLES2/gl2.h> -#include <nsTArray.h> -#include "AndroidGraphicBuffer.h" -#include "AndroidBridge.h" -#include "GLTypes.h" -#include "mozilla/Preferences.h" - -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidGraphicBuffer" , ## args) - -#define EGL_NATIVE_BUFFER_ANDROID 0x3140 -#define EGL_IMAGE_PRESERVED_KHR 0x30D2 - -typedef void *EGLContext; -typedef void *EGLDisplay; -typedef uint32_t EGLenum; -typedef int32_t EGLint; -typedef uint32_t EGLBoolean; - -#define EGL_TRUE 1 -#define EGL_FALSE 0 -#define EGL_NONE 0x3038 -#define EGL_DEFAULT_DISPLAY (void*)0 - -#define ANDROID_LIBUI_PATH "libui.so" -#define ANDROID_GLES_PATH "libGLESv2.so" -#define ANDROID_EGL_PATH "libEGL.so" - -// Really I have no idea, but this should be big enough -#define GRAPHIC_BUFFER_SIZE 1024 - -enum { - /* buffer is never read in software */ - GRALLOC_USAGE_SW_READ_NEVER = 0x00000000, - /* buffer is rarely read in software */ - GRALLOC_USAGE_SW_READ_RARELY = 0x00000002, - /* buffer is often read in software */ - GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003, - /* mask for the software read values */ - GRALLOC_USAGE_SW_READ_MASK = 0x0000000F, - - /* buffer is never written in software */ - GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000, - /* buffer is never written in software */ - GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020, - /* buffer is never written in software */ - GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030, - /* mask for the software write values */ - GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0, - - /* buffer will be used as an OpenGL ES texture */ - GRALLOC_USAGE_HW_TEXTURE = 0x00000100, - /* buffer will be used as an OpenGL ES render target */ - GRALLOC_USAGE_HW_RENDER = 0x00000200, - /* buffer will be used by the 2D hardware blitter */ - GRALLOC_USAGE_HW_2D = 0x00000400, - /* buffer will be used with the framebuffer device */ - GRALLOC_USAGE_HW_FB = 0x00001000, - /* mask for the software usage bit-mask */ - GRALLOC_USAGE_HW_MASK = 0x00001F00, -}; - -enum { - HAL_PIXEL_FORMAT_RGBA_8888 = 1, - HAL_PIXEL_FORMAT_RGBX_8888 = 2, - HAL_PIXEL_FORMAT_RGB_888 = 3, - HAL_PIXEL_FORMAT_RGB_565 = 4, - HAL_PIXEL_FORMAT_BGRA_8888 = 5, - HAL_PIXEL_FORMAT_RGBA_5551 = 6, - HAL_PIXEL_FORMAT_RGBA_4444 = 7, -}; - -typedef struct ARect { - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -} ARect; - -static bool gTryRealloc = true; - -static class GLFunctions -{ -public: - constexpr GLFunctions() : fGetDisplay(nullptr), - fEGLGetError(nullptr), - fCreateImageKHR(nullptr), - fDestroyImageKHR(nullptr), - fImageTargetTexture2DOES(nullptr), - fBindTexture(nullptr), - fGLGetError(nullptr), - fGraphicBufferCtor(nullptr), - fGraphicBufferDtor(nullptr), - fGraphicBufferLock(nullptr), - fGraphicBufferLockRect(nullptr), - fGraphicBufferUnlock(nullptr), - fGraphicBufferGetNativeBuffer(nullptr), - fGraphicBufferReallocate(nullptr), - mInitialized(false) - { - } - - typedef EGLDisplay (* pfnGetDisplay)(void *display_id); - pfnGetDisplay fGetDisplay; - typedef EGLint (* pfnEGLGetError)(void); - pfnEGLGetError fEGLGetError; - - typedef EGLImageKHR (* pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); - pfnCreateImageKHR fCreateImageKHR; - typedef EGLBoolean (* pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image); - pfnDestroyImageKHR fDestroyImageKHR; - - typedef void (* pfnImageTargetTexture2DOES)(GLenum target, EGLImageKHR image); - pfnImageTargetTexture2DOES fImageTargetTexture2DOES; - - typedef void (* pfnBindTexture)(GLenum target, GLuint texture); - pfnBindTexture fBindTexture; - - typedef GLenum (* pfnGLGetError)(); - pfnGLGetError fGLGetError; - - typedef void (*pfnGraphicBufferCtor)(void*, uint32_t w, uint32_t h, uint32_t format, uint32_t usage); - pfnGraphicBufferCtor fGraphicBufferCtor; - - typedef void (*pfnGraphicBufferDtor)(void*); - pfnGraphicBufferDtor fGraphicBufferDtor; - - typedef int (*pfnGraphicBufferLock)(void*, uint32_t usage, unsigned char **addr); - pfnGraphicBufferLock fGraphicBufferLock; - - typedef int (*pfnGraphicBufferLockRect)(void*, uint32_t usage, const ARect&, unsigned char **addr); - pfnGraphicBufferLockRect fGraphicBufferLockRect; - - typedef int (*pfnGraphicBufferUnlock)(void*); - pfnGraphicBufferUnlock fGraphicBufferUnlock; - - typedef void* (*pfnGraphicBufferGetNativeBuffer)(void*); - pfnGraphicBufferGetNativeBuffer fGraphicBufferGetNativeBuffer; - - typedef int (*pfnGraphicBufferReallocate)(void*, uint32_t w, uint32_t h, uint32_t format); - pfnGraphicBufferReallocate fGraphicBufferReallocate; - - bool EnsureInitialized() - { - if (mInitialized) { - return true; - } - - void *handle = dlopen(ANDROID_EGL_PATH, RTLD_LAZY); - if (!handle) { - LOG("Couldn't load EGL library"); - return false; - } - - fGetDisplay = (pfnGetDisplay)dlsym(handle, "eglGetDisplay"); - fEGLGetError = (pfnEGLGetError)dlsym(handle, "eglGetError"); - fCreateImageKHR = (pfnCreateImageKHR)dlsym(handle, "eglCreateImageKHR"); - fDestroyImageKHR = (pfnDestroyImageKHR)dlsym(handle, "eglDestroyImageKHR"); - - if (!fGetDisplay || !fEGLGetError || !fCreateImageKHR || !fDestroyImageKHR) { - LOG("Failed to find some EGL functions"); - return false; - } - - handle = dlopen(ANDROID_GLES_PATH, RTLD_LAZY); - if (!handle) { - LOG("Couldn't load GL library"); - return false; - } - - fImageTargetTexture2DOES = (pfnImageTargetTexture2DOES)dlsym(handle, "glEGLImageTargetTexture2DOES"); - fBindTexture = (pfnBindTexture)dlsym(handle, "glBindTexture"); - fGLGetError = (pfnGLGetError)dlsym(handle, "glGetError"); - - if (!fImageTargetTexture2DOES || !fBindTexture || !fGLGetError) { - LOG("Failed to find some GL functions"); - return false; - } - - handle = dlopen(ANDROID_LIBUI_PATH, RTLD_LAZY); - if (!handle) { - LOG("Couldn't load libui.so"); - return false; - } - - fGraphicBufferCtor = (pfnGraphicBufferCtor)dlsym(handle, "_ZN7android13GraphicBufferC1Ejjij"); - fGraphicBufferDtor = (pfnGraphicBufferDtor)dlsym(handle, "_ZN7android13GraphicBufferD1Ev"); - fGraphicBufferLock = (pfnGraphicBufferLock)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjPPv"); - fGraphicBufferLockRect = (pfnGraphicBufferLockRect)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjRKNS_4RectEPPv"); - fGraphicBufferUnlock = (pfnGraphicBufferUnlock)dlsym(handle, "_ZN7android13GraphicBuffer6unlockEv"); - fGraphicBufferGetNativeBuffer = (pfnGraphicBufferGetNativeBuffer)dlsym(handle, "_ZNK7android13GraphicBuffer15getNativeBufferEv"); - fGraphicBufferReallocate = (pfnGraphicBufferReallocate)dlsym(handle, "_ZN7android13GraphicBuffer10reallocateEjjij"); - - if (!fGraphicBufferCtor || !fGraphicBufferDtor || !fGraphicBufferLock || - !fGraphicBufferUnlock || !fGraphicBufferGetNativeBuffer) { - LOG("Failed to lookup some GraphicBuffer functions"); - return false; - } - - mInitialized = true; - return true; - } - -private: - bool mInitialized; - -} sGLFunctions; - -namespace mozilla { - -static void clearGLError() -{ - while (glGetError() != GL_NO_ERROR); -} - -static bool ensureNoGLError(const char* name) -{ - bool result = true; - GLuint error; - - while ((error = glGetError()) != GL_NO_ERROR) { - LOG("GL error [%s]: %40x\n", name, error); - result = false; - } - - return result; -} - -AndroidGraphicBuffer::AndroidGraphicBuffer(uint32_t width, uint32_t height, uint32_t usage, - gfxImageFormat format) : - mWidth(width) - , mHeight(height) - , mUsage(usage) - , mFormat(format) - , mHandle(0) - , mEGLImage(0) -{ -} - -AndroidGraphicBuffer::~AndroidGraphicBuffer() -{ - DestroyBuffer(); -} - -void -AndroidGraphicBuffer::DestroyBuffer() -{ - /** - * XXX: eglDestroyImageKHR crashes sometimes due to refcount badness (I think) - * - * If you look at egl.cpp (https://github.com/android/platform_frameworks_base/blob/master/opengl/libagl/egl.cpp#L2002) - * you can see that eglCreateImageKHR just refs the native buffer, and eglDestroyImageKHR - * just unrefs it. Somehow the ref count gets messed up and things are already destroyed - * by the time eglDestroyImageKHR gets called. For now, at least, just not calling - * eglDestroyImageKHR should be fine since we do free the GraphicBuffer below. - * - * Bug 712716 - */ -#if 0 - if (mEGLImage) { - if (sGLFunctions.EnsureInitialized()) { - sGLFunctions.fDestroyImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), mEGLImage); - mEGLImage = nullptr; - } - } -#endif - mEGLImage = nullptr; - - if (mHandle) { - if (sGLFunctions.EnsureInitialized()) { - sGLFunctions.fGraphicBufferDtor(mHandle); - } - free(mHandle); - mHandle = nullptr; - } - -} - -bool -AndroidGraphicBuffer::EnsureBufferCreated() -{ - if (!mHandle) { - mHandle = malloc(GRAPHIC_BUFFER_SIZE); - sGLFunctions.fGraphicBufferCtor(mHandle, mWidth, mHeight, GetAndroidFormat(mFormat), GetAndroidUsage(mUsage)); - } - - return true; -} - -bool -AndroidGraphicBuffer::EnsureInitialized() -{ - if (!sGLFunctions.EnsureInitialized()) { - return false; - } - - EnsureBufferCreated(); - return true; -} - -int -AndroidGraphicBuffer::Lock(uint32_t aUsage, unsigned char **bits) -{ - if (!EnsureInitialized()) - return true; - - return sGLFunctions.fGraphicBufferLock(mHandle, GetAndroidUsage(aUsage), bits); -} - -int -AndroidGraphicBuffer::Lock(uint32_t aUsage, const nsIntRect& aRect, unsigned char **bits) -{ - if (!EnsureInitialized()) - return false; - - ARect rect; - rect.left = aRect.x; - rect.top = aRect.y; - rect.right = aRect.x + aRect.width; - rect.bottom = aRect.y + aRect.height; - - return sGLFunctions.fGraphicBufferLockRect(mHandle, GetAndroidUsage(aUsage), rect, bits); -} - -int -AndroidGraphicBuffer::Unlock() -{ - if (!EnsureInitialized()) - return false; - - return sGLFunctions.fGraphicBufferUnlock(mHandle); -} - -bool -AndroidGraphicBuffer::Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat) -{ - if (!EnsureInitialized()) - return false; - - mWidth = aWidth; - mHeight = aHeight; - mFormat = aFormat; - - // Sometimes GraphicBuffer::reallocate just doesn't work. In those cases we'll just allocate a brand - // new buffer. If reallocate fails once, never try it again. - if (!gTryRealloc || sGLFunctions.fGraphicBufferReallocate(mHandle, aWidth, aHeight, GetAndroidFormat(aFormat)) != 0) { - DestroyBuffer(); - EnsureBufferCreated(); - - gTryRealloc = false; - } - - return true; -} - -uint32_t -AndroidGraphicBuffer::GetAndroidUsage(uint32_t aUsage) -{ - uint32_t flags = 0; - - if (aUsage & UsageSoftwareRead) { - flags |= GRALLOC_USAGE_SW_READ_OFTEN; - } - - if (aUsage & UsageSoftwareWrite) { - flags |= GRALLOC_USAGE_SW_WRITE_OFTEN; - } - - if (aUsage & UsageTexture) { - flags |= GRALLOC_USAGE_HW_TEXTURE; - } - - if (aUsage & UsageTarget) { - flags |= GRALLOC_USAGE_HW_RENDER; - } - - if (aUsage & Usage2D) { - flags |= GRALLOC_USAGE_HW_2D; - } - - return flags; -} - -uint32_t -AndroidGraphicBuffer::GetAndroidFormat(gfxImageFormat aFormat) -{ - switch (aFormat) { - case SurfaceFormat::X8R8G8B8_UINT32: - return HAL_PIXEL_FORMAT_RGBX_8888; - case SurfaceFormat::R5G6B5_UINT16: - return HAL_PIXEL_FORMAT_RGB_565; - default: - return 0; - } -} - -bool -AndroidGraphicBuffer::EnsureEGLImage() -{ - if (mEGLImage) - return true; - - - if (!EnsureInitialized()) - return false; - - EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE }; - void* nativeBuffer = sGLFunctions.fGraphicBufferGetNativeBuffer(mHandle); - - mEGLImage = sGLFunctions.fCreateImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)nativeBuffer, eglImgAttrs); - return mEGLImage != nullptr; -} - -bool -AndroidGraphicBuffer::Bind() -{ - if (!EnsureInitialized()) - return false; - - if (!EnsureEGLImage()) { - LOG("No valid EGLImage!"); - return false; - } - - clearGLError(); - sGLFunctions.fImageTargetTexture2DOES(GL_TEXTURE_2D, mEGLImage); - return ensureNoGLError("glEGLImageTargetTexture2DOES"); -} - -// Build whitelist to check for board type. -static void InitWhiteList(nsTArray<nsString>& list) -{ - nsString ele; - ele.AssignASCII("droid2"); // Motorola Droid 2 - list.AppendElement(ele); - ele.AssignASCII("GT-I9100"); // Samsung Galaxy SII - list.AppendElement(ele); - ele.AssignASCII("herring"); // Samsung Nexus S - list.AppendElement(ele); - ele.AssignASCII("omap4sdp"); // Amazon Kindle Fire - list.AppendElement(ele); - ele.AssignASCII("SGH-I897"); // Samsung Galaxy S - list.AppendElement(ele); - ele.AssignASCII("sgh-i997"); // Samsung Infuse 4G - list.AppendElement(ele); - ele.AssignASCII("sgh-t839"); // Samsung Sidekick 4G - list.AppendElement(ele); - ele.AssignASCII("shadow"); // Motorola Droid X - list.AppendElement(ele); - ele.AssignASCII("spyder"); // Motorola Razr - list.AppendElement(ele); - ele.AssignASCII("targa"); // Motorola Droid Bionic - list.AppendElement(ele); - ele.AssignASCII("tuna"); // Galaxy Nexus - list.AppendElement(ele); - ele.AssignASCII("venus2"); // Motorla Droid Pro - list.AppendElement(ele); -} - -bool -AndroidGraphicBuffer::IsBlacklisted() -{ - nsAutoString board; - if (!AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "BOARD", board)) - return true; - - NS_ConvertUTF16toUTF8 boardUtf8(board); - - if (Preferences::GetBool("direct-texture.force.enabled", false)) { - LOG("allowing board '%s' due to prefs override", boardUtf8.get()); - return false; - } - - if (Preferences::GetBool("direct-texture.force.disabled", false)) { - LOG("disallowing board '%s' due to prefs override", boardUtf8.get()); - return true; - } - - static nsTArray<nsString> sListAllowed; - if (sListAllowed.Length() == 0) { - InitWhiteList(sListAllowed); - } - - int i = -1; - if ((i = sListAllowed.BinaryIndexOf(board)) >= 0) { - nsString name = sListAllowed.ElementAt(i); - LOG("allowing board '%s' based on '%s'\n", boardUtf8.get(), NS_ConvertUTF16toUTF8(name).get()); - return false; - } - - LOG("disallowing board: %s\n", boardUtf8.get()); - return true; -} - -} /* mozilla */
--- a/widget/android/moz.build +++ b/widget/android/moz.build @@ -21,18 +21,16 @@ EXPORTS += [ 'AndroidJNIWrapper.h', 'GeneratedJNINatives.h', 'GeneratedJNIWrappers.h', ] UNIFIED_SOURCES += [ 'AndroidBridge.cpp', 'AndroidContentController.cpp', - 'AndroidDirectTexture.cpp', - 'AndroidGraphicBuffer.cpp', 'AndroidJavaWrappers.cpp', 'AndroidJNI.cpp', 'AndroidJNIWrapper.cpp', 'ANRReporter.cpp', 'GeneratedJNIWrappers.cpp', 'GfxInfo.cpp', 'NativeJSContainer.cpp', 'nsAndroidProtocolHandler.cpp', @@ -57,9 +55,12 @@ LOCAL_INCLUDES += [ '/dom/system/android', '/netwerk/base', '/netwerk/cache', '/widget', ] CXXFLAGS += ['-Wno-error=shadow'] +OS_LIBS += ['android'] + #DEFINES['DEBUG_WIDGETS'] = True +