Add a DrawWindowUnderlay() to match DrawWindowOverlay()
authorPatrick Walton <pwalton@mozilla.com>
Thu, 09 Feb 2012 19:47:50 -0800
changeset 92424 737218b404d98ee30d4c43ef7f308449134e20ed
parent 92421 23107130ea2279672b2fc923e62700fa9b141ae7
child 92425 79653c6e92b5866d12ef625986d06fae99ed710b
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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
Add a DrawWindowUnderlay() to match DrawWindowOverlay()
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/nsIWidget.h
widget/xpwidgets/nsBaseWidget.h
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -37,16 +37,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "CompositorParent.h"
 #include "ShadowLayersParent.h"
 #include "LayerManagerOGL.h"
 #include "nsIWidget.h"
+#include "nsGkAtoms.h"
 
 #if defined(MOZ_WIDGET_ANDROID)
 #include "AndroidBridge.h"
 #include <android/log.h>
 #endif
 
 namespace mozilla {
 namespace layers {
@@ -187,31 +188,37 @@ CompositorParent::Composite()
   worldTransform.Scale(mXScale, mYScale, 1.0f);
 #ifdef MOZ_WIDGET_ANDROID
   Layer* layer = GetPrimaryScrollableLayer();
 #else
   Layer* layer = mLayerManager->GetRoot();
 #endif
   layer->AsShadowLayer()->SetShadowTransform(worldTransform);
 
+  // Hang the transform of the root layer off the layer manager.
+  gfx3DMatrix transform = layer->GetTransform();
+  transform *= worldTransform;
+  TransformLayerUserData* transformUserData = new TransformLayerUserData(transform);
+  mLayerManager->SetUserData(nsGkAtoms::transform, transformUserData);
+
   mLayerManager->EndEmptyTransaction();
   mLastCompose = mozilla::TimeStamp::Now();
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 // Do a breadth-first search to find the first layer in the tree with a
 // displayport set.
 Layer*
 CompositorParent::GetPrimaryScrollableLayer()
 {
   Layer* root = mLayerManager->GetRoot();
 
   nsTArray<Layer*> queue;
   queue.AppendElement(root);
-  for (int i = 0; i < queue.Length(); i++) {
+  for (unsigned i = 0; i < queue.Length(); i++) {
     ContainerLayer* containerLayer = queue[i]->AsContainerLayer();
     if (!containerLayer) {
       continue;
     }
 
     const FrameMetrics& frameMetrics = containerLayer->GetFrameMetrics();
     if (!frameMetrics.mDisplayPort.IsEmpty()) {
       return containerLayer;
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -135,12 +135,20 @@ private:
   bool mPaused;
   float mXScale;
   float mYScale;
   nsIntPoint mScrollOffset;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
 
+class TransformLayerUserData : public LayerUserData {
+public:
+    gfx3DMatrix matrix;
+
+    TransformLayerUserData(gfx3DMatrix& aMatrix) : matrix(aMatrix) {}
+    virtual ~TransformLayerUserData() {}
+};
+
 } // layers
 } // mozilla
 
 #endif // mozilla_layers_CompositorParent_h
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -780,34 +780,36 @@ LayerManagerOGL::Render()
     mGLContext->fScissor(0, 0, width, height);
   }
 
   mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
 
   mGLContext->fClearColor(1.0, 1.0, 1.0, 0.0);
   mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
 
+  // Allow widget to render a custom background.
+  mWidget->DrawWindowUnderlay(this, rect);
+
   // Render our layers.
   RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
                            nsIntPoint(0, 0));
 
+  // Allow widget to render a custom foreground too.
   mWidget->DrawWindowOverlay(this, rect);
 
   if (mTarget) {
     CopyToTarget();
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   if (sDrawFPS) {
     mFPS.DrawFPS(mGLContext, GetCopy2DProgram());
   }
 
-  PerformPostRenderHook();
-
   if (mGLContext->IsDoubleBuffered()) {
     mGLContext->SwapBuffers();
     LayerManager::PostPresent();
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
@@ -890,32 +892,16 @@ LayerManagerOGL::Render()
   mGLContext->fDisableVertexAttribArray(vcattr);
   mGLContext->fDisableVertexAttribArray(tcattr);
 
   mGLContext->fFlush();
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 void
-LayerManagerOGL::PerformPreRenderHook()
-{
-#ifdef MOZ_WIDGET_ANDROID
-  // TODO: AndroidBridge::PerformPreRenderHook();
-#endif
-}
-
-void
-LayerManagerOGL::PerformPostRenderHook()
-{
-#ifdef MOZ_WIDGET_ANDROID
-  // TODO: AndroidBridge::PerformPostRenderHook();
-#endif
-}
-
-void
 LayerManagerOGL::SetWorldTransform(const gfxMatrix& aMatrix)
 {
   NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
                "SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
   NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
                "SetWorldTransform only accepts matrices with integer scale");
 
   mWorldMatrix = aMatrix;
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -382,19 +382,16 @@ public:
     DontApplyWorldTransform
   };
 
   /**
    * Setup the viewport and projection matrix for rendering
    * to a window of the given dimensions.
    */
   void SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy);
- 
-  void PerformPreRenderHook();
-  void PerformPostRenderHook();
 
   /**
    * Setup World transform matrix.
    * Transform will be ignored if it is not PreservesAxisAlignedRectangles
    * or has non integer scale
    */
   void SetWorldTransform(const gfxMatrix& aMatrix);
   gfxMatrix& GetWorldTransform(void);
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -2380,8 +2380,20 @@ nsWindow::OnIMESelectionChange(void)
 }
 
 nsIMEUpdatePreference
 nsWindow::GetIMEUpdatePreference()
 {
     return nsIMEUpdatePreference(true, true);
 }
 
+#ifdef MOZ_JAVA_COMPOSITOR
+void
+nsWindow::DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) {
+    __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### TODO: Render custom background");
+}
+
+void
+nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) {
+    __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### TODO: Render custom foreground");
+}
+#endif
+
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -174,16 +174,19 @@ public:
 
 #ifdef ACCESSIBILITY
     static bool sAccessibilityEnabled;
 #endif
 
 #ifdef MOZ_JAVA_COMPOSITOR
     static void BindToTexture();
     static bool HasDirectTexture();
