Limit composite events to one at a time
authorBenoit Girard <b56girard@gmail.com>
Mon, 06 Feb 2012 12:38:23 -0500
changeset 90888 ea664069a4ff505b5591a0b7edb004048991e8a5
parent 90887 43016f417f0bc2a1d22c4078ecbc2eb9eb02af00
child 90889 a88d4cc81de327dee03d1db307366a6ace15677a
push idunknown
push userunknown
push dateunknown
milestone12.0a1
Limit composite events to one at a time
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -47,17 +47,19 @@
 #include "AndroidBridge.h"
 #include <android/log.h>
 #endif
 
 namespace mozilla {
 namespace layers {
 
 CompositorParent::CompositorParent(nsIWidget* aWidget)
-  : mPaused(false), mWidget(aWidget)
+  : mPaused(false)
+  , mWidget(aWidget)
+  , mCurrentCompositeTask(NULL)
 {
   MOZ_COUNT_CTOR(CompositorParent);
 }
 
 CompositorParent::~CompositorParent()
 {
   MOZ_COUNT_DTOR(CompositorParent);
 }
@@ -75,17 +77,16 @@ CompositorParent::Destroy()
 bool
 CompositorParent::RecvStop()
 {
   mPaused = true;
   Destroy();
   return true;
 }
 
-
 void
 CompositorParent::ScheduleRenderOnCompositorThread(::base::Thread &aCompositorThread)
 {
   CancelableTask *renderTask = NewRunnableMethod(this, &CompositorParent::AsyncRender);
   aCompositorThread.message_loop()->PostTask(FROM_HERE, renderTask);
 }
 
 void
@@ -122,19 +123,23 @@ CompositorParent::ScheduleResumeOnCompos
   CancelableTask *resumeTask = NewRunnableMethod(this,
                                                  &CompositorParent::ResumeComposition);
   aCompositorThread.message_loop()->PostTask(FROM_HERE, resumeTask);
 }
 
 void
 CompositorParent::ScheduleComposition()
 {
+  if (mCurrentCompositeTask) {
+    return;
+  }
+
   printf_stderr("Schedule composition\n");
-  CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
-  MessageLoop::current()->PostTask(FROM_HERE, composeTask);
+  mCurrentCompositeTask = NewRunnableMethod(this, &CompositorParent::Composite);
+  MessageLoop::current()->PostTask(FROM_HERE, mCurrentCompositeTask);
 
 // Test code for async scrolling.
 #ifdef OMTC_TEST_ASYNC_SCROLLING
   static bool scrollScheduled = false;
   if (!scrollScheduled) {
     CancelableTask *composeTask2 = NewRunnableMethod(this,
                                                      &CompositorParent::TestScroll);
     MessageLoop::current()->PostDelayedTask(FROM_HERE, composeTask2, 500);
@@ -149,20 +154,35 @@ CompositorParent::SetTransformation(floa
   mXScale = aScale;
   mYScale = aScale;
   mScrollOffset = aScrollOffset;
 }
 
 void
 CompositorParent::Composite()
 {
+  mCurrentCompositeTask = NULL;
+
   if (mPaused || !mLayerManager) {
     return;
   }
 
+#ifdef MOZ_WIDGET_ANDROID
+  RequestViewTransform();
+#endif
+
+  gfx3DMatrix worldTransform;
+  gfxPoint3D offset(-mScrollOffset.x, -mScrollOffset.y, 0.0f);
+  printf_stderr("Correcting for position fixed %i, %i\n", -mScrollOffset.x, -mScrollOffset.y);
+  worldTransform.Translate(offset);
+  worldTransform.Scale(mXScale, mYScale, 1.0f);
+  Layer* root = mLayerManager->GetRoot();
+  root->AsShadowLayer()->SetShadowTransform(worldTransform);
+
+
   mLayerManager->EndEmptyTransaction();
 }
 
 // Go down shadow layer tree, setting properties to match their non-shadow
 // counterparts.
 static void
 SetShadowProperties(Layer* aLayer)
 {
@@ -280,32 +300,22 @@ CompositorParent::AsyncRender()
     printf("mViewPortScrollOffset: x: %d, y: %d\n",
             metrics.mViewportScrollOffset.x,
             metrics.mViewportScrollOffset.y);
     // Modify framemetrics here, just as a test.
   metrics.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
   container->SetFrameMetrics(metrics);
 */
 
-#ifdef MOZ_WIDGET_ANDROID
-  RequestViewTransform();
-#endif
-
-  gfx3DMatrix worldTransform;
-  gfxPoint3D offset(-mScrollOffset.x, -mScrollOffset.y, 0.0f);
-  worldTransform.Translate(offset);
-  worldTransform.Scale(mXScale, mYScale, 1.0f);
-  root->AsShadowLayer()->SetShadowTransform(worldTransform);
-
 #if 0
   ViewTransform transform;
   TransformShadowTree(root, transform);
 #endif
 
-  Composite();
+  ScheduleComposition();
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 void
 CompositorParent::RequestViewTransform()
 {
   mozilla::AndroidBridge::Bridge()->GetViewTransform(mScrollOffset, mXScale, mYScale);
 
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -85,16 +85,17 @@ public:
 
   virtual void ShadowLayersUpdated() MOZ_OVERRIDE;
   void Destroy();
 
   LayerManager* GetLayerManager() { return mLayerManager; }
 
   void SetTransformation(float aScale, nsIntPoint aScrollOffset);
   void AsyncRender();
+  // Can be called from any thread
   void ScheduleRenderOnCompositorThread(::base::Thread &aCompositorThread);
 
   void PauseComposition();
   void ResumeComposition();
   void SchedulePauseOnCompositorThread(::base::Thread &aCompositorThread);
   void ScheduleResumeOnCompositorThread(::base::Thread &aCompositorThread);
 
 protected:
@@ -123,18 +124,20 @@ private:
   /**
    * Asks Java for the viewport position and updates the world transform
    * accordingly.
    */
   void RequestViewTransform();
 #endif
 
   nsRefPtr<LayerManager> mLayerManager;
+  nsIWidget* mWidget;
+  CancelableTask *mCurrentCompositeTask;
+
   bool mPaused;
-  nsIWidget* mWidget;
   float mXScale;
   float mYScale;
   nsIntPoint mScrollOffset;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
 
 } // layers