Bug 43921 - Window size changes + resources on absolute sized content leads to pixelation
Summary: Window size changes + resources on absolute sized content leads to pixelation
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Nikolas Zimmermann
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-12 08:38 PDT by Nikolas Zimmermann
Modified: 2010-08-13 03:06 PDT (History)
2 users (show)

See Also:


Attachments
Patch (114.29 KB, patch)
2010-08-12 08:50 PDT, Nikolas Zimmermann
no flags Details | Formatted Diff | Diff
Patch v2 (142.05 KB, patch)
2010-08-13 02:05 PDT, Nikolas Zimmermann
krit: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nikolas Zimmermann 2010-08-12 08:38:38 PDT
Resizing a SVG document containing an absolute sized object where a resources is applied leads to pixelation (for masks, atm.)
The resource is not being invalidated. When using a target object with relative lengths everything works fine.
Comment 1 Nikolas Zimmermann 2010-08-12 08:50:20 PDT
Created attachment 64229 [details]
Patch
Comment 2 Dirk Schulze 2010-08-12 11:52:06 PDT
Comment on attachment 64229 [details]
Patch

>  void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
>  {
>      bool layoutSizeChanged = svgRootTreeObject(start)->isLayoutSizeChanged();
> +    HashSet<RenderObject*> notlayoutedObjects;
>  
>      for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
>          bool needsLayout = selfNeedsLayout;
> @@ -252,11 +263,25 @@ void SVGRenderSupport::layoutChildren(Re
>          if (needsLayout) {
>              child->setNeedsLayout(true, false);
>              child->layout();
> -        } else
> -            child->layoutIfNeeded();
> +        } else {
> +            if (child->needsLayout())
> +                child->layout();
> +            else if (layoutSizeChanged)
> +                notlayoutedObjects.add(child);
> +        }
>  
>          ASSERT(!child->needsLayout());
>      }
> +
> +    if (!layoutSizeChanged) {
> +        ASSERT(notlayoutedObjects.isEmpty());
> +        return;
> +    }
> +
> +    // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
> +    HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
> +    for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
> +        invalidateResourcesOfChildren(*it);
>  }
>  

I'm not sure about the last loop here. You store the objects, because they don't need a relayout. But when you call invalidateResourcesOfChildren, the resources want the objects to relayout at least the boundaries. Seems unneccessary to me, because we already know, that they don't need a relayout.
Comment 3 Nikolas Zimmermann 2010-08-12 13:18:13 PDT
(In reply to comment #2)
> > +    // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
> > +    HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
> > +    for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
> > +        invalidateResourcesOfChildren(*it);
> >  }
> >  
> 
> I'm not sure about the last loop here. You store the objects, because they don't need a relayout. But when you call invalidateResourcesOfChildren, the resources want the objects to relayout at least the boundaries. Seems unneccessary to me, because we already know, that they don't need a relayout.

You mixed up something. They call setNeedsBoundariesUpdate(), but not do any relayouting.
It just marks for a boundaries update, next time it relayouts. But this relayout doesn't happen, so there's no problem.
Comment 4 Dirk Schulze 2010-08-12 22:40:19 PDT
(In reply to comment #3)
> (In reply to comment #2)
> > > +    // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
> > > +    HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
> > > +    for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
> > > +        invalidateResourcesOfChildren(*it);
> > >  }
> > >  
> > 
> > I'm not sure about the last loop here. You store the objects, because they don't need a relayout. But when you call invalidateResourcesOfChildren, the resources want the objects to relayout at least the boundaries. Seems unneccessary to me, because we already know, that they don't need a relayout.
> 
> You mixed up something. They call setNeedsBoundariesUpdate(), but not do any relayouting.
> It just marks for a boundaries update, next time it relayouts. But this relayout doesn't happen, so there's no problem.

Yes, I know it's just a flag. This makes still no sense. Why should we mark something for realyouting, but never relayout it? And even if we call layout sometime later, we have to update the boundaries, independent why we call layout. An expensive operation for RenderPath.
Comment 5 Nikolas Zimmermann 2010-08-13 02:05:57 PDT
Created attachment 64313 [details]
Patch v2

New approach after discussing with Dirk.
Comment 6 Dirk Schulze 2010-08-13 02:56:22 PDT
Comment on attachment 64313 [details]
Patch v2

LGTM. r=me
Comment 7 Nikolas Zimmermann 2010-08-13 03:06:17 PDT
Landed in r65310.