Bug 23090 - Redraw issue with width and opacity change
Summary: Redraw issue with width and opacity change
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Macintosh OS X 10.5
: P2 Normal
Assignee: Simon Fraser (smfr)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-01-03 10:49 PST by Simon Fraser (smfr)
Modified: 2009-01-04 10:40 PST (History)
2 users (show)

See Also:


Attachments
Testcase (732 bytes, text/html)
2009-01-03 10:50 PST, Simon Fraser (smfr)
no flags Details
Patch, testcase, changelog (6.07 KB, patch)
2009-01-03 12:20 PST, Simon Fraser (smfr)
no flags Details | Formatted Diff | Diff
Improved patch (6.07 KB, patch)
2009-01-03 19:11 PST, Simon Fraser (smfr)
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Fraser (smfr) 2009-01-03 10:49:24 PST
The attached testcase shows that a block with width and opacity changing at the same time shows a redraw issue which leaves an area where the element used to be un-repainted.
Comment 1 Simon Fraser (smfr) 2009-01-03 10:50:44 PST
Created attachment 26392 [details]
Testcase
Comment 2 Simon Fraser (smfr) 2009-01-03 10:51:48 PST
Seems to be an issue only when the element toggles between having a layer (opacity < 1) and no layer (opacity == 1).
Comment 3 Simon Fraser (smfr) 2009-01-03 12:20:06 PST
Created attachment 26393 [details]
Patch, testcase, changelog
Comment 4 Darin Adler 2009-01-03 18:39:53 PST
Comment on attachment 26393 [details]
Patch, testcase, changelog

> +            } else if (m_style->hasTransform() != newStyle->hasTransform() ||
> +                       m_style->hasOpacity() != newStyle->hasOpacity()) {
> +                // If we don't have a layer yet, but we are going to get one because of a transform or opacity change, then
>                  // we need to repaint the old position of the object

The comment is right, but the code is wrong. This will decide to repaint something that already has a layer if its opacity is going to change. Can we do a better check that gets this right? We want to repaint if "gets own layer" is going to change, so that's what we should be checking.
Comment 5 Simon Fraser (smfr) 2009-01-03 19:03:11 PST
(In reply to comment #4)
> (From update of attachment 26393 [details] [review])
> > +            } else if (m_style->hasTransform() != newStyle->hasTransform() ||
> > +                       m_style->hasOpacity() != newStyle->hasOpacity()) {
> > +                // If we don't have a layer yet, but we are going to get one because of a transform or opacity change, then
> >                  // we need to repaint the old position of the object
> 
> The comment is right, but the code is wrong. This will decide to repaint
> something that already has a layer if its opacity is going to change. Can we do
> a better check that gets this right? We want to repaint if "gets own layer" is
> going to change, so that's what we should be checking.

This is in a !hasLayer() clause, so it will actually do the right thing.
However, I will tidy up the logic.
Comment 6 Simon Fraser (smfr) 2009-01-03 19:11:16 PST
Created attachment 26400 [details]
Improved patch
Comment 7 Darin Adler 2009-01-03 20:44:11 PST
Comment on attachment 26400 [details]
Improved patch

> +    bool hasOpacity() const { return rareNonInheritedData->opacity < 1; }

I'm not a huge fan of this name for the function. What this function means is that you have non-standard opacity, non-opaque opacity. It says nothing about whether you have any CSS opacity rules, for example. You could have one saying opacity: 1.

But the real problem is it doesn't make sense to say that a fully opaque object with an opacity of "1" does not have opacity.

I'd suggest just saying opacity() < 1 at the call site, or coming up with a better name for this helper function.

r=me with or without a change to that
Comment 8 Simon Fraser (smfr) 2009-01-04 10:40:06 PST
I changed it to test opacity() < 1 at the call site.

Committing to http://svn.webkit.org/repository/webkit/trunk ...
	M	LayoutTests/ChangeLog
	A	LayoutTests/fast/repaint/create-layer-repaint.html
	A	LayoutTests/platform/mac/fast/repaint/create-layer-repaint-expected.checksum
	A	LayoutTests/platform/mac/fast/repaint/create-layer-repaint-expected.png
	A	LayoutTests/platform/mac/fast/repaint/create-layer-repaint-expected.txt
	M	WebCore/ChangeLog
	M	WebCore/rendering/RenderObject.cpp
Committed r39588