+
+    virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect);
+    virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect);
 #endif
 
 protected:
     void BringToFront();
     nsWindow *FindTopLevel();
     bool DrawTo(gfxASurface *targetSurface);
     bool DrawTo(gfxASurface *targetSurface, const nsIntRect &aRect);
     bool IsTopLevel();
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1067,16 +1067,24 @@ class nsIWidget : public nsISupports {
      * LAYERS_NONE means "no hint".
      */
     virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager,
                                           LayersBackend aBackendHint,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull) = 0;
 
     /**
+     * Called before the LayerManager draws the layer tree.
+     *
+     * @param aManager The drawing LayerManager.
+     * @param aWidgetRect The current widget rect that is being drawn.
+     */
+    virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) = 0;
+
+    /**
      * Called after the LayerManager draws the layer tree
      *
      * @param aManager The drawing LayerManager.
      * @param aRect Current widget rect that is being drawn.
      */
     virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) = 0;
 
     /**
--- a/widget/xpwidgets/nsBaseWidget.h
+++ b/widget/xpwidgets/nsBaseWidget.h
@@ -127,16 +127,17 @@ public:
   NS_IMETHOD              MakeFullScreen(bool aFullScreen);
   virtual nsDeviceContext* GetDeviceContext();
   virtual LayerManager*   GetLayerManager(PLayersChild* aShadowManager = nsnull,
                                           LayersBackend aBackendHint = LayerManager::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull);
 
   virtual void            CreateCompositor();
+  virtual void            DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) {}
   virtual void            DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) {}
   virtual void            UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {}
   virtual gfxASurface*    GetThebesSurface();
   NS_IMETHOD              SetModal(bool aModal); 
   NS_IMETHOD              SetWindowClass(const nsAString& xulWinType);
   NS_IMETHOD              MoveClient(PRInt32 aX, PRInt32 aY);
   NS_IMETHOD              ResizeClient(PRInt32 aWidth, PRInt32 aHeight, bool aRepaint);
   NS_IMETHOD              ResizeClient(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, bool aRepaint);