Partial removal of tiling, stub callouts
authorPatrick Walton <pwalton@mozilla.com>
Thu, 02 Feb 2012 19:28:22 -0800
changeset 92375 78631ebfbd86baf31a2501c4e042eb1fbd46a1c1
parent 92374 52e24cbce2dad1f2d8eb6734d532308597861478
child 92376 6a17b93d69336766e3407e720a2367611cd7027d
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.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
Partial removal of tiling, stub callouts
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
mobile/android/app/mobile.js
mobile/android/base/gfx/FlexibleGLSurfaceView.java
mobile/android/chrome/content/browser.js
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsWindow.cpp
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -42,16 +42,18 @@
 #include "ShadowLayersParent.h"
 #include "LayerManagerOGL.h"
 #include "nsIWidget.h"
 
 #if defined(MOZ_WIDGET_ANDROID)
 #include "AndroidBridge.h"
 #endif
 
+#include <android/log.h>
+
 namespace mozilla {
 namespace layers {
 
 CompositorParent::CompositorParent(nsIWidget* aWidget)
   : mStopped(false), mWidget(aWidget)
 {
   MOZ_COUNT_CTOR(CompositorParent);
 }
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -61,16 +61,18 @@
 
 #include "nsIServiceManager.h"
 #include "nsIConsoleService.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "sampler.h"
 
+#include <android/log.h>
+
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gl;
 
 #ifdef CHECK_CURRENT_PROGRAM
 int LayerManagerOGLProgram::sCurrentProgramKey = 0;
 #endif
@@ -573,16 +575,18 @@ LayerManagerOGL::FPSState::DrawFPS(GLCon
     TimeDuration duration = now - last;
     last = now;
     fps = rate / duration.ToSeconds() + .5;
     fcount = 0;
   }
 
   GLint viewport[4];
   context->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
+  __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Viewport: %d %d %d %d",
+                      viewport[0], viewport[1], viewport[2], viewport[3]);
 
   static GLuint texture;
   if (!initialized) {
     // Bind the number of textures we need, in this case one.
     context->fGenTextures(1, &texture);
     context->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
     context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MIN_FILTER,LOCAL_GL_NEAREST);
     context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MAG_FILTER,LOCAL_GL_NEAREST);
@@ -839,16 +843,18 @@ LayerManagerOGL::Render()
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   if (sDrawFPS) {
     mFPS.DrawFPS(mGLContext, GetCopy2DProgram());
   }
 
+  PerformPostRenderHook();
+
   if (mGLContext->IsDoubleBuffered()) {
     mGLContext->SwapBuffers();
     LayerManager::PostPresent();
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
@@ -931,16 +937,32 @@ LayerManagerOGL::Render()
   mGLContext->fDisableVertexAttribArray(vcattr);
   mGLContext->fDisableVertexAttribArray(tcattr);
 
   mGLContext->fFlush();
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 void
+LayerManagerOGL::PerformPreRenderHook()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  // TODO: AndroidBridge::PerformPreRenderHook();
+#endif
+}
+
+void
+LayerManagerOGL::PerformPostRenderHook()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  // TODO: AndroidBridge::PerformPostRenderHook();
+#endif
+}
+
+void
 LayerManagerOGL::SetWorldTransform(const gfxMatrix& aMatrix)
 {
   NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
                "SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
   NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
                "SetWorldTransform only accepts matrices with integer scale");
 
   mWorldMatrix = aMatrix;
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -394,17 +394,20 @@ public:
     DontApplyWorldTransform
   };
 
   /**
    * Setup the viewport and projection matrix for rendering
    * to a window of the given dimensions.
    */
   void SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy);
-  
+ 
+  void PerformPreRenderHook();
+  void PerformPostRenderHook();
+
   /**
    * Setup World transform matrix.
    * Transform will be ignored if it is not PreservesAxisAlignedRectangles
    * or has non integer scale
    */
   void SetWorldTransform(const gfxMatrix& aMatrix);
   gfxMatrix& GetWorldTransform(void);
   void WorldTransformRect(nsIntRect& aRect);
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -590,16 +590,17 @@ pref("ui.dragThresholdY", 25);
 pref("layers.acceleration.disabled", false);
 #elifdef ANDROID
 pref("layers.acceleration.disabled", false);
 #else
 pref("layers.acceleration.disabled", true);
 #endif
 
 pref("layers.offmainthreadcomposition.enabled", true);
+pref("layers.acceleration.draw-fps", true);
 
 pref("notification.feature.enabled", true);
 
 // prevent tooltips from showing up
 pref("browser.chrome.toolbar_tips", false);
 pref("indexedDB.feature.enabled", true);
 pref("dom.indexedDB.warningQuota", 5);
 
