Flutter Engine
The Flutter Engine
FuzzCreateDDL.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google, LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
19
20#include "fuzz/Fuzz.h"
21
22#include <tuple>
23
24/**
25 * The fuzzer aims to fuzz the use of GrDeferredDisplayList. It mainly consists of
26 * three parts.
27 * 1. In create_surface_characterization, (make_characterization) Create GrSurfaceCharacterization
28 * by using GrDirectContext of ContextType::kGL as it can be applied on all platform, and
29 * (make_surface) create a GPU backend surface of the same GrDirectContext
30 * 2. (make_ddl) Create GrDeferredDisplayListRecorder from the GrSurfaceCharacterization, and test
31 * the recoder's corresponding canvas.
32 * 3. (make_ddl, draw_ddl) Create GrDeferredDisplayList from the SkDeferredDisplayRecorder and draw
33 * the ddl on a GPU backend surface.
34 */
35
36static constexpr int kMaxWidth = 64;
37static constexpr int kMaxHeight = 64;
38static constexpr int kSampleCount = 1;
39
41 SkPixelGeometry pixel;
42 fuzz->nextEnum(&pixel, kBGR_V_SkPixelGeometry);
43 return SkSurfaceProps(0x0, pixel);
44}
45
47 float R, G, B, Alpha;
48 fuzz->nextRange(&R, -1, 2);
49 fuzz->nextRange(&G, -1, 2);
50 fuzz->nextRange(&B, -1, 2);
51 fuzz->nextRange(&Alpha, 0, 1);
52 SkColor4f color = {R, G, B, Alpha};
53 return SkPaint(color);
54}
55
57 int width, height;
58 fuzz->nextRange(&width, 1, kMaxWidth);
59 fuzz->nextRange(&height, 1, kMaxHeight);
60 SkAlphaType alphaType;
63 uint8_t skcms;
64 fuzz->nextRange(&skcms, 0, 5);
65 switch (skcms) {
66 case 0: {
68 break;
69 }
70 case 1: {
72 break;
73 }
74 case 2: {
76 break;
77 }
78 case 3: {
80 break;
81 }
82 case 4: {
83 skcmsFn = SkNamedTransferFn::kPQ;
84 break;
85 }
86 case 5: {
88 break;
89 }
90 default:
91 SkASSERT(false);
92 break;
93 }
94 skcms_Matrix3x3 skcmsMat;
95 fuzz->nextRange(&skcms, 0, 4);
96 switch (skcms) {
97 case 0: {
98 skcmsMat = SkNamedGamut::kAdobeRGB;
99 break;
100 }
101 case 1: {
102 skcmsMat = SkNamedGamut::kDisplayP3;
103 break;
104 }
105 case 2: {
106 skcmsMat = SkNamedGamut::kRec2020;
107 break;
108 }
109 case 3: {
110 skcmsMat = SkNamedGamut::kSRGB;
111 break;
112 }
113 case 4: {
114 skcmsMat = SkNamedGamut::kXYZ;
115 break;
116 }
117 default:
118 SkASSERT(false);
119 break;
120 }
121 return SkImageInfo::Make(width, height, surfaceType, alphaType,
122 SkColorSpace::MakeRGB(skcmsFn, skcmsMat));
123}
124
126 SkImageInfo& ii, SkColorType surfaceType,
127 GrSurfaceOrigin origin) {
128 if (!dContext->colorTypeSupportedAsSurface(surfaceType)) {
129 SkDebugf("Couldn't create backend texture in the backend %s",
130 GrBackendApiToStr(dContext->backend()));
131 return {};
132 }
133
134 GrBackendFormat backendFormat = dContext->defaultBackendFormat(surfaceType,
136 if (!backendFormat.isValid()) {
137 SkDebugf("Color Type is not supported in the backend %s",
138 GrBackendApiToStr(dContext->backend()));
139 return {};
140 }
142#ifdef SK_VULKAN
143 fuzz->nextEnum(&protect, GrProtected::kYes);
144#endif
146 size_t maxResourceBytes = dContext->getResourceCacheLimit();
147 c = dContext->threadSafeProxy()->createCharacterization(maxResourceBytes,
148 ii,
149 backendFormat,
151 origin,
154 false,
155 true,
156 protect);
157 if (!c.isValid()) {
158 SkDebugf("Could not create Characterization in the backend %s",
159 GrBackendApiToStr(dContext->backend()));
160 return {};
161 }
162 return c;
163}
164
166 const GrSurfaceCharacterization& c) {
168 SkCanvas* canvas = r.getCanvas();
169 if (!canvas) {
170 SkDebugf("Could not create canvas for backend %s", GrBackendApiToStr(dContext->backend()));
171 return nullptr;
172 }
173 // For now we only draw a rect into the DDL. This will be scaled up to draw more varied content.
174 SkRect tile;
175 fuzz->next(&tile);
176 canvas->drawRect(tile, gen_fuzzed_skpaint(fuzz));
177 return r.detach();
178}
179
181 GrSurfaceOrigin origin) {
182 skgpu::Budgeted budgeted;
183 fuzz->nextEnum(&budgeted, skgpu::Budgeted::kYes);
184 SkSurfaceProps surfaceProps = gen_fuzzed_surface_props(fuzz);
185 auto surface =
186 SkSurfaces::RenderTarget(dContext, budgeted, ii, kSampleCount, origin, &surfaceProps);
187 return surface;
188}
189
191 return skgpu::ganesh::DrawDDL(std::move(surface), std::move(ddl));
192}
193
194using SurfaceAndChar = std::tuple<sk_sp<SkSurface>, GrSurfaceCharacterization>;
196 SkColorType surfaceType,
197 GrSurfaceOrigin origin) {
198 SkImageInfo ii = gen_fuzzed_imageinfo(fuzz, surfaceType);
199 GrSurfaceCharacterization c = make_characterization(fuzz, dContext, ii, surfaceType, origin);
200 if (!c.isValid()) {
201 return {};
202 }
203
204 auto surface = make_surface(fuzz, dContext, ii, origin);
205 if (!surface) {
206 return {};
207 }
208 return {surface, c};
209}
210
211DEF_FUZZ(CreateDDL, fuzz) {
212 SkColorType surfaceType;
213 GrSurfaceOrigin origin;
214 fuzz->nextEnum(&surfaceType, SkColorType::kLastEnum_SkColorType);
215 fuzz->nextEnum(&origin, GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin);
216
218 auto ctxInfo = factory.getContextInfo(skgpu::ContextType::kGL);
219
220 GrDirectContext* dContext = ctxInfo.directContext();
221 if (!dContext) {
222 SkDebugf("Context creation failed");
223 return;
224 }
225
226 auto[surface, c] = create_surface_and_characterization(fuzz, dContext, surfaceType, origin);
227 if (!surface || !c.isValid()) {
228 return;
229 }
230
231 sk_sp<GrDeferredDisplayList> ddl = make_ddl(fuzz, dContext, c);
232 if (!ddl) {
233 SkDebugf("Could not create ddl %s", GrBackendApiToStr(dContext->backend()));
234 return;
235 }
236 if (!draw_ddl(std::move(surface), std::move(ddl))) {
237 SkDebugf("Could not draw ddl in the backend");
238 }
239 return;
240}
static sk_sp< GrDeferredDisplayList > make_ddl(Fuzz *fuzz, GrDirectContext *dContext, const GrSurfaceCharacterization &c)
static bool draw_ddl(sk_sp< SkSurface > surface, sk_sp< const GrDeferredDisplayList > ddl)
std::tuple< sk_sp< SkSurface >, GrSurfaceCharacterization > SurfaceAndChar
static GrSurfaceCharacterization make_characterization(Fuzz *fuzz, GrDirectContext *dContext, SkImageInfo &ii, SkColorType surfaceType, GrSurfaceOrigin origin)
static constexpr int kMaxHeight
static SkPaint gen_fuzzed_skpaint(Fuzz *fuzz)
static constexpr int kSampleCount
DEF_FUZZ(CreateDDL, fuzz)
static constexpr int kMaxWidth
static SurfaceAndChar create_surface_and_characterization(Fuzz *fuzz, GrDirectContext *dContext, SkColorType surfaceType, GrSurfaceOrigin origin)
static sk_sp< SkSurface > make_surface(Fuzz *fuzz, GrDirectContext *dContext, const SkImageInfo &ii, GrSurfaceOrigin origin)
static SkImageInfo gen_fuzzed_imageinfo(Fuzz *fuzz, SkColorType surfaceType)
static SkSurfaceProps gen_fuzzed_surface_props(Fuzz *fuzz)
GrSurfaceOrigin
Definition: GrTypes.h:147
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
SkAlphaType
Definition: SkAlphaType.h:26
@ kLastEnum_SkAlphaType
last valid value
Definition: SkAlphaType.h:31
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
@ kLastEnum_SkColorType
last valid value
Definition: SkColorType.h:56
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static void skcms(char *dst, const char *src, int n, skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha, skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha)
SkPixelGeometry
@ kBGR_V_SkPixelGeometry
Definition: Fuzz.h:24
void next(T *t)
Definition: Fuzz.h:64
void nextRange(T *, Min, Max)
Definition: Fuzz.h:119
void nextEnum(T *ptr, T max)
Definition: Fuzz.h:131
bool isValid() const
GrSurfaceCharacterization createCharacterization(size_t cacheMaxResourceBytes, const SkImageInfo &ii, const GrBackendFormat &backendFormat, int sampleCount, GrSurfaceOrigin origin, const SkSurfaceProps &surfaceProps, skgpu::Mipmapped isMipmapped, bool willUseGLFBO0=false, bool isTextureable=true, skgpu::Protected isProtected=GrProtected::kNo, bool vkRTSupportsInputAttachment=false, bool forVulkanSecondaryCommandBuffer=false)
SK_API GrBackendApi backend() const
SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const
sk_sp< GrDeferredDisplayList > detach()
SK_API bool colorTypeSupportedAsSurface(SkColorType colorType) const
size_t getResourceCacheLimit() const
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
ContextInfo getContextInfo(ContextType type, ContextOverrides=ContextOverrides::kNone)
DlColor color
VkSurfaceKHR surface
Definition: main.cc:49
#define R(r)
#define B
static constexpr skcms_Matrix3x3 kSRGB
Definition: SkColorSpace.h:67
static constexpr skcms_Matrix3x3 kAdobeRGB
Definition: SkColorSpace.h:77
static constexpr skcms_Matrix3x3 kXYZ
Definition: SkColorSpace.h:99
static constexpr skcms_Matrix3x3 kRec2020
Definition: SkColorSpace.h:93
static constexpr skcms_Matrix3x3 kDisplayP3
Definition: SkColorSpace.h:87
static constexpr skcms_TransferFunction kRec2020
Definition: SkColorSpace.h:54
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
static constexpr skcms_TransferFunction kSRGB
Definition: SkColorSpace.h:45
static constexpr skcms_TransferFunction kHLG
Definition: SkColorSpace.h:60
static constexpr skcms_TransferFunction kPQ
Definition: SkColorSpace.h:57
static constexpr skcms_TransferFunction kLinear
Definition: SkColorSpace.h:51
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
SK_API bool DrawDDL(SkSurface *, sk_sp< const GrDeferredDisplayList > ddl)
Budgeted
Definition: GpuTypes.h:35
Protected
Definition: GpuTypes.h:61
int32_t height
int32_t width
Definition: SkMD5.cpp:125
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)