Commit 6200540a authored by Robert O'Callahan's avatar Robert O'Callahan
Browse files

Bug 339548. Part 4: Move responsibility for removing child widget areas from...

Bug 339548. Part 4: Move responsibility for removing child widget areas from the paint region from nsViewManager to platform widget code. r=karl,josh
parent 1b3f569e
Loading
Loading
Loading
Loading
+0 −57
Original line number Diff line number Diff line
@@ -497,10 +497,6 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
    ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a,
                            -gfxFloat(viewRect.y) / p2a));

    nsRegion opaqueRegion;
    AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView);
    damageRegion.Sub(damageRegion, opaqueRegion);

    RenderViews(aView, *localcx, damageRegion);

    ctx->Restore();
@@ -524,59 +520,6 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,

}

void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
                                                     nsView* aRootView) {
  NS_PRECONDITION(aRootView, "Must have root view");
  
  // We accumulate the bounds of widgets obscuring aRootView's widget into opaqueRgn.
  // In OptimizeDisplayList, display list elements which lie behind obscuring native
  // widgets are dropped.
  // This shouldn't really be necessary, since the GFX/Widget toolkit should remove these
  // covering widgets from the clip region passed into the paint command. But right now
  // they only give us a paint rect and not a region, so we can't access that information.
  // It's important to identifying areas that are covered by native widgets to avoid
  // painting their views many times as we process invalidates from the root widget all the
  // way down to the nested widgets.
  // 
  // NB: we must NOT add widgets that correspond to floating views!
  // We may be required to paint behind them
  aRgn.SetEmpty();

  nsPoint offsetToWidget;
  nsIWidget* widget = aRootView->GetNearestWidget(&offsetToWidget);
  if (!widget) {
    return;
  }
  
  if (widget->GetTransparencyMode() == eTransparencyTransparent) {
    return;
  }

  for (nsIWidget* childWidget = widget->GetFirstChild();
       childWidget;
       childWidget = childWidget->GetNextSibling()) {
    PRBool widgetVisible;
    childWidget->IsVisible(widgetVisible);
    if (widgetVisible) {
      nsTArray<nsIntRect> clipRects;
      childWidget->GetWindowClipRegion(&clipRects);

      nsView* view = nsView::GetViewFor(childWidget);
      if (view && view->GetVisibility() == nsViewVisibility_kShow
          && !view->GetFloating()) {
        nsIntRect bounds;
        childWidget->GetBounds(bounds);
        for (PRUint32 i = 0; i < clipRects.Length(); ++i) {
          nsIntRect r = clipRects[i] + bounds.TopLeft();
          nsRect rr = r.ToAppUnits(mContext->AppUnitsPerDevPixel()) -
            offsetToWidget;
          aRgn.Or(aRgn, rr);
        }
      }
    }
  }
}

// aRC and aRegion are in view coordinates
void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
                                const nsRegion& aRegion)
+0 −3
Original line number Diff line number Diff line
@@ -223,9 +223,6 @@ private:
  void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
                                          PRUint32 aUpdateFlags, nscoord aY1, nscoord aY2, PRBool aInCutOut);

  void AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
                                        nsView* aRootView);

  // Utilities

  PRBool IsViewInserted(nsView *aView);
+15 −5
Original line number Diff line number Diff line
@@ -2817,7 +2817,8 @@ static const PRInt32 sShadowInvalidationInterval = 100;

  /* clip and build a region */
  nsCOMPtr<nsIRegion> rgn(do_CreateInstance(kRegionCID));
  if (rgn)
  if (!rgn)
    return;
  rgn->Init();

  // bounding box of the dirty area
@@ -2832,7 +2833,6 @@ static const PRInt32 sShadowInvalidationInterval = 100;
      const NSRect& r = rects[i];

      // add to the region
      if (rgn)
      rgn->Union((PRInt32)r.origin.x, (PRInt32)r.origin.y, (PRInt32)r.size.width, (PRInt32)r.size.height);

      // to the context for clipping
@@ -2844,6 +2844,16 @@ static const PRInt32 sShadowInvalidationInterval = 100;
  }
  targetContext->Clip();

  // Subtract child view rectangles from the region
  NSArray* subviews = [self subviews];
  for (int i = 0; i < int([subviews count]); ++i) {
    NSView* view = [subviews objectAtIndex:i];
    if (![view isKindOfClass:[ChildView class]] || [view isHidden])
      continue;
    NSRect frame = [view frame];
    rgn->Subtract(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
  }

  nsPaintEvent paintEvent(PR_TRUE, NS_PAINT, mGeckoChild);
  paintEvent.renderingContext = rc;
  paintEvent.rect = &fullRect;
+26 −2
Original line number Diff line number Diff line
@@ -2152,6 +2152,32 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
        LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height));
    }

    PRBool translucent = eTransparencyTransparent == GetTransparencyMode();
    if (!translucent) {
        GList *children =
            gdk_window_peek_children(mDrawingarea->inner_window);
        while (children) {
            GdkWindow *gdkWin = GDK_WINDOW(children->data);
            nsWindow *kid = get_window_for_gdk_window(gdkWin);
            if (kid) {
                nsAutoTArray<nsIntRect,1> clipRects;
                kid->GetWindowClipRegion(&clipRects);
                nsIntRect bounds;
                kid->GetBounds(bounds);
                for (PRUint32 i = 0; i < clipRects.Length(); ++i) {
                    nsIntRect r = clipRects[i] + bounds.TopLeft();
                    updateRegion->Subtract(r.x, r.y, r.width, r.height);
                }
            }
            children = children->next;
        }
    }

    if (updateRegion->IsEmpty()) {
        g_free(rects);
        return TRUE;
    }

#ifdef MOZ_DFB
    nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
    if (NS_UNLIKELY(!rc)) {
@@ -2181,8 +2207,6 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
        return FALSE;
    }

    PRBool translucent;
    translucent = eTransparencyTransparent == GetTransparencyMode();
    nsIntRect boundsRect;

    GdkPixmap* bufferPixmap = nsnull;