Bug 339548. Part 4: Move responsibility for removing child widget areas from the paint region from nsViewManager to platform widget code. r=karl,josh

This commit is contained in:
Robert O'Callahan 2009-07-22 12:44:55 +12:00
parent 3c281129eb
commit 81bc0a54db
4 changed files with 41 additions and 67 deletions

View File

@ -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)

View File

@ -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);

View File

@ -2817,8 +2817,9 @@ static const PRInt32 sShadowInvalidationInterval = 100;
/* clip and build a region */
nsCOMPtr<nsIRegion> rgn(do_CreateInstance(kRegionCID));
if (rgn)
rgn->Init();
if (!rgn)
return;
rgn->Init();
// bounding box of the dirty area
nsIntRect fullRect;
@ -2832,8 +2833,7 @@ 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);
rgn->Union((PRInt32)r.origin.x, (PRInt32)r.origin.y, (PRInt32)r.size.width, (PRInt32)r.size.height);
// to the context for clipping
targetContext->Rectangle(gfxRect(r.origin.x, r.origin.y, r.size.width, r.size.height));
@ -2843,7 +2843,17 @@ static const PRInt32 sShadowInvalidationInterval = 100;
targetContext->Rectangle(gfxRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height));
}
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;

View File

@ -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;