check all calls to SkCreateRasterPipelineBlitter

We made these functions return nullptr but several
call sites were not updated to expect nullptr.

This is my best guess for the attached fuzzer bug.
I haven't looked deeply but will if this doesn't fix it.

Bug: chromium:1097084
Change-Id: Id57d402dea5f007d886d852be8035b13f62be9a8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297820
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-06-19 14:03:39 -05:00 committed by Skia Commit-Bot
parent 0426947243
commit e66636c332
4 changed files with 45 additions and 39 deletions

View File

@ -142,6 +142,9 @@ public:
bool is_opaque = fSource.isOpaque() && fPaintColor.fA == 1.0f;
fBlitter = SkCreateRasterPipelineBlitter(fDst, paint, p, is_opaque, fAlloc, fClipShader);
if (!fBlitter) {
fBlitter = fAlloc->make<SkNullBlitter>();
}
}
void blitRect(int x, int y, int width, int height) override {

View File

@ -164,12 +164,10 @@ private:
///////////////////////////////////////////////////////////////////////////////
// Neither of these ever returns nullptr, but this first factory may return a SkNullBlitter.
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&,
const SkMatrixProvider& matrixProvider, SkArenaAlloc*,
sk_sp<SkShader> clipShader);
// Use this if you've pre-baked a shader pipeline, including modulating with paint alpha.
// This factory never returns an SkNullBlitter.
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&,
const SkRasterPipeline& shaderPipeline,
bool shader_is_opaque,

View File

@ -101,24 +101,25 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
isOpaque = false;
}
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
fRC->clipShader());
SkPath scratchPath;
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
fRC->clipShader())) {
SkPath scratchPath;
for (int i = 0; i < count; ++i) {
if (colors) {
SkColor4f c4 = SkColor4f::FromColor(colors[i]);
steps.apply(c4.vec());
load_color(uniformCtx, c4.premul().vec());
}
for (int i = 0; i < count; ++i) {
if (colors) {
SkColor4f c4 = SkColor4f::FromColor(colors[i]);
steps.apply(c4.vec());
load_color(uniformCtx, c4.premul().vec());
}
SkMatrix mx;
mx.setRSXform(xform[i]);
mx.preTranslate(-textures[i].fLeft, -textures[i].fTop);
mx.postConcat(fMatrixProvider->localToDevice());
SkMatrix mx;
mx.setRSXform(xform[i]);
mx.preTranslate(-textures[i].fLeft, -textures[i].fTop);
mx.postConcat(fMatrixProvider->localToDevice());
if (updator->update(mx, nullptr)) {
fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);
if (updator->update(mx, nullptr)) {
fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);
}
}
}
}

View File

@ -330,14 +330,16 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
p.setShader(sk_ref_sp(shader));
if (!textures) { // only tricolor shader
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *fMatrixProvider, outerAlloc,
this->fRC->clipShader());
while (vertProc(&state)) {
if (triShader &&
!triShader->update(ctmInv, positions, dstColors, state.f0, state.f1, state.f2)) {
continue;
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *fMatrixProvider, outerAlloc,
this->fRC->clipShader())) {
while (vertProc(&state)) {
if (triShader &&
!triShader->update(ctmInv, positions, dstColors,
state.f0, state.f1, state.f2)) {
continue;
}
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
return;
}
@ -361,19 +363,20 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
}
}
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, outerAlloc,
fRC->clipShader());
while (vertProc(&state)) {
if (triShader && !triShader->update(ctmInv, positions, dstColors,
state.f0, state.f1, state.f2)) {
continue;
}
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, outerAlloc,
fRC->clipShader())) {
while (vertProc(&state)) {
if (triShader && !triShader->update(ctmInv, positions, dstColors,
state.f0, state.f1, state.f2)) {
continue;
}
SkMatrix localM;
if ((textures == positions) ||
(texture_to_matrix(state, positions, textures, &localM) &&
updater->update(ctm, &localM))) {
fill_triangle(state, blitter, *fRC, dev2, dev3);
SkMatrix localM;
if ((textures == positions) ||
(texture_to_matrix(state, positions, textures, &localM) &&
updater->update(ctm, &localM))) {
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
}
}
} else {
@ -396,9 +399,10 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
matrixProvider = preConcatMatrixProvider.init(*matrixProvider, localM);
}
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *matrixProvider, &innerAlloc,
this->fRC->clipShader());
fill_triangle(state, blitter, *fRC, dev2, dev3);
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *matrixProvider, &innerAlloc,
this->fRC->clipShader())) {
fill_triangle(state, blitter, *fRC, dev2, dev3);
}
}
}
}