Bug 729646 - Allow Java to update the display port on background tabs as well, so that we draw the right thing upon switching to it. r=Cwiiis

This commit is contained in:
Kartikaya Gupta 2012-03-15 10:38:43 -04:00
parent 13abc56f42
commit 883f015b2b
2 changed files with 45 additions and 24 deletions

View File

@ -69,6 +69,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
private IntSize mScreenSize;
private IntSize mWindowSize;
private RectF mDisplayPort;
private RectF mReturnDisplayPort;
private VirtualLayer mRootLayer;
@ -102,6 +103,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
mLayerRenderer = new LayerRenderer(view);
GeckoAppShell.registerGeckoEventListener("Viewport:Update", this);
GeckoAppShell.registerGeckoEventListener("Viewport:CalculateDisplayPort", this);
view.setListener(this);
view.setLayerRenderer(mLayerRenderer);
@ -187,12 +189,10 @@ public class GeckoLayerClient implements GeckoEventResponder,
GeckoAppShell.viewSizeChanged();
}
private void updateDisplayPort() {
private static RectF calculateDisplayPort(ImmutableViewportMetrics metrics) {
float desiredXMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
float desiredYMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
ImmutableViewportMetrics metrics = mLayerController.getViewportMetrics();
// we need to avoid having a display port that is larger than the page, or we will end up
// painting things outside the page bounds (bug 729169). we simultaneously need to make
// the display port as large as possible so that we redraw less.
@ -244,11 +244,10 @@ public class GeckoLayerClient implements GeckoEventResponder,
// content changes or zooming), the size of the display port should remain constant. this
// is intentional to avoid re-creating textures and all sorts of other reallocations in the
// draw and composition code.
mDisplayPort.left = metrics.viewportRectLeft - leftMargin;
mDisplayPort.top = metrics.viewportRectTop - topMargin;
mDisplayPort.right = metrics.viewportRectRight + rightMargin;
mDisplayPort.bottom = metrics.viewportRectBottom + bottomMargin;
return new RectF(metrics.viewportRectLeft - leftMargin,
metrics.viewportRectTop - topMargin,
metrics.viewportRectRight + rightMargin,
metrics.viewportRectBottom + bottomMargin);
}
private void adjustViewport() {
@ -257,14 +256,14 @@ public class GeckoLayerClient implements GeckoEventResponder,
viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
updateDisplayPort();
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(viewportMetrics, mDisplayPort));
}
/** Implementation of GeckoEventResponder/GeckoEventListener. */
public void handleMessage(String event, JSONObject message) {
if ("Viewport:Update".equals(event)) {
try {
try {
if ("Viewport:Update".equals(event)) {
ViewportMetrics newMetrics = new ViewportMetrics(message);
synchronized (mLayerController) {
// keep the old viewport size, but update everything else
@ -272,21 +271,33 @@ public class GeckoLayerClient implements GeckoEventResponder,
newMetrics.setSize(oldMetrics.getSize());
mLayerController.setViewportMetrics(newMetrics);
mLayerController.abortPanZoomAnimation(false);
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
mReturnDisplayPort = mDisplayPort;
}
} catch (JSONException e) {
Log.e(LOGTAG, "Unable to create viewport metrics in " + event + " handler", e);
} else if ("Viewport:CalculateDisplayPort".equals(event)) {
ImmutableViewportMetrics newMetrics = new ImmutableViewportMetrics(new ViewportMetrics(message));
mReturnDisplayPort = calculateDisplayPort(newMetrics);
}
} catch (JSONException e) {
Log.e(LOGTAG, "Unable to create viewport metrics in " + event + " handler", e);
}
}
/** Implementation of GeckoEventResponder. */
public String getResponse() {
// We are responding to the events handled in handleMessage() above with the
// display port we want. Note that all messages we are currently handling
// (just Viewport:Update) require this response, so we can just return this
// indiscriminately.
updateDisplayPort();
return RectUtils.toJSON(mDisplayPort);
// display port we calculated. Different messages will generate different
// display ports and put them in mReturnDisplayPort, so we just return that.
// Note that mReturnDisplayPort is always touched on the Gecko thread, so
// no synchronization is needed for it.
if (mReturnDisplayPort == null) {
return "";
}
try {
return RectUtils.toJSON(mReturnDisplayPort);
} finally {
mReturnDisplayPort = null;
}
}
void geometryChanged() {

View File

@ -1664,12 +1664,22 @@ Tab.prototype = {
},
sendViewportUpdate: function() {
if (BrowserApp.selectedTab != this)
return;
if (!BrowserApp.isBrowserContentDocumentDisplayed())
return;
let message = this.getViewport();
message.type = "Viewport:Update";
let message;
if (BrowserApp.selectedTab == this) {
// for foreground tabs, send the viewport update unless the document
// displayed is different from the content document
if (!BrowserApp.isBrowserContentDocumentDisplayed())
return;
message = this.getViewport();
message.type = "Viewport:Update";
} else {
// for bcakground tabs, request a new display port calculation, so that
// when we do switch to that tab, we have the correct display port and
// don't need to draw twice (once to allow the first-paint viewport to
// get to java, and again once java figures out the display port).
message = this.getViewport();
message.type = "Viewport:CalculateDisplayPort";
}
let displayPort = sendMessageToJava({ gecko: message });
if (displayPort != null)
this.setDisplayPort(message.x, message.y, JSON.parse(displayPort));