Bug 779940: Meter layers transactions in addition to composites. r=cjones
authorMatt Woodrow <matt.woodrow@gmail.com>
Tue, 07 Aug 2012 14:41:29 +1200
changeset 105508 dbc34849f109bf134213e085cb02363f952a519d
parent 105507 b8893f7f80c5c76f739b9396a36822852329bc59
child 105509 88755b34790a1f42fa05163210b05f080376770d
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewerscjones
bugs779940
milestone17.0a1
Bug 779940: Meter layers transactions in addition to composites. r=cjones
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/ShadowLayers.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -318,16 +318,28 @@ CompositorParent::ScheduleTask(Cancelabl
   if (time == 0) {
     MessageLoop::current()->PostTask(FROM_HERE, task);
   } else {
     MessageLoop::current()->PostDelayedTask(FROM_HERE, task, time);
   }
 }
 
 void
+CompositorParent::NotifyShadowTreeTransaction()
+{
+  if (mLayerManager) {
+    ShadowLayerManager *shadow = mLayerManager->AsShadowManager();
+    if (shadow) {
+      shadow->NotifyShadowTreeTransaction();
+    }
+  }
+  ScheduleComposition();
+}
+
+void
 CompositorParent::ScheduleComposition()
 {
   if (mCurrentCompositeTask) {
     return;
   }
 
   bool initialComposition = mLastCompose.IsNull();
   TimeDuration delta;
@@ -882,16 +894,20 @@ CompositorParent::ShadowLayersUpdated(Sh
   mIsFirstPaint = mIsFirstPaint || isFirstPaint;
   mLayersUpdated = true;
   Layer* root = aLayerTree->GetRoot();
   mLayerManager->SetRoot(root);
   if (root) {
     SetShadowProperties(root);
   }
   ScheduleComposition();
+  ShadowLayerManager *shadow = mLayerManager->AsShadowManager();
+  if (shadow) {
+    shadow->NotifyShadowTreeTransaction();
+  }
 }
 
 PLayersParent*
 CompositorParent::AllocPLayers(const LayersBackend& aBackendHint,
                                const uint64_t& aId,
                                LayersBackend* aBackend,
                                int32_t* aMaxTextureSize)
 {
@@ -1189,17 +1205,17 @@ CrossProcessCompositorParent::ShadowLaye
   uint64_t id = aLayerTree->GetId();
   MOZ_ASSERT(id != 0);
   Layer* shadowRoot = aLayerTree->GetRoot();
   if (shadowRoot) {
     SetShadowProperties(shadowRoot);
   }
   UpdateIndirectTree(id, shadowRoot, isFirstPaint);
 
-  sCurrentCompositor->ScheduleComposition();
+  sCurrentCompositor->NotifyShadowTreeTransaction();
 }
 
 void
 CrossProcessCompositorParent::DeferredDestroy()
 {
   mSelfRef = NULL;
   // |this| was just destroyed, hands off
 }
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -81,17 +81,18 @@ public:
   void AsyncRender();
 
   // Can be called from any thread
   void ScheduleRenderOnCompositorThread();
   void SchedulePauseOnCompositorThread();
   void ScheduleResumeOnCompositorThread(int width, int height);
 
   virtual void ScheduleComposition();
-  
+  void NotifyShadowTreeTransaction();
+
   /**
    * Returns a pointer to the compositor corresponding to the given ID. 
    */
   static CompositorParent* GetCompositor(uint64_t id);
 
   /**
    * Returns the compositor thread's message loop.
    *
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -406,16 +406,18 @@ public:
   virtual already_AddRefed<ShadowImageLayer> CreateShadowImageLayer() = 0;
   /** CONSTRUCTION PHASE ONLY */
   virtual already_AddRefed<ShadowColorLayer> CreateShadowColorLayer() = 0;
   /** CONSTRUCTION PHASE ONLY */
   virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer() = 0;
   /** CONSTRUCTION PHASE ONLY */
   virtual already_AddRefed<ShadowRefLayer> CreateShadowRefLayer() { return nullptr; }
 
+  virtual void NotifyShadowTreeTransaction() {}
+
   /**
    * Try to open |aDescriptor| for direct texturing.  If the
    * underlying surface supports direct texturing, a non-null
    * TextureImage is returned.  Otherwise null is returned.
    */
   static already_AddRefed<TextureImage>
   OpenDescriptorForDirectTexturing(GLContext* aContext,
                                    const SurfaceDescriptor& aDescriptor,
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -509,31 +509,44 @@ LayerManagerOGL::RootLayer() const
     return nullptr;
   }
 
   return static_cast<LayerOGL*>(mRoot->ImplData());
 }
 
 bool LayerManagerOGL::sDrawFPS = false;
 
