|
|
Chromium Code Reviews
DescriptionUse size of SkRect as the key for blur mask cache
BUG=429409
Committed: https://skia.googlesource.com/skia/+/69469b570ceb8a5ab7f64778d1b128cd5c472e73
Patch Set 1 #Patch Set 2 : fix GM blur2rects #Patch Set 3 : fix fractional rects #
Messages
Total messages: 19 (2 generated)
qiankun.miao@intel.com changed reviewers: + reed@google.com
PTAL.
What bug is this fixing? Why is it correct to ignore the phase of the outer rect?
On 2014/11/07 14:49:32, reed1 wrote:
> What bug is this fixing? Why is it correct to ignore the phase of the outer
> rect?
1. For a box-shadow effect, mask will be computed several times with differenct
rects but same size. This CL avoids such calculation.
Try simple case as follow, log rects passed to find_cached_rects():
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
div
{
width:1000px;
height:800px;
box-shadow:0 -170px 160px -100px rgba(0,0,0,0.6) inset, 0 170px 160px -100px
inset;
}
</style>
</head>
<body>
<div>
</div>
</body>
</html>
2. Result fImage of SkMask only depends on size of rects and relative position
of outer and inner rect.
#include "SkBlurMaskFilter.h"
static void draw_blur(SkCanvas* canvas) {
SkPaint paint;
paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
2.3f))->unref();
SkRect outer = SkRect::MakeXYWH(10.1f, 10.1f, 100.3f, 100.3f);
SkRect inner = SkRect::MakeXYWH(20, 20, 80, 80);
SkPath path;
path.addRect(outer, SkPath::kCW_Direction);
path.addRect(inner, SkPath::kCCW_Direction);
// path.offset(0.3f, 0.3f);
canvas->drawPath(path, paint);
}
This will generate two different masks depending on if we execute the
path.offset line. I think it is incorrect to ignore the phase of the outer rect.
#include "SkBlurMaskFilter.h"
static void draw_blur(SkCanvas* canvas) {
SkPaint paint;
paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
2.3f))->unref();
SkRect outer = SkRect::MakeXYWH(10.1f, 10.1f, 100.3f, 100.3f);
SkRect inner = SkRect::MakeXYWH(20, 20, 80, 80);
SkPath path;
path.addRect(outer, SkPath::kCW_Direction);
path.addRect(inner, SkPath::kCCW_Direction);
// path.offset(0.3f, 0.3f);
// canvas.translate(-0.3f, -0.3f);
canvas->drawPath(path, paint);
}
Add canvas.translate after path.offset will generate the same masks.
draw_rects_into_mask() does similar thing. So this CL should be correct to
ignore the phase of the outer rect.
On 2014/11/13 07:53:37, qiankun wrote:
> #include "SkBlurMaskFilter.h"
> static void draw_blur(SkCanvas* canvas) {
> SkPaint paint;
>
> paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
> 2.3f))->unref();
>
> SkRect outer = SkRect::MakeXYWH(10.1f, 10.1f, 100.3f, 100.3f);
> SkRect inner = SkRect::MakeXYWH(20, 20, 80, 80);
> SkPath path;
> path.addRect(outer, SkPath::kCW_Direction);
> path.addRect(inner, SkPath::kCCW_Direction);
>
> // path.offset(0.3f, 0.3f);
> // canvas.translate(-0.3f, -0.3f);
> canvas->drawPath(path, paint);
> }
>
> Add canvas.translate after path.offset will generate the same masks.
> draw_rects_into_mask() does similar thing. So this CL should be correct to
> ignore the phase of the outer rect.
Not sure what you mean. In the first code snippet, this CL will treat both paths
draws (w/ and w/o the offset) as the same cache key, which will have it return
the same mask for both, even though they should be different, hence I think this
CL is wrong.
On 2014/11/13 18:43:53, reed1 wrote:
> On 2014/11/13 07:53:37, qiankun wrote:
> > #include "SkBlurMaskFilter.h"
> > static void draw_blur(SkCanvas* canvas) {
> > SkPaint paint;
> >
> > paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
> > 2.3f))->unref();
> >
> > SkRect outer = SkRect::MakeXYWH(10.1f, 10.1f, 100.3f, 100.3f);
> > SkRect inner = SkRect::MakeXYWH(20, 20, 80, 80);
> > SkPath path;
> > path.addRect(outer, SkPath::kCW_Direction);
> > path.addRect(inner, SkPath::kCCW_Direction);
> >
> > // path.offset(0.3f, 0.3f);
> > // canvas.translate(-0.3f, -0.3f);
> > canvas->drawPath(path, paint);
> > }
> >
> > Add canvas.translate after path.offset will generate the same masks.
> > draw_rects_into_mask() does similar thing. So this CL should be correct to
> > ignore the phase of the outer rect.
>
> Not sure what you mean. In the first code snippet, this CL will treat both
paths
> draws (w/ and w/o the offset) as the same cache key, which will have it return
> the same mask for both, even though they should be different, hence I think
this
> CL is wrong.
In Skia's code, mask is generated in SkBlurMaskFilter::draw_rects_into_mask().
That function creates same mask pixels for rects with same size and same
relative position between outer and inner rects though phase of the outer rect
is different. That's because draw_rects_into_mask() call
canvas.translate(-SkIntToScalar(mask->fBounds.left()),
-SkIntToScalar(mask->fBounds.top())); to ignore phase of the outer rect. In your
code snippet, if you call canvas.translate() after path.offset() (same behavior
as draw_rects_into_mask() do), both paths (w/ and w/o the offset) will have the
same mask pixels.
https://codereview.chromium.org/728863002/ This new GM "blur2rects" show the current behavior, where the two drawing versions are slightly different, which is correct as the path is shifted slightly to the right (relative to the pixel boundaries). With the current CL applied, this subtle difference is lost, which is incorrect I believe.
The two drawing versions are slightly different due to precision. Fixed this issue using smallR as the key.
I have updated the gm slightly, and now it may more clearly show that this CL misses the subtle difference between the two draws. The blur code does (correctly) notice the slight phase-shift in the outer rect, and so we can't throw that information away when we try to cache it.
On 2014/11/14 20:20:07, reed1 wrote: > I have updated the gm slightly, and now it may more clearly show that this CL > misses the subtle difference between the two draws. > > The blur code does (correctly) notice the slight phase-shift in the outer rect, > and so we can't throw that information away when we try to cache it. After this GM update, both patch set 1 and set 2 can pass GM. In my opinion, patch set 2 should be correct.
Updated this CL to take rects with fractional boundary into account.
hi reed, could you take a look at this update?
Ping. Any comments about this CL?
The CQ bit was checked by reed@google.com
lgtm
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/708073002/40001
Message was sent while issue was closed.
Committed patchset #3 (id:40001) as https://skia.googlesource.com/skia/+/69469b570ceb8a5ab7f64778d1b128cd5c472e73 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
