SkLayerDrawLooper serialization/deserialization mismatch. |
||||
Issue description
When serializing SkLayerDrawLooper, it seems like filters like SkBlurMaskFilter don't survive past serialization/deserialization.
Is this an expected result? If so, we'd have to create a PaintDrawLooper or something along those lines. I'm hoping that it's just some small change on the Skia side though.
mtklein@, could you triage/take a look?
This is what I'm doing:
SkLayerDrawLooper::Builder builder;
auto* paint = builder.addLayer(SkLayerDrawLooper::LayerInfo());
paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 3.3f));
auto looper = builder.detach();
sk_sp<SkData> data(SkValidatingSerializeFlattenable(looper.get()));
sk_sp<SkDrawLooper> result(
static_cast<SkDrawLooper*>(SkValidatingDeserializeFlattenable(
data->data(), data->size(), SkDrawLooper::GetFlattenableType())));
/* print looper and result */
The printing gets the initial looper (truncated):
SkLayerDrawLooper (1): 0: paintBits: (None) mode: kDst offset: (0, 0) postTranslate: false
SkPaint:
...
TextSkewX:
0
MaskFilter:
SkBlurMaskFilterImpl: (sigma: 3.3 style: normal flags: (None))
Color:
0xFF000000
...
And the result (truncated):
SkLayerDrawLooper (1): 0: paintBits: (None) mode: kDst offset: (0, 0) postTranslate: false
SkPaint:
...
TextSkewX:
0
Color:
0xFF000000
...
Note that the SkBlurMaskFilterImpl is missing.
,
Jan 16 2018
The test (in the bug) is building a "default" Info, which signals that we should ignore all paint-overrides in the layer, and just use the caller's paint (the one passed to the 'draw' call). There is no problem in the serial/deserial code.
If you want to have the looper specify a maskfilter for a given layer, then you must set that bit on the Info's fPaintBits field.
Here is a modified code snippet that draws the blur:
SkLayerDrawLooper::LayerInfo info;
info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit;
SkLayerDrawLooper::Builder builder;
auto* paint = builder.addLayer(info);
paint->setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 3.3f));
p.setLooper(builder.detach());
canvas->drawCircle(50, 50, 40, p);
sk_sp<SkData> data(p.getLooper()->serialize());
sk_sp<SkDrawLooper> result = SkDrawLooper::Deserialize(data->data(), data->size());
p.setLooper(result);
canvas->drawCircle(150, 50, 40, p);
If you comment out the 2nd line where we assign to fPaintBits, both drawings will not show the blur.
,
Jan 16 2018
... oops, need to declare 'p' to be a paint at the beginning. SkPaint p; ...
,
Jan 16 2018
Hmm, setting the fPaintBits yields the same result for me. If I use the same code as in the original post, but set the MaskFilter bit, then the only difference in outputs is that the paintBits are set, but the blur filter is still missing:
SkLayerDrawLooper (1): 0: paintBits: (MaskFilter) mode: kDst offset: (0, 0) postTranslate: false
SkPaint:
TextSize:
12
TextScaleX:
1
TextSkewX:
0
Color:
0xFF000000
Stroke Width:
0
Stroke Miter:
4
Flags:
(None)
FilterLevel:
None
TextAlign:
Left
CapType:
Butt
JoinType:
Miter
Style:
Fill
TextEncoding:
UTF8
Hinting:
Normal
My reduced case possibly reduced too much, but in Chrome, we do set the bits properly and the looper is missing filters.
I'm using this:
<!doctype HTML>
<style>
div {
width: 100px;
height: 100px;
background-color: lightblue;
box-shadow: 10px 10px 10px cyan;
}
</style>
<div></div>
FWIW, I'm just doing toString on the loopers to see the difference, but I also ran this on Chrome with --force-gpu-rasterization and --enable-oop-rasterization. The result is that the looper is there since the drop shadow is drawn, but it's drawn as black and without a blur. When I dug into what's happening, that's when I spotted that the filters associated with the looper are missing.
For completeness, that code path serializes the draw looper here:
https://cs.chromium.org/chromium/src/cc/paint/paint_op_writer.cc?sq=package:chromium&dr=CSs&l=140
and deserializes it here:
https://cs.chromium.org/chromium/src/cc/paint/paint_op_reader.cc?sq=package:chromium&dr=CSs&l=240
,
Jan 16 2018
,
Jan 16 2018
I haven't had time to dig into it, but as a quick test I grabbed an SKP from the c#4 example (chrome.gpuBenchmarking.printToSkPicture), and it seems to render fine. So I'm guessing the problem is external to Skia, but will have verify.
,
Jan 16 2018
Pictures "help" by serializing effects and paints separately. Just calling the raw methods 'from scratch' shows the problem. I think I have a fix here: https://skia-review.googlesource.com/c/skia/+/94761
,
Jan 16 2018
I verified locally that the patch fixes this. Thanks!
,
Jan 16 2018
The following revision refers to this bug: https://skia.googlesource.com/skia/+/c183d1642055fb9a6304f2ae9d3e75656fd82b7b commit c183d1642055fb9a6304f2ae9d3e75656fd82b7b Author: Mike Reed <reed@google.com> Date: Tue Jan 16 20:46:18 2018 it is not an error to have no flattenable Bug:801768 Change-Id: Ib6a0a27a1e6828819879c4b5eef9fe0fd319b225 Reviewed-on: https://skia-review.googlesource.com/94761 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com> [modify] https://crrev.com/c183d1642055fb9a6304f2ae9d3e75656fd82b7b/src/core/SkReadBuffer.cpp
,
Jan 17 2018
|
||||
►
Sign in to add a comment |
||||
Comment 1 by reed@google.com
, Jan 16 2018