Add fuzzer for Triangulating Path Renderer

Bug: skia:11892
Change-Id: I3f8145516f8fd23eb05c29517cd5c1553c9b1df1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/399296
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Robert Phillips 2021-04-22 10:51:58 -04:00 committed by Skia Commit-Bot
parent a4e2f28697
commit 98b066cbe8
5 changed files with 112 additions and 45 deletions

View File

@ -2326,6 +2326,7 @@ if (skia_enable_tools) {
"fuzz/FuzzPolyUtils.cpp",
"fuzz/FuzzRegionOp.cpp",
"fuzz/FuzzSkParagraph.cpp",
"fuzz/FuzzTriangulation.cpp",
"fuzz/oss_fuzz/FuzzAndroidCodec.cpp",
"fuzz/oss_fuzz/FuzzAnimatedImage.cpp",
"fuzz/oss_fuzz/FuzzImage.cpp",
@ -3051,6 +3052,14 @@ if (skia_enable_tools) {
deps = []
}
libfuzzer_app("api_triangulation") {
sources = [
"fuzz/FuzzTriangulation.cpp",
"fuzz/oss_fuzz/FuzzTriangulation.cpp",
]
deps = []
}
libfuzzer_app("api_raster_n32_canvas") {
include_dirs = [
"tools",

View File

@ -0,0 +1,32 @@
/*
* Copyright 2021 Google, LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "fuzz/Fuzz.h"
#include "fuzz/FuzzCommon.h"
#include "include/core/SkPath.h"
#include "src/gpu/GrEagerVertexAllocator.h"
#include "src/gpu/GrTriangulator.h"
#include "src/gpu/geometry/GrPathUtils.h"
DEF_FUZZ(Triangulation, fuzz) {
SkPath path;
FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
SkScalar tol = GrPathUtils::scaleToleranceToSrc(GrPathUtils::kDefaultTolerance,
SkMatrix::I(), path.getBounds());
// TODO(robertphillips): messing w/ the clipBounds might be another axis to fuzz.
// afaict it only affects inverse filled paths.
SkRect clipBounds = path.getBounds();
GrCpuVertexAllocator allocator;
bool isLinear;
GrTriangulator::PathToTriangles(path, tol, clipBounds, &allocator, &isLinear);
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2021 Google, LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "fuzz/Fuzz.h"
void fuzz_Triangulation(Fuzz* f);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size > 4000) {
return 0;
}
auto fuzz = Fuzz(SkData::MakeWithoutCopy(data, size));
fuzz_Triangulation(&fuzz);
return 0;
}

View File

@ -8,6 +8,7 @@
#ifndef GrEagerVertexAllocator_DEFINED
#define GrEagerVertexAllocator_DEFINED
#include "src/gpu/GrThreadSafeCache.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
// This interface is used to allocate and map GPU vertex data before the exact number of required
@ -87,4 +88,26 @@ private:
int fLockCount = 0;
};
class GrCpuVertexAllocator : public GrEagerVertexAllocator {
public:
GrCpuVertexAllocator() = default;
#ifdef SK_DEBUG
~GrCpuVertexAllocator() override {
SkASSERT(!fLockStride && !fVertices && !fVertexData);
}
#endif
void* lock(size_t stride, int eagerCount) override;
void unlock(int actualCount) override;
sk_sp<GrThreadSafeCache::VertexData> detachVertexData();
private:
sk_sp<GrThreadSafeCache::VertexData> fVertexData;
void* fVertices = nullptr;
size_t fLockStride = 0;
};
#endif

View File

@ -158,53 +158,37 @@ private:
size_t fLockStride = 0;
};
class CpuVertexAllocator : public GrEagerVertexAllocator {
public:
CpuVertexAllocator() = default;
#ifdef SK_DEBUG
~CpuVertexAllocator() override {
SkASSERT(!fLockStride && !fVertices && !fVertexData);
}
#endif
void* lock(size_t stride, int eagerCount) override {
SkASSERT(!fLockStride && !fVertices && !fVertexData);
SkASSERT(stride && eagerCount);
fVertices = sk_malloc_throw(eagerCount * stride);
fLockStride = stride;
return fVertices;
}
void unlock(int actualCount) override {
SkASSERT(fLockStride && fVertices && !fVertexData);
fVertices = sk_realloc_throw(fVertices, actualCount * fLockStride);
fVertexData = GrThreadSafeCache::MakeVertexData(fVertices, actualCount, fLockStride);
fVertices = nullptr;
fLockStride = 0;
}
sk_sp<GrThreadSafeCache::VertexData> detachVertexData() {
SkASSERT(!fLockStride && !fVertices && fVertexData);
return std::move(fVertexData);
}
private:
sk_sp<GrThreadSafeCache::VertexData> fVertexData;
void* fVertices = nullptr;
size_t fLockStride = 0;
};
} // namespace
//-------------------------------------------------------------------------------------------------
void* GrCpuVertexAllocator::lock(size_t stride, int eagerCount) {
SkASSERT(!fLockStride && !fVertices && !fVertexData);
SkASSERT(stride && eagerCount);
fVertices = sk_malloc_throw(eagerCount * stride);
fLockStride = stride;
return fVertices;
}
void GrCpuVertexAllocator::unlock(int actualCount) {
SkASSERT(fLockStride && fVertices && !fVertexData);
fVertices = sk_realloc_throw(fVertices, actualCount * fLockStride);
fVertexData = GrThreadSafeCache::MakeVertexData(fVertices, actualCount, fLockStride);
fVertices = nullptr;
fLockStride = 0;
}
sk_sp<GrThreadSafeCache::VertexData> GrCpuVertexAllocator::detachVertexData() {
SkASSERT(!fLockStride && !fVertices && fVertexData);
return std::move(fVertexData);
}
//-------------------------------------------------------------------------------------------------
GrTriangulatingPathRenderer::GrTriangulatingPathRenderer()
: fMaxVerbCount(GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
}
@ -536,7 +520,7 @@ private:
return;
}
CpuVertexAllocator allocator;
GrCpuVertexAllocator allocator;
bool isLinear;
int vertexCount = Triangulate(&allocator, fViewMatrix, fShape, fDevClipBounds, tol,