+void
+LayerManagerOGL::FPSState::NotifyShadowTreeTransaction()
+{
+  contentFCount++;
+}
+
 /* This function tries to stick to portable C89 as much as possible
  * so that it can be easily copied into other applications */
 void
 LayerManagerOGL::FPSState::DrawFPS(GLContext* context, ShaderProgramOGL* copyprog)
 {
   fcount++;
 
   int rate = 30;
   if (fcount >= rate) {
     TimeStamp now = TimeStamp::Now();
     TimeDuration duration = now - last;
     last = now;
     fps = rate / duration.ToSeconds() + .5;
     fcount = 0;
   }
+  if (contentFCount >= rate) {
+    TimeStamp now = TimeStamp::Now();
+    TimeDuration duration = now - contentLast;
+    contentLast = now;
+    contentFps = contentFCount / duration.ToSeconds() + .5;
+    contentFCount = 0;
+  }
 
   GLint viewport[4];
   context->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
 
   static GLuint texture;
   if (!initialized) {
     // Bind the number of textures we need, in this case one.
     context->fGenTextures(1, &texture);
@@ -578,23 +591,44 @@ LayerManagerOGL::FPSState::DrawFPS(GLCon
     {  -1.0f + 22.f / viewport[2], 1.0f - 42.f / viewport[3] },
     {  -1.0f + 22.f / viewport[2], 1.0f },
     {  -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] },
     {  -1.0f + 44.f / viewport[2], 1.0f },
 
     { -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] },
     { -1.0f + 44.f / viewport[2], 1.0f },
     { -1.0f + 66.f / viewport[2], 1.0f - 42.f / viewport[3] },
-    { -1.0f + 66.f / viewport[2], 1.0f }
+    { -1.0f + 66.f / viewport[2], 1.0f },
+  };
+    
+  const Vertex2D vertices2[] = {
+    { -1.0f + 80.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 80.f / viewport[2], 1.0f },
+    { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 102.f / viewport[2], 1.0f },
+    
+    { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 102.f / viewport[2], 1.0f },
+    { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 124.f / viewport[2], 1.0f },
+    
+    { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 124.f / viewport[2], 1.0f },
+    { -1.0f + 146.f / viewport[2], 1.0f - 42.f / viewport[3] },
+    { -1.0f + 146.f / viewport[2], 1.0f },
   };
 
   int v1   = fps % 10;
   int v10  = (fps % 100) / 10;
   int v100 = (fps % 1000) / 100;
 
