diff --git a/mobile/android/base/gfx/GeckoGLLayerClient.java b/mobile/android/base/gfx/GeckoGLLayerClient.java index fcc8714b790e..570005e4e0a2 100644 --- a/mobile/android/base/gfx/GeckoGLLayerClient.java +++ b/mobile/android/base/gfx/GeckoGLLayerClient.java @@ -44,6 +44,7 @@ import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.RectF; import android.util.Log; import android.view.View; @@ -51,6 +52,9 @@ public class GeckoGLLayerClient extends GeckoLayerClient implements FlexibleGLSurfaceView.Listener, VirtualLayer.Listener { private static final String LOGTAG = "GeckoGLLayerClient"; + private LayerRenderer mLayerRenderer; + private boolean mLayerRendererInitialized; + public GeckoGLLayerClient(Context context) { super(context); } @@ -95,7 +99,10 @@ public class GeckoGLLayerClient extends GeckoLayerClient public void setLayerController(LayerController layerController) { super.setLayerController(layerController); - ((FlexibleGLSurfaceView)layerController.getView()).setListener(this); + LayerView view = layerController.getView(); + view.setListener(this); + + mLayerRenderer = new LayerRenderer(view); } @Override @@ -211,5 +218,25 @@ public class GeckoGLLayerClient extends GeckoLayerClient compositionResumeRequested(); renderRequested(); } + + /** For Gecko to use. */ + public LayerRenderer.Frame createFrame(float offsetX, float offsetY, float zoomFactor) { + // Create the shaders and textures if necessary. + if (!mLayerRendererInitialized) { + mLayerRenderer.onSurfaceCreated(null, null); + } + + // FIXME: This geometry is surely wrong. + ViewportMetrics metrics = getLayerController().getViewportMetrics(); + FloatSize pageSize = metrics.getPageSize(), screenSize = metrics.getSize(); + RectF viewport = new RectF(offsetX, offsetY, offsetX + screenSize.width, + offsetY + screenSize.height); + + // Build the contexts and create the frame. + Layer.RenderContext pageContext = mLayerRenderer.createContext(viewport, pageSize, + zoomFactor); + Layer.RenderContext screenContext = mLayerRenderer.createScreenContext(); + return mLayerRenderer.createFrame(false, pageContext, screenContext); + } } diff --git a/mobile/android/base/gfx/LayerRenderer.java b/mobile/android/base/gfx/LayerRenderer.java index 1f89e3c03fda..d3cd4ad464f8 100644 --- a/mobile/android/base/gfx/LayerRenderer.java +++ b/mobile/android/base/gfx/LayerRenderer.java @@ -255,7 +255,8 @@ public class LayerRenderer implements GLSurfaceView.Renderer { * Called whenever a new frame is about to be drawn. */ public void onDrawFrame(GL10 gl) { - Frame frame = new Frame(true); + RenderContext pageContext = createPageContext(), screenContext = createScreenContext(); + Frame frame = createFrame(true, pageContext, screenContext); synchronized (mView.getController()) { frame.beginDrawing(); frame.drawBackground(); @@ -286,13 +287,12 @@ public class LayerRenderer implements GLSurfaceView.Renderer { return pixelBuffer; } - private RenderContext createScreenContext() { + public RenderContext createScreenContext() { LayerController layerController = mView.getController(); IntSize viewportSize = new IntSize(layerController.getViewportSize()); RectF viewport = new RectF(0.0f, 0.0f, viewportSize.width, viewportSize.height); FloatSize pageSize = new FloatSize(layerController.getPageSize()); - return new RenderContext(viewport, pageSize, 1.0f, mPositionHandle, mTextureHandle, - mCoordBuffer); + return createContext(viewport, pageSize, 1.0f); } private RenderContext createPageContext() { @@ -303,8 +303,12 @@ public class LayerRenderer implements GLSurfaceView.Renderer { FloatSize pageSize = new FloatSize(layerController.getPageSize()); float zoomFactor = layerController.getZoomFactor(); - return new RenderContext(new RectF(viewport), pageSize, zoomFactor, mPositionHandle, - mTextureHandle, mCoordBuffer); + return createContext(new RectF(viewport), pageSize, zoomFactor); + } + + public RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) { + return new RenderContext(viewport, pageSize, zoomFactor, mPositionHandle, mTextureHandle, + mCoordBuffer); } private Rect getPageRect() { @@ -423,6 +427,11 @@ public class LayerRenderer implements GLSurfaceView.Renderer { return shader; } + public Frame createFrame(boolean scissor, RenderContext pageContext, + RenderContext screenContext) { + return new Frame(scissor, pageContext, screenContext); + } + class FadeRunnable implements Runnable { private boolean mStarted; private long mRunAt; @@ -469,8 +478,10 @@ public class LayerRenderer implements GLSurfaceView.Renderer { // Whether a layer was updated. private boolean mUpdated; - public Frame(boolean scissor) { + public Frame(boolean scissor, RenderContext pageContext, RenderContext screenContext) { mScissor = scissor; + mPageContext = pageContext; + mScreenContext = screenContext; } public void beginDrawing() { @@ -479,13 +490,10 @@ public class LayerRenderer implements GLSurfaceView.Renderer { TextureReaper.get().reap(); TextureGenerator.get().fill(); - LayerController controller = mView.getController(); - mScreenContext = createScreenContext(); - mUpdated = true; + LayerController controller = mView.getController(); Layer rootLayer = controller.getRoot(); - mPageContext = createPageContext(); if (!mPageContext.fuzzyEquals(mLastPageContext)) { // the viewport or page changed, so show the scrollbars again @@ -558,7 +566,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer { } // Draws the layer the client added to us. - public void drawRootLayer() { + void drawRootLayer() { Layer rootLayer = mView.getController().getRoot(); if (rootLayer != null) rootLayer.draw(mPageContext); diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 76aada2edc18..8f421eef22e2 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -120,6 +120,13 @@ jmethodID AndroidGeckoSoftwareLayerClient::jGetRenderOffsetMethod = 0; jclass AndroidGeckoGLLayerClient::jGeckoGLLayerClientClass = 0; jmethodID AndroidGeckoGLLayerClient::jGetViewTransformMethod = 0; +jmethodID AndroidGeckoGLLayerClient::jCreateFrameMethod = 0; + +jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0; +jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0; +jmethodID AndroidLayerRendererFrame::jDrawBackgroundMethod = 0; +jmethodID AndroidLayerRendererFrame::jDrawForegroundMethod = 0; +jmethodID AndroidLayerRendererFrame::jEndDrawingMethod = 0; jclass AndroidViewTransform::jViewTransformClass = 0; jfieldID AndroidViewTransform::jXField = 0; @@ -162,6 +169,7 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv) AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv); AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(jEnv); AndroidGeckoGLLayerClient::InitGeckoGLLayerClientClass(jEnv); + AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv); AndroidViewTransform::InitViewTransformClass(jEnv); AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(jEnv); } @@ -377,6 +385,23 @@ AndroidGeckoGLLayerClient::InitGeckoGLLayerClientClass(JNIEnv *jEnv) jGetViewTransformMethod = getMethod("getViewTransform", "()Lorg/mozilla/gecko/gfx/ViewTransform;"); + jCreateFrameMethod = getMethod("createFrame", + "(FFF)Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;"); +#endif +} + +void +AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv) +{ +#ifdef MOZ_JAVA_COMPOSITOR + initInit(); + + jLayerRendererFrameClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerRenderer$Frame"); + + jBeginDrawingMethod = getMethod("beginDrawing", "()V"); + jDrawBackgroundMethod = getMethod("drawBackground", "()V"); + jDrawForegroundMethod = getMethod("drawForeground", "()V"); + jEndDrawingMethod = getMethod("endDrawing", "()V"); #endif } @@ -666,6 +691,13 @@ AndroidGeckoGLLayerClient::Init(jobject jobj) AndroidBridge::Bridge()->SetViewTransformGetter(mViewTransformGetter); } +void +AndroidLayerRendererFrame::Init(jobject jobj) +{ + NS_ASSERTION(wrapped_obj == nsnull, "Init called on non-null wrapped_obj!"); + wrapped_obj = jobj; +} + void AndroidViewTransform::Init(jobject jobj) { @@ -880,6 +912,70 @@ AndroidGeckoGLLayerClient::GetViewTransform(AndroidViewTransform& aViewTransform aViewTransform.Init(viewTransformJObj); } +void +AndroidGeckoGLLayerClient::CreateFrame(AndroidLayerRendererFrame& aFrame, + float aXOffset, float aYOffset, float aZoomFactor) +{ + JNIEnv *env = GetJNIForThread(); + NS_ABORT_IF_FALSE(env, "No JNI environment at CreateFrame()!"); + if (!env) { + return; + } + + jobject frameJObj = env->CallObjectMethod(wrapped_obj, jCreateFrameMethod, aXOffset, aYOffset, + aZoomFactor); + NS_ABORT_IF_FALSE(frameJObj, "No frame object!"); + aFrame.Init(frameJObj); +} + +void +AndroidLayerRendererFrame::BeginDrawing() +{ + JNIEnv *env = GetJNIForThread(); + NS_ABORT_IF_FALSE(env, "No JNI environment at BeginDrawing()!"); + if (!env) { + return; + } + + env->CallVoidMethod(wrapped_obj, jBeginDrawingMethod); +} + +void +AndroidLayerRendererFrame::DrawBackground() +{ + JNIEnv *env = GetJNIForThread(); + NS_ABORT_IF_FALSE(env, "No JNI environment at DrawBackground()!"); + if (!env) { + return; + } + + env->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod); +} + +void +AndroidLayerRendererFrame::DrawForeground() +{ + JNIEnv *env = GetJNIForThread(); + NS_ABORT_IF_FALSE(env, "No JNI environment at DrawForeground()!"); + if (!env) { + return; + } + + env->CallVoidMethod(wrapped_obj, jDrawForegroundMethod); +} + +void +AndroidLayerRendererFrame::EndDrawing() +{ + JNIEnv *env = GetJNIForThread(); + NS_ABORT_IF_FALSE(env, "No JNI environment at EndDrawing()!"); + if (!env) { + return; + } + + env->CallVoidMethod(wrapped_obj, jEndDrawingMethod); +} + float AndroidViewTransform::GetX() { diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 499731e2fa4b..eb5c4fb72640 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -237,6 +237,25 @@ private: static jfieldID jScaleField; }; +class AndroidLayerRendererFrame : public WrappedJavaObject { +public: + static void InitLayerRendererFrameClass(JNIEnv *jEnv); + + void Init(jobject jobj); + + void BeginDrawing(); + void DrawBackground(); + void DrawForeground(); + void EndDrawing(); + +private: + static jclass jLayerRendererFrameClass; + static jmethodID jBeginDrawingMethod; + static jmethodID jDrawBackgroundMethod; + static jmethodID jDrawForegroundMethod; + static jmethodID jEndDrawingMethod; +}; + class AndroidGeckoGLLayerClient : public AndroidGeckoLayerClient { public: static void InitGeckoGLLayerClientClass(JNIEnv *jEnv); @@ -250,10 +269,13 @@ public: : mViewTransformGetter(*this) { Init(jobj); } void GetViewTransform(AndroidViewTransform& aViewTransform); + void CreateFrame(AndroidLayerRendererFrame& aFrame, float aXOffset, float aYOffset, + float aZoomFactor); private: static jclass jGeckoGLLayerClientClass; static jmethodID jGetViewTransformMethod; + static jmethodID jCreateFrameMethod; AndroidGeckoGLLayerClientViewTransformGetter mViewTransformGetter; };