Bug 590294, part 4: IGNORE_VIEWPORT_SCROLLING currently implies interpreting the visible region as being relative to document space. Displayport rendering wants everything IGNORE_VIEWPORT_SCROLLING implies, except it wants the visible region to be relative to the viewport. So, split the coordinate-space interpretation into a new flag DOCUMENT_RELATIVE, which interprets the visible region as document-relative. r=tn sr=roc
authorChris Jones <jones.chris.g@gmail.com>
Fri, 03 Sep 2010 15:10:46 -0500
changeset 54079 99279c1c33cc443a880f190a464fb59c75f186cc
parent 54078 99204e5b40f24eb9e1651ed8797d6e2aca28d92d
child 54080 a5f171570672749482392ef98f4c7f03071217cd
push idunknown
push userunknown
push dateunknown
reviewerstn, roc
bugs590294
milestone2.0b6pre
Bug 590294, part 4: IGNORE_VIEWPORT_SCROLLING currently implies interpreting the visible region as being relative to document space. Displayport rendering wants everything IGNORE_VIEWPORT_SCROLLING implies, except it wants the visible region to be relative to the viewport. So, split the coordinate-space interpretation into a new flag DOCUMENT_RELATIVE, which interprets the visible region as document-relative. r=tn sr=roc
content/canvas/src/nsCanvasRenderingContext2D.cpp
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3725,22 +3725,24 @@ nsCanvasRenderingContext2D::DrawWindow(n
 
     nsIPresShell* presShell = presContext->PresShell();
     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
     nsRect r(nsPresContext::CSSPixelsToAppUnits(aX),
              nsPresContext::CSSPixelsToAppUnits(aY),
              nsPresContext::CSSPixelsToAppUnits(aW),
              nsPresContext::CSSPixelsToAppUnits(aH));
-    PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+    PRUint32 renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
+                               nsIPresShell::RENDER_DOCUMENT_RELATIVE);
     if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
         renderDocFlags |= nsIPresShell::RENDER_CARET;
     }
     if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
-        renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+        renderDocFlags &= ~(nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
+                            nsIPresShell::RENDER_DOCUMENT_RELATIVE);
     }
     if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_USE_WIDGET_LAYERS) {
         renderDocFlags |= nsIPresShell::RENDER_USE_WIDGET_LAYERS;
     }
     if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_ASYNC_DECODE_IMAGES) {
         renderDocFlags |= nsIPresShell::RENDER_ASYNC_DECODE_IMAGES;
     }
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -836,27 +836,30 @@ public:
    * (if the layer manager must read back data from the GPU) or low-quality
    * (if the layer manager reads back pixel data and scales it
    * instead of rendering using the appropriate scaling). It may also
    * slow everything down if the area rendered does not correspond to the
    * normal visible area of the window.
    *   set RENDER_ASYNC_DECODE_IMAGES to avoid having images synchronously
    * decoded during rendering.
    * (by default images decode synchronously with RenderDocument)