+  int content1 = contentFps % 10;
+  int content10  = (contentFps % 100) / 10;
+  int content100 = (contentFps % 1000) / 100;
+
   // Feel free to comment these texture coordinates out and use one
   // of the ones below instead, or play around with your own values.
   const GLfloat texCoords[] = {
     (v100 * 4.f) / 64, 7.f / 8,
     (v100 * 4.f) / 64, 0.0f,
     (v100 * 4.f + 4) / 64, 7.f / 8,
     (v100 * 4.f + 4) / 64, 0.0f,
 
@@ -603,16 +637,33 @@ LayerManagerOGL::FPSState::DrawFPS(GLCon
     (v10 * 4.f + 4) / 64, 7.f / 8,
     (v10 * 4.f + 4) / 64, 0.0f,
 
     (v1 * 4.f) / 64, 7.f / 8,
     (v1 * 4.f) / 64, 0.0f,
     (v1 * 4.f + 4) / 64, 7.f / 8,
     (v1 * 4.f + 4) / 64, 0.0f,
   };
+    
+  const GLfloat texCoords2[] = {
+    (content100 * 4.f) / 64, 7.f / 8,
+    (content100 * 4.f) / 64, 0.0f,
+    (content100 * 4.f + 4) / 64, 7.f / 8,
+    (content100 * 4.f + 4) / 64, 0.0f,
+
+    (content10 * 4.f) / 64, 7.f / 8,
+    (content10 * 4.f) / 64, 0.0f,
+    (content10 * 4.f + 4) / 64, 7.f / 8,
+    (content10 * 4.f + 4) / 64, 0.0f,
+
+    (content1 * 4.f) / 64, 7.f / 8,
+    (content1 * 4.f) / 64, 0.0f,
+    (content1 * 4.f + 4) / 64, 7.f / 8,
+    (content1 * 4.f + 4) / 64, 0.0f,
+  };
 
   // Turn necessary features on
   context->fEnable(LOCAL_GL_BLEND);
   context->fBlendFunc(LOCAL_GL_ONE, LOCAL_GL_SRC_COLOR);
 
   context->fActiveTexture(LOCAL_GL_TEXTURE0);
   context->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
 
@@ -640,16 +691,28 @@ LayerManagerOGL::FPSState::DrawFPS(GLCon
                                 0, vertices);
 
   context->fVertexAttribPointer(tcattr,
                                 2, LOCAL_GL_FLOAT,
                                 LOCAL_GL_FALSE,
                                 0, texCoords);
 
   context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
+  
+  context->fVertexAttribPointer(vcattr,
+                                2, LOCAL_GL_FLOAT,
+                                LOCAL_GL_FALSE,
+                                0, vertices2);
+
+  context->fVertexAttribPointer(tcattr,
+                                2, LOCAL_GL_FLOAT,
+                                LOCAL_GL_FALSE,
+                                0, texCoords2);
+
+  context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
 }
 
 // |aTexCoordRect| is the rectangle from the texture that we want to
 // draw using the given program.  The program already has a necessary
 // offset and scale, so the geometry that needs to be drawn is a unit
 // square from 0,0 to 1,1.
 //
 // |aTexSize| is the actual size of the texture, as it can be larger
@@ -718,16 +781,22 @@ LayerManagerOGL::BindAndDrawQuadWithText
 
       mGLContext->fDisableVertexAttribArray(vertAttribIndex);
     }
     mGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
   }
 }
 
 void
+LayerManagerOGL::NotifyShadowTreeTransaction()
+{
+  mFPS.NotifyShadowTreeTransaction();
+}
+
+void
 LayerManagerOGL::Render()
 {
   SAMPLE_LABEL("LayerManagerOGL", "Render");
   if (mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return;
   }
 
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -98,16 +98,17 @@ public:
 
   void BeginTransaction();
 
   void BeginTransactionWithTarget(gfxContext* aTarget);
 
   void EndConstruction();
 
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
+  virtual void NotifyShadowTreeTransaction();
   virtual void EndTransaction(DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT);
 
   virtual void SetRoot(Layer* aLayer) { mRoot = aLayer; }
 
   virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize)
   {
@@ -441,25 +442,32 @@ private:
   struct FPSState
   {
       GLuint texture;
       int fps;
       bool initialized;
       int fcount;
       TimeStamp last;
 
+      int contentFps;
+      int contentFCount;
+      TimeStamp contentLast;
+
       FPSState()
         : texture(0)
         , fps(0)
         , initialized(false)
         , fcount(0)
+        , contentFps(0)
+        , contentFCount(0)
       {
-        last = TimeStamp::Now();
+        contentLast = last = TimeStamp::Now();
       }
       void DrawFPS(GLContext*, ShaderProgramOGL*);
+      void NotifyShadowTreeTransaction();
   } mFPS;
 
   static bool sDrawFPS;
 };
 
 /**
  * General information and tree management for OGL layers.
  */