Bug 732091 - Part 5: Make the compositor notify Java when the page size changes or when a first paint occurs. r=bgirard
authorAli Juma <ajuma@mozilla.com>
Mon, 12 Mar 2012 11:50:27 -0400
changeset 89318 86d34ff552a7de049500e9460f9fea42f6227503
parent 89317 b5e523571e453debebc515023a49e83435f30229
child 89319 8a20a89149ac3c6f925d388abad25b81fdf88ed5
push id22242
push userkgupta@mozilla.com
push dateWed, 14 Mar 2012 15:19:09 +0000
treeherdermozilla-central@936ef50fa498 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard
bugs732091
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 732091 - Part 5: Make the compositor notify Java when the page size changes or when a first paint occurs. r=bgirard
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -173,17 +173,16 @@ CompositorParent::Composite()
 
   mLastCompose = mozilla::TimeStamp::Now();
 
   if (mPaused || !mLayerManager) {
     return;
   }
 
 #ifdef MOZ_WIDGET_ANDROID
-  RequestViewTransform();
   TransformShadowTree();
 #endif
 
   Layer* aLayer = mLayerManager->GetRoot();
   mozilla::layers::RenderTraceLayers(aLayer, "0000");
 
   mLayerManager->EndEmptyTransaction();
 
@@ -255,44 +254,62 @@ static double GetYScale(const gfx3DMatri
 }
 
 void
 CompositorParent::TransformShadowTree()
 {
 #ifdef MOZ_WIDGET_ANDROID
   Layer* layer = GetPrimaryScrollableLayer();
   ShadowLayer* shadow = layer->AsShadowLayer();
-
-  gfx3DMatrix shadowTransform = layer->GetTransform();
-
   ContainerLayer* container = layer->AsContainerLayer();
 
   const FrameMetrics* metrics = &container->GetFrameMetrics();
+  const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
   const gfx3DMatrix& currentTransform = layer->GetTransform();
 
+  float rootScaleX = GetXScale(rootTransform);
+  float rootScaleY = GetYScale(rootTransform);
+
+  if (mIsFirstPaint && metrics) {
+    nsIntPoint scrollOffset = metrics->mViewportScrollOffset;
+    mContentSize = metrics->mContentSize;
+    mozilla::AndroidBridge::Bridge()->SetFirstPaintViewport(scrollOffset.x, scrollOffset.y,
+                                                            1/rootScaleX, mContentSize.width,
+                                                            mContentSize.height);
+    mIsFirstPaint = false;
+  } else if (metrics && (metrics->mContentSize != mContentSize)) {
+    mContentSize = metrics->mContentSize;
+    mozilla::AndroidBridge::Bridge()->SetPageSize(1/rootScaleX, mContentSize.width,
+                                                  mContentSize.height);
+  }
+
+  // We request the view transform from Java after sending the above notifications,
+  // so that Java can take these into account in its response.
+  RequestViewTransform();
+
+  // Handle transformations for asynchronous panning and zooming. We determine the
+  // zoom used by Gecko from the transformation set on the root layer, and we
+  // determine the scroll offset used by Gecko from the frame metrics of the
+  // primary scrollable layer. We compare this to the desired zoom and scroll
+  // offset in the view transform we obtained from Java in order to compute the
+  // transformation we need to apply.
   if (metrics && metrics->IsScrollable()) {
-    float tempScaleDiffX = GetXScale(mLayerManager->GetRoot()->GetTransform()) * mXScale;
-    float tempScaleDiffY = GetYScale(mLayerManager->GetRoot()->GetTransform()) * mYScale;
+    float tempScaleDiffX = rootScaleX * mXScale;
+    float tempScaleDiffY = rootScaleY * mYScale;
 
     nsIntPoint metricsScrollOffset = metrics->mViewportScrollOffset;
 
     nsIntPoint scrollCompensation(
       (mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
       (mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
-    ViewTransform treeTransform(-scrollCompensation, mXScale,
-                              mYScale);
-    shadowTransform = gfx3DMatrix(treeTransform) * currentTransform;
-
-    shadow->SetShadowTransform(shadowTransform);
+    ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale);
+    shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
   } else {
-    ViewTransform treeTransform(nsIntPoint(0,0), mXScale,
-                              mYScale);
-    shadowTransform = gfx3DMatrix(treeTransform) * currentTransform;
-
-    shadow->SetShadowTransform(shadowTransform);
+    ViewTransform treeTransform(nsIntPoint(0,0), mXScale, mYScale);
+    shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
   }
 #endif
 }
 
 void
 CompositorParent::AsyncRender()
 {
   if (mPaused || !mLayerManager) {
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -138,16 +138,17 @@ private:
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   TimeStamp mExpectedComposeTime;
 #endif
 
   bool mPaused;
   float mXScale;
   float mYScale;
   nsIntPoint mScrollOffset;
+  nsIntSize mContentSize;
 
   // When this flag is set, the next composition will be the first for a
   // particular document (i.e. the document displayed on the screen will change).
   // This happens when loading a new page or switching tabs. We notify the
   // front-end (e.g. Java on Android) about this so that it take the new page
   // size and zoom into account when providing us with the next view transform.
   bool mIsFirstPaint;