Bug 674753 - Add support for loading apitrace explicitly on Android - r=jrmuizel,bjacob
authorGeorge Wright <george@mozilla.com>
Wed, 29 Feb 2012 16:55:46 -0500
changeset 89282 aa51129a3495ee690917aa66f967fdef23d9402e
parent 89281 b9d1226647d8d9ffc108bede9efb4844b2577a5a
child 89283 92afa414d2621670e6ab1a55d3af5ae7a6582283
push id22242
push userkgupta@mozilla.com
push dateWed, 14 Mar 2012 15:19:09 +0000
treeherdermozilla-central@936ef50fa498 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, bjacob
bugs674753
milestone13.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
Bug 674753 - Add support for loading apitrace explicitly on Android - r=jrmuizel,bjacob
gfx/gl/GLContextProviderEGL.cpp
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -34,16 +34,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "mozilla/Preferences.h"
 #include "mozilla/Util.h"
 
 #if defined(XP_UNIX)
 
 #ifdef MOZ_WIDGET_GTK2
 #include <gdk/gdkx.h>
 // we're using default display for now
 #define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
@@ -64,16 +65,22 @@
 #endif
 
 #if defined(ANDROID)
 /* from widget */
 #if defined(MOZ_WIDGET_ANDROID)
 #include "AndroidBridge.h"
 #endif
 #include <android/log.h>
+
+// We only need to explicitly dlopen egltrace
+// on android as we can use LD_PRELOAD or other tricks
+// on other platforms. We look for it in /data/local
+// as that's writeable by all users
+#define APITRACE_LIB "/data/local/egltrace.so"
 #endif
 
 #define EGL_LIB "libEGL.so"
 #define GLES2_LIB "libGLESv2.so"
 #define EGL_LIB1 "libEGL.so.1"
 #define GLES2_LIB2 "libGLESv2.so.2"
 
 typedef void *EGLNativeDisplayType;
@@ -222,16 +229,48 @@ static EGLint gContextAttribs[] = {
 
 static EGLint gContextAttribsRobustness[] = {
     LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
     //LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE,
     LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
     LOCAL_EGL_NONE
 };
 
+static PRLibrary* LoadApitraceLibrary()
+{
+    PRLibrary* sApitraceLibrary = NULL;
+
+    if (sApitraceLibrary)
+        return sApitraceLibrary;
+
+#if defined(ANDROID)
+    nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
+
+    if (logFile.IsEmpty()) {
+        logFile = "firefox.trace";
+    }
+
+    // The firefox process can't write to /data/local, but it can write
+    // to $GRE_HOME/
+    nsCAutoString logPath;
+    logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
+
+    // apitrace uses the TRACE_FILE environment variable to determine where
+    // to log trace output to
+    printf_stderr("Logging GL tracing output to %s", logPath.get());
+    setenv("TRACE_FILE", logPath.get(), false);
+
+    printf_stderr("Attempting load of %s\n", APITRACE_LIB);
+
+    sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
+#endif
+
+    return sApitraceLibrary;
+}
+
 static int
 next_power_of_two(int v)
 {
     v--;
     v |= v >> 1;
     v |= v >> 2;
     v |= v >> 4;
     v |= v >> 8;
@@ -645,22 +684,27 @@ public:
                 break;
 
             eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
             eglFile->Load(&mEGLLibrary);
         } while (false);
 #endif
 
         if (!mEGLLibrary) {
-            mEGLLibrary = PR_LoadLibrary(EGL_LIB);
-#if defined(XP_UNIX)
+            mEGLLibrary = LoadApitraceLibrary();
+
             if (!mEGLLibrary) {
-                mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
+                printf_stderr("Attempting load of %s\n", EGL_LIB);
+                mEGLLibrary = PR_LoadLibrary(EGL_LIB);
+#if defined(XP_UNIX)
+                if (!mEGLLibrary) {
+                    mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
+                }
+#endif
             }
-#endif
         }
 
         if (!mEGLLibrary) {
             NS_WARNING("Couldn't load EGL LIB.");
             return false;
         }
 
 #define SYMBOL(name) \
@@ -1014,24 +1058,29 @@ public:
     }
 
     GLContextType GetContextType() {
         return ContextTypeEGL;
     }
 
     bool Init()
     {
-        if (!OpenLibrary(GLES2_LIB)) {
+#if defined(ANDROID)
+        // We can't use LoadApitraceLibrary here because the GLContext
+        // expects its own handle to the GL library
+        if (!OpenLibrary(APITRACE_LIB))
+#endif
+            if (!OpenLibrary(GLES2_LIB)) {
 #if defined(XP_UNIX)
-            if (!OpenLibrary(GLES2_LIB2)) {
-                NS_WARNING("Couldn't load EGL LIB.");
+                if (!OpenLibrary(GLES2_LIB2)) {
+                    NS_WARNING("Couldn't load GLES2 LIB.");
+                    return false;
+                }
+#endif
             }
-#endif
-            return false;
-        }
 
         bool current = MakeCurrent();
         if (!current) {
             gfx::LogFailure(NS_LITERAL_CSTRING(
                 "Couldn't get device attachments for device."));
             return false;
         }