--- a/mobile/android/base/gfx/FlexibleGLSurfaceView.java
+++ b/mobile/android/base/gfx/FlexibleGLSurfaceView.java
@@ -37,16 +37,17 @@
 
 package org.mozilla.gecko.gfx;
 
 import org.mozilla.gecko.GeckoApp;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.opengl.GLSurfaceView;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
 public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
     private static final String LOGTAG = "GeckoFlexibleGLSurfaceView";
 
     private GLSurfaceView.Renderer mRenderer;
     private GLThread mGLThread; // Protected by this class's monitor.
@@ -89,30 +90,38 @@ public class FlexibleGLSurfaceView exten
      * like a GLSurfaceView. It is illegal to access the controller after this has been called.
      */
     public synchronized void createGLThread() {
         if (mGLThread != null) {
             throw new FlexibleGLSurfaceViewException("createGLThread() called with a GL thread " +
                                                      "already in place!");
         }
 
+        Log.e(LOGTAG, "### Creating GL thread!");
         mGLThread = new GLThread(mController);
         mGLThread.start();
+        notifyAll();
     }
 
     /**
      * Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is
      * fully shut down.
      */
     public synchronized Thread destroyGLThread() {
-        if (mGLThread == null) {
-            throw new FlexibleGLSurfaceViewException("destroyGLThread() called with no GL " +
-                                                     "thread active!");
+        // Wait for the GL thread to be started.
+        Log.e(LOGTAG, "### Waiting for GL thread to be created...");
+        while (mGLThread == null) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
         }
 
+        Log.e(LOGTAG, "### Destroying GL thread!");
         Thread glThread = mGLThread;
         mGLThread.shutdown();
         mGLThread = null;
         return glThread;
     }
 
     public synchronized void recreateSurface() {
         if (mGLThread == null) {
@@ -151,22 +160,31 @@ public class FlexibleGLSurfaceView exten
         mController.surfaceDestroyed();
         if (mGLThread != null) {
             mGLThread.surfaceDestroyed();
         }
     }
 
     // Called from the compositor thread
     public static GLController registerCxxCompositor() {
-        System.out.println("register layer comp");
-        FlexibleGLSurfaceView flexView = (FlexibleGLSurfaceView)GeckoApp.mAppContext.getLayerController().getView();
         try {
-            flexView.destroyGLThread().join();
-        } catch (InterruptedException e) {}
-        return flexView.getGLController();
+            Log.e(LOGTAG, "### registerCxxCompositor point A");
+            System.out.println("register layer comp");
+            Log.e(LOGTAG, "### registerCxxCompositor point B");
+            FlexibleGLSurfaceView flexView = (FlexibleGLSurfaceView)GeckoApp.mAppContext.getLayerController().getView();
+            Log.e(LOGTAG, "### registerCxxCompositor point C: " + flexView);
+            try {
+                flexView.destroyGLThread().join();
+            } catch (InterruptedException e) {}
+            Log.e(LOGTAG, "### registerCxxCompositor point D: " + flexView.getGLController());
+            return flexView.getGLController();
+        } catch (Exception e) {
+            Log.e(LOGTAG, "### Exception! " + e);
+            return null;
+        }
 /*
         synchronized (FlexibleGLSurfaceView.class) {
             // Wait for the layer controller if by some miracle
             // gecko beats the java thread here.
             while (mLayerController == null) {
                 try {
                     OGLSurfaceView.class.wait();
                 } catch (InterruptedException e) {}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1570,17 +1570,18 @@ Tab.prototype = {
       transformChanged = true;
     }
 
     if (transformChanged)
       this.updateTransform();
   },
 
   screenshot: function(aSrc, aDst) {
-      if (!this.browser || !this.browser.contentWindow)
+      // FIXME: Reenable
+      //if (!this.browser || !this.browser.contentWindow)
         return;
 
       let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
       canvas.setAttribute("width", aDst.width);  
       canvas.setAttribute("height", aDst.height);
       canvas.setAttribute("moz-opaque", "true");
 
       let ctx = canvas.getContext("2d");
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -1040,16 +1040,42 @@ AndroidBridge::RegisterCompositor()
 
     sController.Acquire(env, glController);
     sController.SetGLVersion(2);
     sController.InitGLContext();
     sController.WaitForValidSurface();
     return sController.GetEGLSurface();
 }
 
+void
+AndroidBridge::PerformPreRenderHook()
+{
+    JNIEnv *env = GetJNIForThread();
+    if (!env) {
+        return;
+    }
+
+    AutoLocalJNIFrame jniFrame(env, 3);
+
+    // TODO
+}
+
+void
+AndroidBridge::PerformPostRenderHook()
+{
+    JNIEnv *env = GetJNIForThread();
+    if (!env) {
+        return;
+    }
+
+    AutoLocalJNIFrame jniFrame(env, 3);
+
+    // TODO
+}
+
 bool
 AndroidBridge::GetStaticIntField(const char *className, const char *fieldName, PRInt32* aInt)
 {
     ALOG_BRIDGE("AndroidBridge::GetStaticIntField %s", fieldName);
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -305,16 +305,18 @@ public:
         JNIEnv* mJNIEnv;
     };
 
     /* See GLHelpers.java as to why this is needed */
     void *CallEglCreateWindowSurface(void *dpy, void *config, AndroidGeckoSurfaceView& surfaceView);
 
     // Switch Java to composite with the Gecko Compositor thread
     EGLSurface RegisterCompositor();
+    void PerformPreRenderHook();
+    void PerformPostRenderHook();
 
     bool GetStaticStringField(const char *classID, const char *field, nsAString &result);
 
     bool GetStaticIntField(const char *className, const char *fieldName, PRInt32* aInt);
 
     void SetKeepScreenOn(bool on);
 
     void ScanMedia(const nsAString& aFile, const nsACString& aMimeType);
@@ -484,16 +486,20 @@ protected:
     jclass jEGLContextImplClass;
     jclass jEGLConfigImplClass;
     jclass jEGLDisplayImplClass;
     jclass jEGLContextClass;
     jclass jEGL10Class;
 
     jclass jFlexSurfaceView;
 
+    jmethodID jRegisterCompositorMethod;
+    jmethodID jPerformPreRenderHookMethod;
+    jmethodID jPerformPostRenderHookMethod;
+
     // 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);
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -755,19 +755,20 @@ nsWindow::GetLayerManager(PLayersChild*,
 {
     if (aAllowRetaining) {
         *aAllowRetaining = true;
     }
     if (mLayerManager) {
         return mLayerManager;
     }
 
-    printf_stderr("nsWindow::GetLayerManager\n");
+    nsWindow *topWindow = TopWindow();
 
-    nsWindow *topWindow = TopWindow();
+    __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### nsWindow::GetLayerManager this=%p "
+                        "topWindow=%p", this, topWindow);
 
     if (!topWindow) {
         printf_stderr(" -- no topwindow\n");
         mLayerManager = CreateBasicLayerManager();
         return mLayerManager;
     }
 
     bool useCompositor =
@@ -1109,16 +1110,18 @@ nsWindow::DrawTo(gfxASurface *targetSurf
     if (coveringChildIndex == -1) {
         nsPaintEvent event(true, NS_PAINT, this);
 
         nsIntRect tileRect(0, 0, gAndroidBounds.width, gAndroidBounds.height);
         event.region = boundsRect.Intersect(invalidRect).Intersect(tileRect);
 
         switch (GetLayerManager(nsnull)->GetBackendType()) {
             case LayerManager::LAYERS_BASIC: {
+                __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Basic layers drawing");
+
                 nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
 
                 {
                     AutoLayerManagerSetup
                       setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
 
                     status = DispatchEvent(&event);
                 }
@@ -1131,16 +1134,18 @@ nsWindow::DrawTo(gfxASurface *targetSurf
 #endif
 
                 // XXX if we got an ignore for the parent, do we still want to draw the children?
                 // We don't really have a good way not to...
                 break;
             }
 
             case LayerManager::LAYERS_OPENGL: {
+                __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Basic layers drawing");
+
                 static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nsnull))->
                     SetClippingRegion(nsIntRegion(boundsRect));
 
                 status = DispatchEvent(&event);
                 break;
             }
 
             default:
@@ -1190,45 +1195,24 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
     }
 
     if (!mIsVisible) {
         ALOG("##### redraw for window %p, which is not visible -- ignoring!", (void*) this);
         DumpWindows();
         return;
     }
 
+    nsRefPtr<nsWindow> kungFuDeathGrip(this);
+
     AndroidBridge::AutoLocalJNIFrame jniFrame;
 #ifdef MOZ_JAVA_COMPOSITOR
     // We haven't been given a window-size yet, so do nothing
     if (gAndroidBounds.width <= 0 || gAndroidBounds.height <= 0)
         return;
 
-#if 0
-    // BEGIN HACK: gl layers
-    nsPaintEvent event(true, NS_PAINT, this);
-    nsIntRect tileRect(0, 0, gAndroidBounds.width, gAndroidBounds.height);
-    event.region = tileRect;
-
-    unsigned char *bits2 = new unsigned char[gAndroidBounds.width * gAndroidBounds.height * 2];
-    nsRefPtr<gfxImageSurface> targetSurface =
-        new gfxImageSurface(bits2,
-                            gfxIntSize(gAndroidBounds.width, gAndroidBounds.height),
-                            gAndroidBounds.width * 2,
-                            gfxASurface::ImageFormatRGB16_565);
-
-    nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
-    AutoLayerManagerSetup
-      setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
-    DispatchEvent(&event);
-
-    delete[] bits2;
-    return;
-    // END HACK: gl layers
-#endif
-
     /*
      * Check to see whether the presentation shell corresponding to the document on the screen
      * is suppressing painting. If it is, we bail out, as continuing would result in a mismatch
      * between the content on the screen and the current viewport metrics.
      */
     nsCOMPtr<nsIAndroidDrawMetadataProvider> metadataProvider =
         AndroidBridge::Bridge()->GetDrawMetadataProvider();
 
@@ -1240,27 +1224,58 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
         return;
     }
 
     nsAutoString metadata;
     if (metadataProvider) {
         metadataProvider->GetDrawMetadata(metadata);
     }
 
+#if 0
+    // BEGIN HACK: gl layers
+    nsPaintEvent event(true, NS_PAINT, this);
+    nsIntRect tileRect(0, 0, gAndroidBounds.width, gAndroidBounds.height);
+    event.region = tileRect;
+#endif
+
+    static unsigned char *bits2 = NULL;
+    static gfxIntSize bitsSize(0, 0);
+    if (bitsSize.width != gAndroidBounds.width || bitsSize.height != gAndroidBounds.height) {
+        if (bits2) {
+            delete[] bits2;
+        }
+        bits2 = new unsigned char[gAndroidBounds.width * gAndroidBounds.height * 2];
+        bitsSize = gAndroidBounds;
+    }
+
+    nsRefPtr<gfxImageSurface> targetSurface =
+        new gfxImageSurface(bits2,
+                            gfxIntSize(gAndroidBounds.width, gAndroidBounds.height),
+                            gAndroidBounds.width * 2,
+                            gfxASurface::ImageFormatRGB16_565);
+
+#if 0
+    nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
+    AutoLayerManagerSetup setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
+
+    nsEventStatus status;
+    status = DispatchEvent(&event);
+
+    return;
+    // END HACK: gl layers
+#endif
+
     AndroidGeckoSoftwareLayerClient &client =
         AndroidBridge::Bridge()->GetSoftwareLayerClient();
     if (!client.BeginDrawing(gAndroidBounds.width, gAndroidBounds.height,
                              gAndroidTileSize.width, gAndroidTileSize.height,
                              metadata, HasDirectTexture())) {
         return;
     }
 
-    nsIntPoint renderOffset;
-    client.GetRenderOffset(renderOffset);
-
     nsIntRect dirtyRect = ae->Rect().Intersect(nsIntRect(0, 0, gAndroidBounds.width, gAndroidBounds.height));
 
     unsigned char *bits = NULL;
     if (HasDirectTexture()) {
       if (sDirectTexture->Width() != gAndroidBounds.width ||
           sDirectTexture->Height() != gAndroidBounds.height) {
         sDirectTexture->Reallocate(gAndroidBounds.width, gAndroidBounds.height);
       }
@@ -1276,36 +1291,24 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
         int tileWidth = (gAndroidTileSize.width > 0) ? gAndroidTileSize.width : gAndroidBounds.width;
         int tileHeight = (gAndroidTileSize.height > 0) ? gAndroidTileSize.height : gAndroidBounds.height;
 
         int offset = 0;
 
         // It is assumed that the buffer has been over-allocated so that not
         // only is the tile-size constant, but that a render-offset of anything
         // up to (but not including) the tile size could be accommodated.
-        for (int y = 0; y < gAndroidBounds.height + gAndroidTileSize.height; y += tileHeight) {
-            for (int x = 0; x < gAndroidBounds.width + gAndroidTileSize.width; x += tileWidth) {
+        int x = 0, y = 0;
 
-                nsRefPtr<gfxImageSurface> targetSurface =
-                    new gfxImageSurface(bits + offset,
-                                        gfxIntSize(tileWidth, tileHeight),
-                                        tileWidth * 2,
-                                        gfxASurface::ImageFormatRGB16_565);
 
-                offset += tileWidth * tileHeight * 2;
-
-                if (targetSurface->CairoStatus()) {
-                    ALOG("### Failed to create a valid surface from the bitmap");
-                    break;
-                } else {
-                    targetSurface->SetDeviceOffset(gfxPoint(renderOffset.x - x,
-                                                            renderOffset.y - y));
-                    DrawTo(targetSurface, dirtyRect);
-                }
-            }
+        if (targetSurface->CairoStatus()) {
+            ALOG("### Failed to create a valid surface from the bitmap");
+            //break;
+        } else {
+            DrawTo(targetSurface, dirtyRect);
         }
     }
 
     if (HasDirectTexture()) {
         sDirectTexture->Unlock();
     } else {
         client.UnlockBuffer();
     }