Bug 744916 - Make the Java viewport keep track of its size in both CSS pixels and device pixels. r=kats

--HG--
extra : rebase_source : f733c2a4eadaeaa9c845b83886af8ab335250f85
This commit is contained in:
Joe Drew 2012-04-12 16:00:56 -04:00
parent 78533845be
commit 5248a80c1d
10 changed files with 82 additions and 29 deletions

View File

@ -307,13 +307,18 @@ CompositorParent::TransformShadowTree()
nsIntPoint scrollOffset = metrics->mViewportScrollOffset;
mContentSize = metrics->mContentSize;
mozilla::AndroidBridge::Bridge()->SetFirstPaintViewport(scrollOffset.x, scrollOffset.y,
1/rootScaleX, mContentSize.width,
mContentSize.height);
1/rootScaleX,
mContentSize.width,
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
mIsFirstPaint = false;
} else if (metrics && (metrics->mContentSize != mContentSize)) {
mContentSize = metrics->mContentSize;
mozilla::AndroidBridge::Bridge()->SetPageSize(1/rootScaleX, mContentSize.width,
mContentSize.height);
mContentSize.height,
metrics->mCSSContentSize.width,
metrics->mCSSContentSize.height);
}
// We synchronise the viewport information with Java after sending the above

View File

@ -225,7 +225,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
// and our zoom level (which may have diverged).
float scaleFactor = oldMetrics.zoomFactor / messageMetrics.getZoomFactor();
newMetrics = new ViewportMetrics(oldMetrics);
newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor));
newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor), messageMetrics.getCssPageSize());
break;
}
@ -322,12 +322,12 @@ public class GeckoLayerClient implements GeckoEventResponder,
* viewport information provided. setPageSize will never be invoked on the same frame that
* this function is invoked on; and this function will always be called prior to syncViewportInfo.
*/
public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, float pageWidth, float pageHeight) {
public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, float pageWidth, float pageHeight, float cssPageWidth, float cssPageHeight) {
synchronized (mLayerController) {
ViewportMetrics currentMetrics = new ViewportMetrics(mLayerController.getViewportMetrics());
currentMetrics.setOrigin(new PointF(offsetX, offsetY));
currentMetrics.setZoomFactor(zoom);
currentMetrics.setPageSize(new FloatSize(pageWidth, pageHeight));
currentMetrics.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
mLayerController.setViewportMetrics(currentMetrics);
// At this point, we have just switched to displaying a different document than we
// we previously displaying. This means we need to abort any panning/zooming animations
@ -347,7 +347,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
* is invoked on a frame, then this function will not be. For any given frame, this
* function will be invoked before syncViewportInfo.
*/
public void setPageSize(float zoom, float pageWidth, float pageHeight) {
public void setPageSize(float zoom, float pageWidth, float pageHeight, float cssPageWidth, float cssPageHeight) {
synchronized (mLayerController) {
// adjust the page dimensions to account for differences in zoom
// between the rendered content (which is what the compositor tells us)
@ -355,7 +355,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
float ourZoom = mLayerController.getZoomFactor();
pageWidth = pageWidth * ourZoom / zoom;
pageHeight = pageHeight * ourZoom /zoom;
mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight));
mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
// Here the page size of the document has changed, but the document being displayed
// is still the same. Therefore, we don't need to send anything to browser.js; any
// changes we need to make to the display port will get sent the next time we call

View File

@ -19,6 +19,8 @@ public class ImmutableViewportMetrics {
// because Java doesn't have the concept of const classes
public final float pageSizeWidth;
public final float pageSizeHeight;
public final float cssPageSizeWidth;
public final float cssPageSizeHeight;
public final float viewportRectBottom;
public final float viewportRectLeft;
public final float viewportRectRight;
@ -36,6 +38,10 @@ public class ImmutableViewportMetrics {
pageSizeWidth = pageSize.width;
pageSizeHeight = pageSize.height;
FloatSize cssPageSize = m.getCssPageSize();
cssPageSizeWidth = cssPageSize.width;
cssPageSizeHeight = cssPageSize.height;
zoomFactor = m.getZoomFactor();
}
@ -67,4 +73,8 @@ public class ImmutableViewportMetrics {
public FloatSize getPageSize() {
return new FloatSize(pageSizeWidth, pageSizeHeight);
}
public FloatSize getCssPageSize() {
return new FloatSize(cssPageSizeWidth, cssPageSizeHeight);
}
}

View File

@ -136,6 +136,10 @@ public class LayerController {
return mViewportMetrics.getPageSize();
}
public FloatSize getCssPageSize() {
return mViewportMetrics.getCssPageSize();
}
public PointF getOrigin() {
return mViewportMetrics.getOrigin();
}
@ -194,12 +198,12 @@ public class LayerController {
}
/** Sets the current page size. You must hold the monitor while calling this. */
public void setPageSize(FloatSize size) {
if (mViewportMetrics.getPageSize().fuzzyEquals(size))
public void setPageSize(FloatSize size, FloatSize cssSize) {
if (mViewportMetrics.getCssPageSize().equals(cssSize))
return;
ViewportMetrics viewportMetrics = new ViewportMetrics(mViewportMetrics);
viewportMetrics.setPageSize(size);
viewportMetrics.setPageSize(size, cssSize);
mViewportMetrics = new ImmutableViewportMetrics(viewportMetrics);
// Page size is owned by the layer client, so no need to notify it of

View File

@ -61,6 +61,7 @@ public class ViewportMetrics {
private static final String LOGTAG = "GeckoViewportMetrics";
private FloatSize mPageSize;
private FloatSize mCssPageSize;
private RectF mViewportRect;
private float mZoomFactor;
@ -69,18 +70,21 @@ public class ViewportMetrics {
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
mPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mCssPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
mViewportRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
mZoomFactor = 1.0f;
}
public ViewportMetrics(ViewportMetrics viewport) {
mPageSize = new FloatSize(viewport.getPageSize());
mCssPageSize = new FloatSize(viewport.getCssPageSize());
mViewportRect = new RectF(viewport.getViewport());
mZoomFactor = viewport.getZoomFactor();
}
public ViewportMetrics(ImmutableViewportMetrics viewport) {
mPageSize = new FloatSize(viewport.pageSizeWidth, viewport.pageSizeHeight);
mCssPageSize = new FloatSize(viewport.cssPageSizeWidth, viewport.cssPageSizeHeight);
mViewportRect = new RectF(viewport.viewportRectLeft,
viewport.viewportRectTop,
viewport.viewportRectRight,
@ -96,9 +100,12 @@ public class ViewportMetrics {
float height = (float)json.getDouble("height");
float pageWidth = (float)json.getDouble("pageWidth");
float pageHeight = (float)json.getDouble("pageHeight");
float cssPageWidth = (float)json.getDouble("cssPageWidth");
float cssPageHeight = (float)json.getDouble("cssPageHeight");
float zoom = (float)json.getDouble("zoom");
mPageSize = new FloatSize(pageWidth, pageHeight);
mCssPageSize = new FloatSize(cssPageWidth, cssPageHeight);
mViewportRect = new RectF(x, y, x + width, y + height);
mZoomFactor = zoom;
}
@ -139,12 +146,18 @@ public class ViewportMetrics {
return mPageSize;
}
public FloatSize getCssPageSize() {
return mCssPageSize;
}
public float getZoomFactor() {
return mZoomFactor;
}
public void setPageSize(FloatSize pageSize) {
public void setPageSize(FloatSize pageSize, FloatSize cssPageSize) {
mPageSize = pageSize;
mCssPageSize = cssPageSize;
}
public void setViewport(RectF viewport) {
@ -171,14 +184,17 @@ public class ViewportMetrics {
* after scaling.
*/
public void scaleTo(float newZoomFactor, PointF focus) {
// mCssPageSize is invariant, since we're setting the scale factor
// here. The page size is based on the CSS page size.
mPageSize = mCssPageSize.scale(newZoomFactor);
float scaleFactor = newZoomFactor / mZoomFactor;
mPageSize = mPageSize.scale(scaleFactor);
PointF origin = getOrigin();
origin.offset(focus.x, focus.y);
origin = PointUtils.scale(origin, scaleFactor);
origin.offset(-focus.x, -focus.y);
setOrigin(origin);
mZoomFactor = newZoomFactor;
@ -192,6 +208,7 @@ public class ViewportMetrics {
public ViewportMetrics interpolate(ViewportMetrics to, float t) {
ViewportMetrics result = new ViewportMetrics();
result.mPageSize = mPageSize.interpolate(to.mPageSize, t);
result.mCssPageSize = mCssPageSize.interpolate(to.mCssPageSize, t);
result.mZoomFactor = FloatUtils.interpolate(mZoomFactor, to.mZoomFactor, t);
result.mViewportRect = RectUtils.interpolate(mViewportRect, to.mViewportRect, t);
return result;
@ -199,6 +216,7 @@ public class ViewportMetrics {
public boolean fuzzyEquals(ViewportMetrics other) {
return mPageSize.fuzzyEquals(other.mPageSize)
&& mCssPageSize.fuzzyEquals(other.mCssPageSize)
&& RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect)
&& FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor);
}
@ -216,6 +234,8 @@ public class ViewportMetrics {
.append(", \"height\" : ").append(height)
.append(", \"pageWidth\" : ").append(mPageSize.width)
.append(", \"pageHeight\" : ").append(mPageSize.height)
.append(", \"cssPageWidth\" : ").append(mCssPageSize.width)
.append(", \"cssPageHeight\" : ").append(mCssPageSize.height)
.append(", \"zoom\" : ").append(mZoomFactor)
.append(" }");
return sb.toString();
@ -226,6 +246,7 @@ public class ViewportMetrics {
StringBuffer buff = new StringBuffer(128);
buff.append("v=").append(mViewportRect.toString())
.append(" p=").append(mPageSize.toString())
.append(" c=").append(mCssPageSize.toString())
.append(" z=").append(mZoomFactor);
return buff.toString();
}

View File

@ -1771,6 +1771,9 @@ Tab.prototype = {
height: gScreenHeight,
pageWidth: gScreenWidth,
pageHeight: gScreenHeight,
// We make up matching css page dimensions
cssPageWidth: gScreenWidth / this._zoom,
cssPageHeight: gScreenHeight / this._zoom,
zoom: this._zoom
};
@ -1786,6 +1789,9 @@ Tab.prototype = {
if (doc != null) {
let [pageWidth, pageHeight] = this.getPageSize(doc, viewport.width, viewport.height);
let cssPageWidth = pageWidth;
let cssPageHeight = pageHeight;
/* Transform the page width and height based on the zoom factor. */
pageWidth *= viewport.zoom;
pageHeight *= viewport.zoom;
@ -1796,6 +1802,8 @@ Tab.prototype = {
* send updates regardless of page size; we'll zoom to fit the content as needed.
*/
if (doc.readyState === 'complete' || (pageWidth >= gScreenWidth && pageHeight >= gScreenHeight)) {
viewport.cssPageWidth = cssPageWidth;
viewport.cssPageHeight = cssPageHeight;
viewport.pageWidth = pageWidth;
viewport.pageHeight = pageHeight;
}

View File

@ -1870,23 +1870,24 @@ AndroidBridge::IsTablet()
}
void
AndroidBridge::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight)
AndroidBridge::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SetFirstPaintViewport(aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight);
client->SetFirstPaintViewport(aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void
AndroidBridge::SetPageSize(float aZoom, float aPageWidth, float aPageHeight)
AndroidBridge::SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SetPageSize(aZoom, aPageWidth, aPageHeight);
client->SetPageSize(aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void

View File

@ -413,8 +413,9 @@ public:
void EnableNetworkNotifications();
void DisableNetworkNotifications();
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight);
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);

View File

@ -271,8 +271,8 @@ AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
jGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient");
jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFF)V");
jSetPageSize = getMethod("setPageSize", "(FFF)V");
jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V");
jSetPageSize = getMethod("setPageSize", "(FFFFF)V");
jSyncViewportInfoMethod = getMethod("syncViewportInfo",
"(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
@ -658,7 +658,8 @@ AndroidGeckoSurfaceView::Draw2D(jobject buffer, int stride)
}
void
AndroidGeckoLayerClient::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight)
AndroidGeckoLayerClient::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight)
{
NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
@ -666,11 +667,12 @@ AndroidGeckoLayerClient::SetFirstPaintViewport(float aOffsetX, float aOffsetY, f
return;
AndroidBridge::AutoLocalJNIFrame jniFrame(env);
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight);
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight,
aCssPageWidth, aCssPageHeight);
}
void
AndroidGeckoLayerClient::SetPageSize(float aZoom, float aPageWidth, float aPageHeight)
AndroidGeckoLayerClient::SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight)
{
NS_ASSERTION(!isNull(), "SetPageSize called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
@ -678,7 +680,7 @@ AndroidGeckoLayerClient::SetPageSize(float aZoom, float aPageWidth, float aPageH
return;
AndroidBridge::AutoLocalJNIFrame jniFrame(env);
return env->CallVoidMethod(wrapped_obj, jSetPageSize, aZoom, aPageWidth, aPageHeight);
return env->CallVoidMethod(wrapped_obj, jSetPageSize, aZoom, aPageWidth, aPageHeight, aCssPageWidth, aCssPageHeight);
}
void

View File

@ -202,8 +202,9 @@ public:
AndroidGeckoLayerClient() {}
AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight);
void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
float aCssPageWidth, float aCssPageHeight);
void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
void CreateFrame(AndroidLayerRendererFrame& aFrame);