+   *   set RENDER_DOCUMENT_RELATIVE to interpret |aRect| relative to the
+   * document instead of the CSS viewport
    * @param aBackgroundColor a background color to render onto
    * @param aRenderedContext the gfxContext to render to. We render so that
    * one CSS pixel in the source document is rendered to one unit in the current
    * transform.
    */
   enum {
     RENDER_IS_UNTRUSTED = 0x01,
     RENDER_IGNORE_VIEWPORT_SCROLLING = 0x02,
     RENDER_CARET = 0x04,
     RENDER_USE_WIDGET_LAYERS = 0x08,
-    RENDER_ASYNC_DECODE_IMAGES = 0x10
+    RENDER_ASYNC_DECODE_IMAGES = 0x10,
+    RENDER_DOCUMENT_RELATIVE = 0x20
   };
   virtual NS_HIDDEN_(nsresult) RenderDocument(const nsRect& aRect, PRUint32 aFlags,
                                               nscolor aBackgroundColor,
                                               gfxContext* aRenderedContext) = 0;
 
   /**
    * Renders a node aNode to a surface and returns it. The aRegion may be used
    * to clip the rendering. This region is measured in CSS pixels from the
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1262,21 +1262,23 @@ nsLayoutUtils::PaintFrame(nsIRenderingCo
   }
   nsRect canvasArea(nsPoint(0, 0), aFrame->GetSize());
   if (aFlags & PAINT_IGNORE_VIEWPORT_SCROLLING) {
     NS_ASSERTION(!aFrame->GetParent(), "must have root frame");
     nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
     if (rootScrollFrame) {
       nsIScrollableFrame* rootScrollableFrame =
         presShell->GetRootScrollFrameAsScrollable();
-      // Make visibleRegion and aRenderingContext relative to the
-      // scrolled frame instead of the root frame.
-      nsPoint pos = rootScrollableFrame->GetScrollPosition();
-      visibleRegion.MoveBy(-pos);
-      aRenderingContext->Translate(pos.x, pos.y);
+      if (aFlags & PAINT_DOCUMENT_RELATIVE) {
+        // Make visibleRegion and aRenderingContext relative to the
+        // scrolled frame instead of the root frame.
+        nsPoint pos = rootScrollableFrame->GetScrollPosition();
+        visibleRegion.MoveBy(-pos);
+        aRenderingContext->Translate(pos.x, pos.y);
+      }
       builder.SetIgnoreScrollFrame(rootScrollFrame);
 
       nsCanvasFrame* canvasFrame =
         do_QueryFrame(rootScrollableFrame->GetScrolledFrame());
       if (canvasFrame) {
         // Use UnionRect here to ensure that areas where the scrollbars
         // were are still filled with the background color.
         canvasArea.UnionRect(canvasArea,
@@ -1397,17 +1399,17 @@ nsLayoutUtils::PaintFrame(nsIRenderingCo
     nsIntRegion visibleWindowRegion(visibleRegion.ToOutsidePixels(pixelRatio));
     nsIntRegion dirtyWindowRegion(aDirtyRegion.ToOutsidePixels(pixelRatio));
 
     if (willFlushLayers) {
       // We're going to display something different from what we'd normally
       // paint in a window, so make sure we flush out any retained layer
       // trees before *and after* we draw
       flags |= nsDisplayList::PAINT_FLUSH_LAYERS;
-    } else if (widget) {
+    } else if (widget && !(aFlags & PAINT_DOCUMENT_RELATIVE)) {
       // XXX we should simplify this API now that dirtyWindowRegion always
       // covers the entire window
       widget->UpdatePossiblyTransparentRegion(dirtyWindowRegion, visibleWindowRegion);
     }
   }
 
   list.PaintRoot(&builder, aRenderingContext, flags);
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -512,19 +512,20 @@ public:
    */
   static nsresult GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
 
   enum {
     PAINT_IN_TRANSFORM = 0x01,
     PAINT_SYNC_DECODE_IMAGES = 0x02,
     PAINT_WIDGET_LAYERS = 0x04,
     PAINT_IGNORE_SUPPRESSION = 0x08,
-    PAINT_IGNORE_VIEWPORT_SCROLLING = 0x10,
+    PAINT_DOCUMENT_RELATIVE = 0x10,
     PAINT_HIDE_CARET = 0x20,
-    PAINT_ALL_CONTINUATIONS = 0x40
+    PAINT_ALL_CONTINUATIONS = 0x40,
+    PAINT_IGNORE_VIEWPORT_SCROLLING = 0x80
   };
 
   /**
    * Given aFrame, the root frame of a stacking context, paint it and its
    * descendants to aRenderingContext.
    * @param aRenderingContext a rendering context translated so that (0,0)
    * is the origin of aFrame; for best results, (0,0) should transform
    * to pixel-aligned coordinates. This can be null, in which case
@@ -538,16 +539,19 @@ public:
    * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
    * this is inside a transform or SVG foreignObject. If
    * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
    * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
    * and we will use the frame's widget's layer manager to paint
    * even if aRenderingContext is non-null. This is useful if you want
    * to force rendering to use the widget's layer manager for testing
    * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
+   * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
+   * as being relative to the document.  (Normally it's relative to the CSS
+   * viewport.)
    *
    * So there are three possible behaviours:
    * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
    * by calling BeginTransaction on the widget's layer manager
    * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
    * paint by calling BeginTransactionWithTarget on the widget's layer
    * maanger
    * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5289,16 +5289,19 @@ PresShell::RenderDocument(const nsRect& 
     }
   }
   if (!(aFlags & RENDER_CARET)) {
     flags |= nsLayoutUtils::PAINT_HIDE_CARET;
   }
   if (aFlags & RENDER_IGNORE_VIEWPORT_SCROLLING) {
     flags |= nsLayoutUtils::PAINT_IGNORE_VIEWPORT_SCROLLING;
   }
+  if (aFlags & RENDER_DOCUMENT_RELATIVE) {
+    flags |= nsLayoutUtils::PAINT_DOCUMENT_RELATIVE;
+  }
   nsLayoutUtils::PaintFrame(rc, rootFrame, nsRegion(aRect),
                             aBackgroundColor, flags);
 
   // if we had to use a group, paint it to the destination now
   if (needsGroup) {
     aThebesContext->Restore();
     aThebesContext->PopGroupToSource();
     aThebesContext->Paint();