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 103474 dbc34849f109bf134213e085cb02363f952a519d
parent 103473 b8893f7f80c5c76f739b9396a36822852329bc59
child 103475 88755b34790a1f42fa05163210b05f080376770d
push id13994
push usercjones@mozilla.com
push dateSun, 26 Aug 2012 04:17:00 +0000
treeherdermozilla-inbound@dbc34849f109 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs779940
milestone17.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 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.
  */