From d6e3afde17d12e77ceea8a676353e858dd340e00 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 3 Feb 2012 15:48:26 -0800 Subject: [PATCH] Add a virtual layer and GL layer client implementation --- mobile/android/base/GeckoApp.java | 7 +++++- mobile/android/base/Makefile.in | 2 ++ mobile/android/base/gfx/GeckoLayerClient.java | 9 +++++++- mobile/android/base/gfx/Layer.java | 4 ++++ widget/android/AndroidBridge.cpp | 3 --- widget/android/AndroidJavaWrappers.cpp | 19 ++++++++++++++++ widget/android/AndroidJavaWrappers.h | 13 +++++++++++ widget/android/nsWindow.cpp | 22 ++++++++++++++----- 8 files changed, 69 insertions(+), 10 deletions(-) diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index d4efd18dafe..01850a0fd33 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -41,6 +41,7 @@ package org.mozilla.gecko; import org.mozilla.gecko.gfx.FloatSize; +import org.mozilla.gecko.gfx.GeckoGLLayerClient; import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient; import org.mozilla.gecko.gfx.IntSize; @@ -1591,8 +1592,12 @@ abstract public class GeckoApp /* * Create a layer client so that Gecko will have a buffer to draw into, but don't hook * it up to the layer controller yet. + * + * TODO: Switch between software and GL appropriately. */ - mLayerClient = new GeckoSoftwareLayerClient(this); + Log.e(LOGTAG, "### Creating GeckoGLLayerClient"); + mLayerClient = new GeckoGLLayerClient(this); + Log.e(LOGTAG, "### Done creating GeckoGLLayerClient"); /* * Hook a placeholder layer client up to the layer controller so that the user can pan diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 4eb6206044a..94c45dee759 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -110,6 +110,7 @@ FENNEC_JAVA_FILES = \ gfx/CheckerboardImage.java \ gfx/FlexibleGLSurfaceView.java \ gfx/FloatSize.java \ + gfx/GeckoGLLayerClient.java \ gfx/GeckoLayerClient.java \ gfx/GeckoSoftwareLayerClient.java \ gfx/GLController.java \ @@ -133,6 +134,7 @@ FENNEC_JAVA_FILES = \ gfx/TextureReaper.java \ gfx/TileLayer.java \ gfx/ViewportMetrics.java \ + gfx/VirtualLayer.java \ gfx/WidgetTileLayer.java \ ui/Axis.java \ ui/PanZoomController.java \ diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java index e59df807fd0..f08a908f984 100644 --- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -122,12 +122,17 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent public boolean beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata, boolean hasDirectTexture) { + Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + + tileHeight + " " + hasDirectTexture); + // If we've changed surface types, cancel this draw if (handleDirectTextureChange(hasDirectTexture)) { + Log.e(LOGTAG, "### Cancelling draw due to direct texture change"); return false; } if (!shouldDrawProceed(tileWidth, tileHeight)) { + Log.e(LOGTAG, "### Cancelling draw due to shouldDrawProceed()"); return false; } @@ -202,6 +207,8 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent /* Informs Gecko that the screen size has changed. */ protected void sendResizeEventIfNecessary(boolean force) { + Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force); + DisplayMetrics metrics = new DisplayMetrics(); GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); @@ -219,7 +226,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); IntSize bufferSize = getBufferSize(), tileSize = getTileSize(); - Log.i(LOGTAG, "Screen-size changed to " + mScreenSize); + Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize); GeckoEvent event = new GeckoEvent(GeckoEvent.SIZE_CHANGED, bufferSize.width, bufferSize.height, metrics.widthPixels, metrics.heightPixels, diff --git a/mobile/android/base/gfx/Layer.java b/mobile/android/base/gfx/Layer.java index 099acba340d..57766f8550b 100644 --- a/mobile/android/base/gfx/Layer.java +++ b/mobile/android/base/gfx/Layer.java @@ -186,6 +186,10 @@ public abstract class Layer { return true; } + protected boolean dimensionChangesPending() { + return (mNewOrigin != null) || (mNewResolution != 0.0f); + } + public static class RenderContext { public final RectF viewport; public final FloatSize pageSize; diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index ffde0a50c7c..a34a910f6b0 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -966,12 +966,9 @@ AndroidBridge::SetLayerClient(jobject obj, jint type) break; } case LAYER_CLIENT_TYPE_GL: { - // TODO: Implement. -#if 0 AndroidGeckoGLLayerClient *client = new AndroidGeckoGLLayerClient(); client->Init(obj); mLayerClient = client; -#endif break; } default: diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index a592b56286b..05260ddf716 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -117,6 +117,8 @@ jmethodID AndroidGeckoSoftwareLayerClient::jLockBufferMethod = 0; jmethodID AndroidGeckoSoftwareLayerClient::jUnlockBufferMethod = 0; jmethodID AndroidGeckoSoftwareLayerClient::jGetRenderOffsetMethod = 0; +jclass AndroidGeckoGLLayerClient::jGeckoGLLayerClientClass = 0; + jclass AndroidGeckoSurfaceView::jGeckoSurfaceViewClass = 0; jmethodID AndroidGeckoSurfaceView::jBeginDrawingMethod = 0; jmethodID AndroidGeckoSurfaceView::jEndDrawingMethod = 0; @@ -351,6 +353,16 @@ AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(JNIEnv *jEnv) #endif } +void +AndroidGeckoGLLayerClient::InitGeckoGLLayerClientClass(JNIEnv *jEnv) +{ +#ifdef MOZ_JAVA_COMPOSITOR + initInit(); + + jGeckoGLLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoGLLayerClient"); +#endif +} + #undef initInit #undef initClassGlobalRef #undef getField @@ -608,6 +620,13 @@ AndroidGeckoSoftwareLayerClient::Init(jobject jobj) wrapped_obj = jobj; } +void +AndroidGeckoGLLayerClient::Init(jobject jobj) +{ + NS_ASSERTION(wrapped_obj == nsnull, "Init called on non-null wrapped_obj!"); + wrapped_obj = jobj; +} + void AndroidGeckoSurfaceView::Init(jobject jobj) { diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 5aef3052cbf..7b62271412b 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -193,6 +193,19 @@ protected: static jmethodID jGetRenderOffsetMethod; }; +class AndroidGeckoGLLayerClient : public AndroidGeckoLayerClient { +public: + static void InitGeckoGLLayerClientClass(JNIEnv *jEnv); + + void Init(jobject jobj); + + AndroidGeckoGLLayerClient() {} + AndroidGeckoGLLayerClient(jobject jobj) { Init(jobj); } + +private: + static jclass jGeckoGLLayerClientClass; +}; + class AndroidGeckoSurfaceView : public WrappedJavaObject { public: diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 198348e8085..c977b8e2bd8 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1200,13 +1200,18 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) return; } + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### OnDraw()"); + nsRefPtr 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) + if (gAndroidBounds.width <= 0 || gAndroidBounds.height <= 0) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", + "### No window size yet -- skipping draw!"); return; + } /* * Check to see whether the presentation shell corresponding to the document on the screen @@ -1221,6 +1226,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) metadataProvider->PaintingSuppressed(&paintingSuppressed); } if (paintingSuppressed) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Painting suppressed!"); return; } @@ -1267,6 +1273,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) if (!client.BeginDrawing(gAndroidBounds.width, gAndroidBounds.height, gAndroidTileSize.width, gAndroidTileSize.height, metadata, HasDirectTexture())) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### BeginDrawing returned false!"); return; } @@ -1276,6 +1283,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) unsigned char *bits = NULL; if (HasDirectTexture()) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Have direct texture!"); if (sDirectTexture->Width() != gAndroidBounds.width || sDirectTexture->Height() != gAndroidBounds.height) { sDirectTexture->Reallocate(gAndroidBounds.width, gAndroidBounds.height); @@ -1283,14 +1291,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) sDirectTexture->Lock(AndroidGraphicBuffer::UsageSoftwareWrite, dirtyRect, &bits); } else if (layerClientType == AndroidBridge::LAYER_CLIENT_TYPE_SOFTWARE) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Software layer client!"); bits = ((AndroidGeckoSoftwareLayerClient &)client).LockBufferBits(); + if (!bits) { + ALOG("### Failed to lock buffer"); + } } - if (!bits) { - ALOG("### Failed to lock buffer"); - } else if (targetSurface->CairoStatus()) { + if (targetSurface->CairoStatus()) { ALOG("### Failed to create a valid surface from the bitmap"); - } else { + } else if (bits || layerClientType == AndroidBridge::LAYER_CLIENT_TYPE_GL) { + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Calling DrawTo()!"); DrawTo(targetSurface, dirtyRect); } @@ -1300,6 +1311,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) ((AndroidGeckoSoftwareLayerClient &)client).UnlockBuffer(); } + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### Calling EndDrawing()!"); client.EndDrawing(dirtyRect); return; #endif