Expose the necessary Java routines to render decorations through JNI

This commit is contained in:
Patrick Walton 2012-02-09 22:58:18 -08:00
parent 8e9cf5b1f7
commit f87504cb9a
4 changed files with 166 additions and 13 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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()
{

View File

@ -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;
};