blob: f9a920f523d29c5fc58ecb76e8d75d17177785d6 [file] [log] [blame]
scroggo478652e2015-03-25 07:11:02 -07001/*
2 * Copyright 2015 Google Inc.
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
mtklein748ca3b2015-01-15 10:56:12 -08008#ifndef DMSrcSink_DEFINED
9#define DMSrcSink_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "gm/gm.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkBBHFactory.h"
13#include "include/core/SkBitmap.h"
14#include "include/core/SkCanvas.h"
15#include "include/core/SkData.h"
16#include "include/core/SkPicture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/utils/SkMultiPictureDocument.h"
18#include "tools/flags/CommonFlagsConfig.h"
Brian Osman9c310472019-06-27 16:43:27 -040019#include "tools/gpu/MemoryCache.h"
mtklein748ca3b2015-01-15 10:56:12 -080020
Brian Osmaned58e002019-09-06 14:42:43 -040021#include <functional>
22
Mike Reedbae888e2017-02-18 16:50:45 -050023//#define TEST_VIA_SVG
24
Tyler Denniston45f94f82020-02-04 16:09:08 -050025namespace skiagm {
26namespace verifiers {
27class VerifierList;
John Stilesa6841be2020-08-06 14:11:56 -040028} // namespace verifiers
29} // namespace skiagm
Tyler Denniston45f94f82020-02-04 16:09:08 -050030
mtklein748ca3b2015-01-15 10:56:12 -080031namespace DM {
32
33// This is just convenience. It lets you use either return "foo" or return SkStringPrintf(...).
34struct ImplicitString : public SkString {
35 template <typename T>
36 ImplicitString(const T& s) : SkString(s) {}
msarett9e707a02015-09-01 14:57:57 -070037 ImplicitString() : SkString("") {}
mtklein748ca3b2015-01-15 10:56:12 -080038};
mtklein748ca3b2015-01-15 10:56:12 -080039typedef ImplicitString Name;
mtklein8d17a132015-01-30 11:42:31 -080040typedef ImplicitString Path;
mtklein748ca3b2015-01-15 10:56:12 -080041
Ben Wagnerea25fcf2020-02-12 11:18:46 -050042class Result {
mtklein4089ef72015-03-05 08:40:28 -080043public:
Ben Wagnerea25fcf2020-02-12 11:18:46 -050044 enum class Status : int { Ok, Fatal, Skip };
45 Result(Status status, const SkString& s) : fMsg(s), fStatus(status) {}
46 Result(Status status, const char* s) : fMsg(s), fStatus(status) {}
47 template <typename... Args> Result (Status status, const char* s, Args... args)
48 : fMsg(SkStringPrintf(s, args...)), fStatus(status) {}
mtklein4089ef72015-03-05 08:40:28 -080049
Ben Wagnerea25fcf2020-02-12 11:18:46 -050050 Result(const Result&) = default;
51 Result& operator=(const Result&) = default;
mtklein4089ef72015-03-05 08:40:28 -080052
Ben Wagnerea25fcf2020-02-12 11:18:46 -050053 static Result Ok() { return Result(Status::Ok, nullptr); }
54
55 static Result Fatal(const SkString& s) { return Result(Status::Fatal, s); }
56 static Result Fatal(const char* s) { return Result(Status::Fatal, s); }
57 template <typename... Args> static Result Fatal(const char* s, Args... args) {
58 return Result(Status::Fatal, s, args...);
mtklein4089ef72015-03-05 08:40:28 -080059 }
60
Ben Wagnerea25fcf2020-02-12 11:18:46 -050061 static Result Skip(const SkString& s) { return Result(Status::Skip, s); }
62 static Result Skip(const char* s) { return Result(Status::Skip, s); }
63 template <typename... Args> static Result Skip(const char* s, Args... args) {
64 return Result(Status::Skip, s, args...);
65 }
66
67 bool isOk() { return fStatus == Status::Ok; }
68 bool isFatal() { return fStatus == Status::Fatal; }
69 bool isSkip() { return fStatus == Status::Skip; }
70
mtklein4089ef72015-03-05 08:40:28 -080071 const char* c_str() const { return fMsg.c_str(); }
Ben Wagnerea25fcf2020-02-12 11:18:46 -050072 Status status() const { return fStatus; }
mtklein4089ef72015-03-05 08:40:28 -080073
74private:
75 SkString fMsg;
Ben Wagnerea25fcf2020-02-12 11:18:46 -050076 Status fStatus;
mtklein4089ef72015-03-05 08:40:28 -080077};
78
mtklein99cab4e2015-07-31 06:43:04 -070079struct SinkFlags {
Brian Salomonbd7c5512017-03-07 09:08:36 -050080 enum Type { kNull, kGPU, kVector, kRaster } type;
81 enum Approach { kDirect, kIndirect } approach;
82 enum Multisampled { kNotMultisampled, kMultisampled } multisampled;
83 SinkFlags(Type t, Approach a, Multisampled ms = kNotMultisampled)
84 : type(t), approach(a), multisampled(ms) {}
mtklein99cab4e2015-07-31 06:43:04 -070085};
mtkleine0effd62015-07-29 06:37:28 -070086
mtklein748ca3b2015-01-15 10:56:12 -080087struct Src {
mtklein748ca3b2015-01-15 10:56:12 -080088 virtual ~Src() {}
Robert Phillipsb87b39b2020-07-01 14:45:24 -040089 virtual Result SK_WARN_UNUSED_RESULT draw(GrDirectContext*, SkCanvas*) const = 0;
mtklein748ca3b2015-01-15 10:56:12 -080090 virtual SkISize size() const = 0;
91 virtual Name name() const = 0;
bsalomon4ee6bd82015-05-27 13:23:23 -070092 virtual void modifyGrContextOptions(GrContextOptions* options) const {}
mtklein99cab4e2015-07-31 06:43:04 -070093 virtual bool veto(SinkFlags) const { return false; }
mtklein21eaf3b2016-02-08 12:39:59 -080094
halcanary45420a92016-06-02 12:41:14 -070095 virtual int pageCount() const { return 1; }
Robert Phillipsb87b39b2020-07-01 14:45:24 -040096 virtual Result SK_WARN_UNUSED_RESULT draw(int, GrDirectContext* context,
97 SkCanvas* canvas) const {
Robert Phillips889d6132020-06-16 11:11:33 -040098 return this->draw(context, canvas);
halcanary45420a92016-06-02 12:41:14 -070099 }
100 virtual SkISize size(int) const { return this->size(); }
mtklein21eaf3b2016-02-08 12:39:59 -0800101 // Force Tasks using this Src to run on the main thread?
102 virtual bool serial() const { return false; }
Tyler Denniston45f94f82020-02-04 16:09:08 -0500103
104 /** Return a list of verifiers for the src, or null if no verifiers should be run .*/
105 virtual std::unique_ptr<skiagm::verifiers::VerifierList> getVerifiers() const {
106 return nullptr;
107 }
mtklein748ca3b2015-01-15 10:56:12 -0800108};
109
110struct Sink {
111 virtual ~Sink() {}
mtkleinb9eb4ac2015-02-02 18:26:03 -0800112 // You may write to either the bitmap or stream. If you write to log, we'll print that out.
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500113 virtual Result SK_WARN_UNUSED_RESULT draw(const Src&, SkBitmap*, SkWStream*, SkString* log)
mtkleinb9eb4ac2015-02-02 18:26:03 -0800114 const = 0;
mtklein21eaf3b2016-02-08 12:39:59 -0800115
116 // Force Tasks using this Sink to run on the main thread?
117 virtual bool serial() const { return false; }
mtklein748ca3b2015-01-15 10:56:12 -0800118
119 // File extension for the content draw() outputs, e.g. "png", "pdf".
120 virtual const char* fileExtension() const = 0;
mtklein99cab4e2015-07-31 06:43:04 -0700121
122 virtual SinkFlags flags() const = 0;
Tyler Denniston45f94f82020-02-04 16:09:08 -0500123
124 /** Returns the color type and space used by the sink. */
125 virtual SkColorInfo colorInfo() const { return SkColorInfo(); }
mtklein748ca3b2015-01-15 10:56:12 -0800126};
127
mtklein748ca3b2015-01-15 10:56:12 -0800128/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
129
mtklein748ca3b2015-01-15 10:56:12 -0800130class GMSrc : public Src {
131public:
Hal Canary972eba32018-07-30 17:07:07 -0400132 explicit GMSrc(skiagm::GMFactory);
mtklein748ca3b2015-01-15 10:56:12 -0800133
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400134 Result draw(GrDirectContext*, SkCanvas*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700135 SkISize size() const override;
136 Name name() const override;
bsalomon4ee6bd82015-05-27 13:23:23 -0700137 void modifyGrContextOptions(GrContextOptions* options) const override;
138
Tyler Denniston45f94f82020-02-04 16:09:08 -0500139 std::unique_ptr<skiagm::verifiers::VerifierList> getVerifiers() const override;
140
mtklein748ca3b2015-01-15 10:56:12 -0800141private:
Hal Canary972eba32018-07-30 17:07:07 -0400142 skiagm::GMFactory fFactory;
mtklein748ca3b2015-01-15 10:56:12 -0800143};
144
scroggo9b77ddd2015-03-19 06:03:39 -0700145class CodecSrc : public Src {
146public:
scroggo9c59ebc2015-03-25 13:48:49 -0700147 enum Mode {
msarett9e707a02015-09-01 14:57:57 -0700148 kCodec_Mode,
msarettbb25b532016-01-13 09:31:39 -0800149 // We choose to test only one mode with zero initialized memory.
150 // This will exercise all of the interesting cases in SkSwizzler
151 // without doubling the size of our test suite.
152 kCodecZeroInit_Mode,
scroggo9c59ebc2015-03-25 13:48:49 -0700153 kScanline_Mode,
msarett0a242972015-06-11 14:27:27 -0700154 kStripe_Mode, // Tests the skipping of scanlines
msarett91c22b22016-02-22 12:27:46 -0800155 kCroppedScanline_Mode, // Tests (jpeg) cropped scanline optimization
scroggob636b452015-07-22 07:16:20 -0700156 kSubset_Mode, // For codecs that support subsets directly.
scroggo19b91532016-10-24 09:03:26 -0700157 kAnimated_Mode, // For codecs that support animation.
scroggo9c59ebc2015-03-25 13:48:49 -0700158 };
msarett438b2ad2015-04-09 12:43:10 -0700159 enum DstColorType {
160 kGetFromCanvas_DstColorType,
msarett438b2ad2015-04-09 12:43:10 -0700161 kGrayscale_Always_DstColorType,
msarett34e0ec42016-04-22 16:27:24 -0700162 kNonNative8888_Always_DstColorType,
msarett438b2ad2015-04-09 12:43:10 -0700163 };
scroggoc5560be2016-02-03 09:42:42 -0800164 CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);
scroggo9b77ddd2015-03-19 06:03:39 -0700165
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400166 Result draw(GrDirectContext*, SkCanvas*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700167 SkISize size() const override;
168 Name name() const override;
mtklein99cab4e2015-07-31 06:43:04 -0700169 bool veto(SinkFlags) const override;
scroggo3ac66e92016-02-08 15:09:48 -0800170 bool serial() const override { return fRunSerially; }
scroggo9b77ddd2015-03-19 06:03:39 -0700171private:
msarett9e707a02015-09-01 14:57:57 -0700172 Path fPath;
173 Mode fMode;
174 DstColorType fDstColorType;
scroggoc5560be2016-02-03 09:42:42 -0800175 SkAlphaType fDstAlphaType;
msarett9e707a02015-09-01 14:57:57 -0700176 float fScale;
scroggo3ac66e92016-02-08 15:09:48 -0800177 bool fRunSerially;
scroggo9b77ddd2015-03-19 06:03:39 -0700178};
179
msarett3d9d7a72015-10-21 10:27:10 -0700180class AndroidCodecSrc : public Src {
181public:
scroggof8dc9df2016-05-16 09:04:13 -0700182 AndroidCodecSrc(Path, CodecSrc::DstColorType, SkAlphaType, int sampleSize);
msarett3d9d7a72015-10-21 10:27:10 -0700183
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400184 Result draw(GrDirectContext*, SkCanvas*) const override;
msarett3d9d7a72015-10-21 10:27:10 -0700185 SkISize size() const override;
186 Name name() const override;
187 bool veto(SinkFlags) const override;
scroggo3ac66e92016-02-08 15:09:48 -0800188 bool serial() const override { return fRunSerially; }
msarett3d9d7a72015-10-21 10:27:10 -0700189private:
190 Path fPath;
msarett3d9d7a72015-10-21 10:27:10 -0700191 CodecSrc::DstColorType fDstColorType;
scroggoc5560be2016-02-03 09:42:42 -0800192 SkAlphaType fDstAlphaType;
msarett3d9d7a72015-10-21 10:27:10 -0700193 int fSampleSize;
scroggo3ac66e92016-02-08 15:09:48 -0800194 bool fRunSerially;
msarett3d9d7a72015-10-21 10:27:10 -0700195};
196
Leon Scroggins III87caae62020-05-04 10:02:45 -0400197#ifdef SK_ENABLE_ANDROID_UTILS
msaretta5783ae2015-09-08 15:35:32 -0700198// Allows for testing of various implementations of Android's BitmapRegionDecoder
199class BRDSrc : public Src {
200public:
201 enum Mode {
202 // Decode the entire image as one region.
203 kFullImage_Mode,
204 // Splits the image into multiple regions using a divisor and decodes the regions
205 // separately. Also, this test adds a border of a few pixels to each of the regions
206 // that it is decoding. This tests the behavior when a client asks for a region that
207 // does not fully fit in the image.
208 kDivisor_Mode,
209 };
210
msarettd1227a72016-05-18 06:23:57 -0700211 BRDSrc(Path, Mode, CodecSrc::DstColorType, uint32_t);
msaretta5783ae2015-09-08 15:35:32 -0700212
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400213 Result draw(GrDirectContext*, SkCanvas*) const override;
msaretta5783ae2015-09-08 15:35:32 -0700214 SkISize size() const override;
215 Name name() const override;
216 bool veto(SinkFlags) const override;
217private:
218 Path fPath;
msaretta5783ae2015-09-08 15:35:32 -0700219 Mode fMode;
220 CodecSrc::DstColorType fDstColorType;
221 uint32_t fSampleSize;
222};
Leon Scroggins III87caae62020-05-04 10:02:45 -0400223#endif
scroggo9b77ddd2015-03-19 06:03:39 -0700224
msarett18976312016-03-09 14:20:58 -0800225class ImageGenSrc : public Src {
226public:
227 enum Mode {
228 kCodec_Mode, // Use CodecImageGenerator
229 kPlatform_Mode, // Uses CG or WIC
230 };
231 ImageGenSrc(Path, Mode, SkAlphaType, bool);
232
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400233 Result draw(GrDirectContext*, SkCanvas*) const override;
msarett18976312016-03-09 14:20:58 -0800234 SkISize size() const override;
235 Name name() const override;
236 bool veto(SinkFlags) const override;
237 bool serial() const override { return fRunSerially; }
238private:
239 Path fPath;
240 Mode fMode;
241 SkAlphaType fDstAlphaType;
242 bool fIsGpu;
243 bool fRunSerially;
244};
245
msarett69deca82016-04-29 09:38:40 -0700246class ColorCodecSrc : public Src {
247public:
Mike Klein0d5d1422019-03-06 10:56:04 -0600248 ColorCodecSrc(Path, bool decode_to_dst);
msarett69deca82016-04-29 09:38:40 -0700249
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400250 Result draw(GrDirectContext*, SkCanvas*) const override;
msarett69deca82016-04-29 09:38:40 -0700251 SkISize size() const override;
252 Name name() const override;
253 bool veto(SinkFlags) const override;
254private:
Mike Klein0d5d1422019-03-06 10:56:04 -0600255 Path fPath;
256 bool fDecodeToDst;
msarett69deca82016-04-29 09:38:40 -0700257};
258
mtklein748ca3b2015-01-15 10:56:12 -0800259class SKPSrc : public Src {
260public:
mtklein8d17a132015-01-30 11:42:31 -0800261 explicit SKPSrc(Path path);
mtklein748ca3b2015-01-15 10:56:12 -0800262
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400263 Result draw(GrDirectContext*, SkCanvas*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700264 SkISize size() const override;
265 Name name() const override;
mtklein748ca3b2015-01-15 10:56:12 -0800266private:
mtklein8d17a132015-01-30 11:42:31 -0800267 Path fPath;
mtklein748ca3b2015-01-15 10:56:12 -0800268};
269
Chris Dalton184c37e2018-09-28 11:27:39 -0600270// This class extracts all the paths from an SKP and then removes unwanted paths according to the
271// provided l/r trail. It then just draws the remaining paths. (Non-path draws are thrown out.) It
272// is useful for finding a reduced repo case for path drawing bugs.
273class BisectSrc : public SKPSrc {
274public:
275 explicit BisectSrc(Path path, const char* trail);
276
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400277 Result draw(GrDirectContext*, SkCanvas*) const override;
Chris Dalton184c37e2018-09-28 11:27:39 -0600278
279private:
280 SkString fTrail;
281
John Stiles7571f9e2020-09-02 22:42:33 -0400282 using INHERITED = SKPSrc;
Chris Dalton184c37e2018-09-28 11:27:39 -0600283};
284
Florin Malita87ccf332018-05-04 12:23:24 -0400285#if defined(SK_ENABLE_SKOTTIE)
Florin Malita54f65c42018-01-16 17:04:30 -0500286class SkottieSrc final : public Src {
Florin Malitafc043dc2017-12-31 11:08:42 -0500287public:
Florin Malita54f65c42018-01-16 17:04:30 -0500288 explicit SkottieSrc(Path path);
Florin Malitafc043dc2017-12-31 11:08:42 -0500289
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400290 Result draw(GrDirectContext*, SkCanvas*) const override;
Florin Malitafc043dc2017-12-31 11:08:42 -0500291 SkISize size() const override;
292 Name name() const override;
293 bool veto(SinkFlags) const override;
294
295private:
296 // Generates a kTileCount x kTileCount filmstrip with evenly distributed frames.
Florin Malita1022f742018-02-23 11:10:22 -0500297 static constexpr int kTileCount = 5;
Florin Malitafc043dc2017-12-31 11:08:42 -0500298
Florin Malita9f7d4cd2018-07-30 15:49:20 -0400299 // Fit kTileCount x kTileCount frames to a 1000x1000 film strip.
300 static constexpr SkScalar kTargetSize = 1000;
301 static constexpr SkScalar kTileSize = kTargetSize / kTileCount;
302
303 Path fPath;
Florin Malitafc043dc2017-12-31 11:08:42 -0500304};
Florin Malita124d5af2017-12-31 17:02:26 -0500305#endif
Florin Malitafc043dc2017-12-31 11:08:42 -0500306
Florin Malita02616ea2020-06-25 13:33:17 -0400307#if defined(SK_ENABLE_SKRIVE)
308class SkRiveSrc final : public Src {
309public:
310 explicit SkRiveSrc(Path path);
311
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400312 Result draw(GrDirectContext*, SkCanvas*) const override;
Florin Malita02616ea2020-06-25 13:33:17 -0400313 SkISize size() const override;
314 Name name() const override;
315 bool veto(SinkFlags) const override;
316
317private:
318 // Generates a kTileCount x kTileCount filmstrip with evenly distributed frames.
319 static constexpr int kTileCount = 5;
320
321 // Fit kTileCount x kTileCount frames to a 1000x1000 film strip.
322 static constexpr SkScalar kTargetSize = 1000;
323 static constexpr SkScalar kTileSize = kTargetSize / kTileCount;
324
325 const Path fPath;
326};
327#endif
328
fmalitaa2b9fdf2016-08-03 19:53:36 -0700329#if defined(SK_XML)
fmalitabdf3e5c2016-09-17 07:26:26 -0700330} // namespace DM
331
332class SkSVGDOM;
333
334namespace DM {
335
fmalitaa2b9fdf2016-08-03 19:53:36 -0700336class SVGSrc : public Src {
337public:
338 explicit SVGSrc(Path path);
339
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400340 Result draw(GrDirectContext*, SkCanvas*) const override;
fmalitaa2b9fdf2016-08-03 19:53:36 -0700341 SkISize size() const override;
342 Name name() const override;
fmalita179d8852016-08-16 14:23:29 -0700343 bool veto(SinkFlags) const override;
fmalitaa2b9fdf2016-08-03 19:53:36 -0700344
345private:
fmalitaacd2f5c2016-11-08 07:13:45 -0800346 Name fName;
347 sk_sp<SkSVGDOM> fDom;
348 SkScalar fScale;
fmalitaa2b9fdf2016-08-03 19:53:36 -0700349
John Stiles7571f9e2020-09-02 22:42:33 -0400350 using INHERITED = Src;
fmalitaa2b9fdf2016-08-03 19:53:36 -0700351};
352#endif // SK_XML
mtklein748ca3b2015-01-15 10:56:12 -0800353/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
354
halcanary45420a92016-06-02 12:41:14 -0700355class MSKPSrc : public Src {
356public:
357 explicit MSKPSrc(Path path);
358
359 int pageCount() const override;
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400360 Result draw(GrDirectContext*, SkCanvas* c) const override;
361 Result draw(int, GrDirectContext*, SkCanvas*) const override;
halcanary45420a92016-06-02 12:41:14 -0700362 SkISize size() const override;
363 SkISize size(int) const override;
364 Name name() const override;
365
366private:
367 Path fPath;
Hal Canary45cde312017-04-03 16:06:42 -0400368 mutable SkTArray<SkDocumentPage> fPages;
halcanary45420a92016-06-02 12:41:14 -0700369};
370
371/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
372
mtkleinad66f9b2015-02-13 15:11:10 -0800373class NullSink : public Sink {
374public:
375 NullSink() {}
376
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500377 Result draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700378 const char* fileExtension() const override { return ""; }
mtklein99cab4e2015-07-31 06:43:04 -0700379 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kNull, SinkFlags::kDirect }; }
mtkleinad66f9b2015-02-13 15:11:10 -0800380};
381
mtklein748ca3b2015-01-15 10:56:12 -0800382class GPUSink : public Sink {
383public:
Brian Osman3fdfe282019-09-09 13:46:52 -0400384 GPUSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
mtklein748ca3b2015-01-15 10:56:12 -0800385
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500386 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
387 Result onDraw(const Src&, SkBitmap*, SkWStream*, SkString*,
388 const GrContextOptions& baseOptions,
Robert Phillipse219c7e2020-08-13 15:58:29 -0400389 std::function<void(GrDirectContext*)> initContext = nullptr) const;
Brian Osmanf9810662017-08-30 10:02:10 -0400390
Brian Salomonb07fd4d2018-03-09 13:17:30 -0500391 sk_gpu_test::GrContextFactory::ContextType contextType() const { return fContextType; }
Robert Phillips3c1efd42020-02-13 15:51:59 -0500392 const sk_gpu_test::GrContextFactory::ContextOverrides& contextOverrides() const {
Brian Salomonb07fd4d2018-03-09 13:17:30 -0500393 return fContextOverrides;
394 }
395 SkCommandLineConfigGpu::SurfType surfType() const { return fSurfType; }
Brian Osman3fdfe282019-09-09 13:46:52 -0400396 bool serial() const override { return true; }
mtklein36352bf2015-03-25 18:17:31 -0700397 const char* fileExtension() const override { return "png"; }
Brian Salomonbd7c5512017-03-07 09:08:36 -0500398 SinkFlags flags() const override {
Brian Salomonbdecacf2018-02-02 20:32:49 -0500399 SinkFlags::Multisampled ms = fSampleCount > 1 ? SinkFlags::kMultisampled
Brian Salomonfd171ed2017-03-08 11:38:45 -0500400 : SinkFlags::kNotMultisampled;
401 return SinkFlags{ SinkFlags::kGPU, SinkFlags::kDirect, ms };
Brian Salomonbd7c5512017-03-07 09:08:36 -0500402 }
Brian Osmanf9810662017-08-30 10:02:10 -0400403 const GrContextOptions& baseContextOptions() const { return fBaseContextOptions; }
Tyler Denniston45f94f82020-02-04 16:09:08 -0500404 SkColorInfo colorInfo() const override {
405 return SkColorInfo(fColorType, fAlphaType, fColorSpace);
406 }
Brian Osmanf9810662017-08-30 10:02:10 -0400407
Robert Phillips3c1efd42020-02-13 15:51:59 -0500408protected:
Brian Salomonf9b00422020-10-08 16:00:14 -0400409 sk_sp<SkSurface> createDstSurface(GrDirectContext*, SkISize size) const;
Robert Phillips3c1efd42020-02-13 15:51:59 -0500410 bool readBack(SkSurface*, SkBitmap* dst) const;
411
mtklein748ca3b2015-01-15 10:56:12 -0800412private:
csmartdaltone812d492017-02-21 12:36:05 -0700413 sk_gpu_test::GrContextFactory::ContextType fContextType;
414 sk_gpu_test::GrContextFactory::ContextOverrides fContextOverrides;
Brian Salomonf865b052018-03-09 09:01:53 -0500415 SkCommandLineConfigGpu::SurfType fSurfType;
csmartdaltone812d492017-02-21 12:36:05 -0700416 int fSampleCount;
Chris Dalton180b4a12021-03-16 20:49:15 -0600417 uint32_t fSurfaceFlags;
csmartdaltone812d492017-02-21 12:36:05 -0700418 SkColorType fColorType;
Brian Salomonce5ee602017-07-17 11:31:31 -0400419 SkAlphaType fAlphaType;
csmartdaltone812d492017-02-21 12:36:05 -0700420 sk_sp<SkColorSpace> fColorSpace;
Brian Osmanf21aa042017-08-21 16:48:46 -0400421 GrContextOptions fBaseContextOptions;
Brian Osman9c310472019-06-27 16:43:27 -0400422 sk_gpu_test::MemoryCache fMemoryCache;
mtklein748ca3b2015-01-15 10:56:12 -0800423};
424
Brian Osmanf9810662017-08-30 10:02:10 -0400425class GPUThreadTestingSink : public GPUSink {
426public:
Brian Osman3fdfe282019-09-09 13:46:52 -0400427 GPUThreadTestingSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
Brian Osmanf9810662017-08-30 10:02:10 -0400428
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500429 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Brian Osmanf9810662017-08-30 10:02:10 -0400430
Brian Osmanf1942de2017-08-30 14:50:22 -0400431 const char* fileExtension() const override {
432 // Suppress writing out results from this config - we just want to do our matching test
433 return nullptr;
434 }
435
Brian Osmanf9810662017-08-30 10:02:10 -0400436private:
437 std::unique_ptr<SkExecutor> fExecutor;
438
John Stiles7571f9e2020-09-02 22:42:33 -0400439 using INHERITED = GPUSink;
Brian Osmanf9810662017-08-30 10:02:10 -0400440};
441
Brian Salomon00a5eb82018-07-11 15:32:05 -0400442class GPUPersistentCacheTestingSink : public GPUSink {
443public:
Brian Osman3fdfe282019-09-09 13:46:52 -0400444 GPUPersistentCacheTestingSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
Brian Salomon00a5eb82018-07-11 15:32:05 -0400445
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500446 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Brian Salomon00a5eb82018-07-11 15:32:05 -0400447
448 const char* fileExtension() const override {
449 // Suppress writing out results from this config - we just want to do our matching test
450 return nullptr;
451 }
452
453private:
Brian Osmanf71b0702019-04-03 13:04:16 -0400454 int fCacheType;
455
John Stiles7571f9e2020-09-02 22:42:33 -0400456 using INHERITED = GPUSink;
Brian Salomon00a5eb82018-07-11 15:32:05 -0400457};
458
Brian Osmaned58e002019-09-06 14:42:43 -0400459class GPUPrecompileTestingSink : public GPUSink {
460public:
Brian Osman3fdfe282019-09-09 13:46:52 -0400461 GPUPrecompileTestingSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
Brian Osmaned58e002019-09-06 14:42:43 -0400462
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500463 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Brian Osmaned58e002019-09-06 14:42:43 -0400464
465 const char* fileExtension() const override {
466 // Suppress writing out results from this config - we just want to do our matching test
467 return nullptr;
468 }
469
470private:
John Stiles7571f9e2020-09-02 22:42:33 -0400471 using INHERITED = GPUSink;
Brian Osmaned58e002019-09-06 14:42:43 -0400472};
473
Robert Phillips762cb4e2020-06-15 13:12:32 -0400474// This sink attempts to emulate Chrome's OOP-R behavior. It:
475// doesn't use promise images
476// uses only a single thread for both DDL creation & drawing
477class GPUOOPRSink : public GPUSink {
478public:
479 GPUOOPRSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
480
481 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
482
483private:
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400484 Result ooprDraw(const Src&, sk_sp<SkSurface> dstSurface, GrDirectContext*) const;
Robert Phillips762cb4e2020-06-15 13:12:32 -0400485
John Stiles7571f9e2020-09-02 22:42:33 -0400486 using INHERITED = GPUSink;
Robert Phillips762cb4e2020-06-15 13:12:32 -0400487};
488
Robert Phillips291f3402020-02-19 14:14:47 -0500489// This sink attempts to better simulate the Chrome DDL use-case. It:
490// creates the DDLs on separate recording threads
491// performs all the GPU work on a separate GPU thread
492// In the future this should be expanded to:
493// upload on a utility thread w/ access to a shared context
494// compile the programs on the utility thread
495// perform fine grained scheduling of gpu tasks based on their image and program prerequisites
496// create a single "compositing" DDL that is replayed last
497class GPUDDLSink : public GPUSink {
498public:
499 GPUDDLSink(const SkCommandLineConfigGpu*, const GrContextOptions&);
500
501 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
502
503private:
504 Result ddlDraw(const Src&,
505 sk_sp<SkSurface> dstSurface,
506 SkTaskGroup* recordingTaskGroup,
507 SkTaskGroup* gpuTaskGroup,
Robert Phillips19f466d2020-02-26 10:27:07 -0500508 sk_gpu_test::TestContext* gpuTestCtx,
Robert Phillipsb87b39b2020-07-01 14:45:24 -0400509 GrDirectContext* gpuThreadCtx) const;
Robert Phillips291f3402020-02-19 14:14:47 -0500510
Robert Phillips762cb4e2020-06-15 13:12:32 -0400511 std::unique_ptr<SkExecutor> fRecordingExecutor;
512 std::unique_ptr<SkExecutor> fGPUExecutor;
Robert Phillips291f3402020-02-19 14:14:47 -0500513
John Stiles7571f9e2020-09-02 22:42:33 -0400514 using INHERITED = GPUSink;
Robert Phillips291f3402020-02-19 14:14:47 -0500515};
516
mtklein748ca3b2015-01-15 10:56:12 -0800517class PDFSink : public Sink {
518public:
Hal Canaryc7d295e2017-07-20 15:36:00 -0400519 PDFSink(bool pdfa, SkScalar rasterDpi) : fPDFA(pdfa), fRasterDpi(rasterDpi) {}
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500520 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700521 const char* fileExtension() const override { return "pdf"; }
mtklein99cab4e2015-07-31 06:43:04 -0700522 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
halcanary4b656662016-04-27 07:45:18 -0700523 bool fPDFA;
Hal Canaryc7d295e2017-07-20 15:36:00 -0400524 SkScalar fRasterDpi;
mtklein748ca3b2015-01-15 10:56:12 -0800525};
526
halcanary47ef4d52015-03-03 09:13:09 -0800527class XPSSink : public Sink {
528public:
529 XPSSink();
530
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500531 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700532 const char* fileExtension() const override { return "xps"; }
mtklein99cab4e2015-07-31 06:43:04 -0700533 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
halcanary47ef4d52015-03-03 09:13:09 -0800534};
535
mtklein748ca3b2015-01-15 10:56:12 -0800536class RasterSink : public Sink {
537public:
brianosmanb109b8c2016-06-16 13:03:24 -0700538 explicit RasterSink(SkColorType, sk_sp<SkColorSpace> = nullptr);
mtklein748ca3b2015-01-15 10:56:12 -0800539
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500540 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700541 const char* fileExtension() const override { return "png"; }
mtklein99cab4e2015-07-31 06:43:04 -0700542 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kRaster, SinkFlags::kDirect }; }
Yuqian Lib8b62532018-02-23 14:13:36 +0800543
Mike Klein48b64902018-07-25 13:28:44 -0400544private:
brianosmanb109b8c2016-06-16 13:03:24 -0700545 SkColorType fColorType;
546 sk_sp<SkColorSpace> fColorSpace;
mtklein748ca3b2015-01-15 10:56:12 -0800547};
548
Yuqian Lib8b62532018-02-23 14:13:36 +0800549class ThreadedSink : public RasterSink {
550public:
551 explicit ThreadedSink(SkColorType, sk_sp<SkColorSpace> = nullptr);
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500552 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Yuqian Lib8b62532018-02-23 14:13:36 +0800553};
554
mtklein9c3f17d2015-01-28 11:35:18 -0800555class SKPSink : public Sink {
556public:
557 SKPSink();
558
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500559 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700560 const char* fileExtension() const override { return "skp"; }
mtklein99cab4e2015-07-31 06:43:04 -0700561 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
mtklein9c3f17d2015-01-28 11:35:18 -0800562};
563
Hal Canary85c7fe82016-10-25 10:33:27 -0400564class DebugSink : public Sink {
565public:
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500566 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Hal Canary85c7fe82016-10-25 10:33:27 -0400567 const char* fileExtension() const override { return "json"; }
568 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
569};
570
mtklein8a4527e2015-01-31 20:00:58 -0800571class SVGSink : public Sink {
572public:
Bryce Thomas95a7b762018-03-02 13:54:21 -0800573 SVGSink(int pageIndex = 0);
mtklein8a4527e2015-01-31 20:00:58 -0800574
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500575 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein36352bf2015-03-25 18:17:31 -0700576 const char* fileExtension() const override { return "svg"; }
mtklein99cab4e2015-07-31 06:43:04 -0700577 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
Bryce Thomas95a7b762018-03-02 13:54:21 -0800578
579private:
580 int fPageIndex;
mtklein8a4527e2015-01-31 20:00:58 -0800581};
582
583
mtklein748ca3b2015-01-15 10:56:12 -0800584/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
585
mtklein78829242015-05-06 07:54:07 -0700586class Via : public Sink {
587public:
msarett62d3b102015-12-10 15:14:27 -0800588 explicit Via(Sink* sink) : fSink(sink) {}
mtklein78829242015-05-06 07:54:07 -0700589 const char* fileExtension() const override { return fSink->fileExtension(); }
mtklein21eaf3b2016-02-08 12:39:59 -0800590 bool serial() const override { return fSink->serial(); }
mtklein99cab4e2015-07-31 06:43:04 -0700591 SinkFlags flags() const override {
592 SinkFlags flags = fSink->flags();
593 flags.approach = SinkFlags::kIndirect;
594 return flags;
595 }
mtklein78829242015-05-06 07:54:07 -0700596protected:
Ben Wagner145dbcd2016-11-03 14:40:50 -0400597 std::unique_ptr<Sink> fSink;
mtklein78829242015-05-06 07:54:07 -0700598};
599
600class ViaMatrix : public Via {
mtklein748ca3b2015-01-15 10:56:12 -0800601public:
msarett62d3b102015-12-10 15:14:27 -0800602 ViaMatrix(SkMatrix, Sink*);
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500603 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein748ca3b2015-01-15 10:56:12 -0800604private:
mtklein78829242015-05-06 07:54:07 -0700605 const SkMatrix fMatrix;
mtklein748ca3b2015-01-15 10:56:12 -0800606};
607
mtklein78829242015-05-06 07:54:07 -0700608class ViaUpright : public Via {
mtkleind603b222015-02-17 11:13:33 -0800609public:
msarett62d3b102015-12-10 15:14:27 -0800610 ViaUpright(SkMatrix, Sink*);
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500611 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtkleind603b222015-02-17 11:13:33 -0800612private:
mtklein78829242015-05-06 07:54:07 -0700613 const SkMatrix fMatrix;
mtkleind603b222015-02-17 11:13:33 -0800614};
615
mtklein78829242015-05-06 07:54:07 -0700616class ViaSerialization : public Via {
mtklein748ca3b2015-01-15 10:56:12 -0800617public:
msarett62d3b102015-12-10 15:14:27 -0800618 explicit ViaSerialization(Sink* sink) : Via(sink) {}
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500619 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein748ca3b2015-01-15 10:56:12 -0800620};
621
mtklein4a34ecb2016-01-08 10:19:35 -0800622class ViaPicture : public Via {
623public:
624 explicit ViaPicture(Sink* sink) : Via(sink) {}
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500625 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
mtklein4a34ecb2016-01-08 10:19:35 -0800626};
627
Mike Reedf67c4592017-02-17 17:06:11 -0500628class ViaSVG : public Via {
629public:
630 explicit ViaSVG(Sink* sink) : Via(sink) {}
Ben Wagnerea25fcf2020-02-12 11:18:46 -0500631 Result draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
Mike Reedf67c4592017-02-17 17:06:11 -0500632};
633
mtklein748ca3b2015-01-15 10:56:12 -0800634} // namespace DM
635
636#endif//DMSrcSink_DEFINED