DMSrcSink.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*
  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. #ifndef DMSrcSink_DEFINED
  8. #define DMSrcSink_DEFINED
  9. #include "gm/gm.h"
  10. #include "include/android/SkBitmapRegionDecoder.h"
  11. #include "include/core/SkBBHFactory.h"
  12. #include "include/core/SkBitmap.h"
  13. #include "include/core/SkCanvas.h"
  14. #include "include/core/SkData.h"
  15. #include "include/core/SkPicture.h"
  16. #include "src/core/SkBBoxHierarchy.h"
  17. #include "src/utils/SkMultiPictureDocument.h"
  18. #include "tools/flags/CommonFlagsConfig.h"
  19. #include "tools/gpu/MemoryCache.h"
  20. //#define TEST_VIA_SVG
  21. namespace DM {
  22. // This is just convenience. It lets you use either return "foo" or return SkStringPrintf(...).
  23. struct ImplicitString : public SkString {
  24. template <typename T>
  25. ImplicitString(const T& s) : SkString(s) {}
  26. ImplicitString() : SkString("") {}
  27. };
  28. typedef ImplicitString Name;
  29. typedef ImplicitString Path;
  30. class Error {
  31. public:
  32. Error(const SkString& s) : fMsg(s), fFatal(!this->isEmpty()) {}
  33. Error(const char* s) : fMsg(s), fFatal(!this->isEmpty()) {}
  34. Error(const Error&) = default;
  35. Error& operator=(const Error&) = default;
  36. static Error Nonfatal(const SkString& s) { return Nonfatal(s.c_str()); }
  37. static Error Nonfatal(const char* s) {
  38. Error e(s);
  39. e.fFatal = false;
  40. return e;
  41. }
  42. const char* c_str() const { return fMsg.c_str(); }
  43. bool isEmpty() const { return fMsg.isEmpty(); }
  44. bool isFatal() const { return fFatal; }
  45. private:
  46. SkString fMsg;
  47. bool fFatal;
  48. };
  49. struct SinkFlags {
  50. enum Type { kNull, kGPU, kVector, kRaster } type;
  51. enum Approach { kDirect, kIndirect } approach;
  52. enum Multisampled { kNotMultisampled, kMultisampled } multisampled;
  53. SinkFlags(Type t, Approach a, Multisampled ms = kNotMultisampled)
  54. : type(t), approach(a), multisampled(ms) {}
  55. };
  56. struct Src {
  57. virtual ~Src() {}
  58. virtual Error SK_WARN_UNUSED_RESULT draw(SkCanvas*) const = 0;
  59. virtual SkISize size() const = 0;
  60. virtual Name name() const = 0;
  61. virtual void modifyGrContextOptions(GrContextOptions* options) const {}
  62. virtual bool veto(SinkFlags) const { return false; }
  63. virtual int pageCount() const { return 1; }
  64. virtual Error SK_WARN_UNUSED_RESULT draw(int, SkCanvas* canvas) const {
  65. return this->draw(canvas);
  66. }
  67. virtual SkISize size(int) const { return this->size(); }
  68. // Force Tasks using this Src to run on the main thread?
  69. virtual bool serial() const { return false; }
  70. };
  71. struct Sink {
  72. virtual ~Sink() {}
  73. // You may write to either the bitmap or stream. If you write to log, we'll print that out.
  74. virtual Error SK_WARN_UNUSED_RESULT draw(const Src&, SkBitmap*, SkWStream*, SkString* log)
  75. const = 0;
  76. // Force Tasks using this Sink to run on the main thread?
  77. virtual bool serial() const { return false; }
  78. // File extension for the content draw() outputs, e.g. "png", "pdf".
  79. virtual const char* fileExtension() const = 0;
  80. virtual SinkFlags flags() const = 0;
  81. };
  82. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  83. class GMSrc : public Src {
  84. public:
  85. explicit GMSrc(skiagm::GMFactory);
  86. Error draw(SkCanvas*) const override;
  87. SkISize size() const override;
  88. Name name() const override;
  89. void modifyGrContextOptions(GrContextOptions* options) const override;
  90. private:
  91. skiagm::GMFactory fFactory;
  92. };
  93. class CodecSrc : public Src {
  94. public:
  95. enum Mode {
  96. kCodec_Mode,
  97. // We choose to test only one mode with zero initialized memory.
  98. // This will exercise all of the interesting cases in SkSwizzler
  99. // without doubling the size of our test suite.
  100. kCodecZeroInit_Mode,
  101. kScanline_Mode,
  102. kStripe_Mode, // Tests the skipping of scanlines
  103. kCroppedScanline_Mode, // Tests (jpeg) cropped scanline optimization
  104. kSubset_Mode, // For codecs that support subsets directly.
  105. kAnimated_Mode, // For codecs that support animation.
  106. };
  107. enum DstColorType {
  108. kGetFromCanvas_DstColorType,
  109. kGrayscale_Always_DstColorType,
  110. kNonNative8888_Always_DstColorType,
  111. };
  112. CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);
  113. Error draw(SkCanvas*) const override;
  114. SkISize size() const override;
  115. Name name() const override;
  116. bool veto(SinkFlags) const override;
  117. bool serial() const override { return fRunSerially; }
  118. private:
  119. Path fPath;
  120. Mode fMode;
  121. DstColorType fDstColorType;
  122. SkAlphaType fDstAlphaType;
  123. float fScale;
  124. bool fRunSerially;
  125. };
  126. class AndroidCodecSrc : public Src {
  127. public:
  128. AndroidCodecSrc(Path, CodecSrc::DstColorType, SkAlphaType, int sampleSize);
  129. Error draw(SkCanvas*) const override;
  130. SkISize size() const override;
  131. Name name() const override;
  132. bool veto(SinkFlags) const override;
  133. bool serial() const override { return fRunSerially; }
  134. private:
  135. Path fPath;
  136. CodecSrc::DstColorType fDstColorType;
  137. SkAlphaType fDstAlphaType;
  138. int fSampleSize;
  139. bool fRunSerially;
  140. };
  141. // Allows for testing of various implementations of Android's BitmapRegionDecoder
  142. class BRDSrc : public Src {
  143. public:
  144. enum Mode {
  145. // Decode the entire image as one region.
  146. kFullImage_Mode,
  147. // Splits the image into multiple regions using a divisor and decodes the regions
  148. // separately. Also, this test adds a border of a few pixels to each of the regions
  149. // that it is decoding. This tests the behavior when a client asks for a region that
  150. // does not fully fit in the image.
  151. kDivisor_Mode,
  152. };
  153. BRDSrc(Path, Mode, CodecSrc::DstColorType, uint32_t);
  154. Error draw(SkCanvas*) const override;
  155. SkISize size() const override;
  156. Name name() const override;
  157. bool veto(SinkFlags) const override;
  158. private:
  159. Path fPath;
  160. Mode fMode;
  161. CodecSrc::DstColorType fDstColorType;
  162. uint32_t fSampleSize;
  163. };
  164. class ImageGenSrc : public Src {
  165. public:
  166. enum Mode {
  167. kCodec_Mode, // Use CodecImageGenerator
  168. kPlatform_Mode, // Uses CG or WIC
  169. };
  170. ImageGenSrc(Path, Mode, SkAlphaType, bool);
  171. Error draw(SkCanvas*) const override;
  172. SkISize size() const override;
  173. Name name() const override;
  174. bool veto(SinkFlags) const override;
  175. bool serial() const override { return fRunSerially; }
  176. private:
  177. Path fPath;
  178. Mode fMode;
  179. SkAlphaType fDstAlphaType;
  180. bool fIsGpu;
  181. bool fRunSerially;
  182. };
  183. class ColorCodecSrc : public Src {
  184. public:
  185. ColorCodecSrc(Path, bool decode_to_dst);
  186. Error draw(SkCanvas*) const override;
  187. SkISize size() const override;
  188. Name name() const override;
  189. bool veto(SinkFlags) const override;
  190. private:
  191. Path fPath;
  192. bool fDecodeToDst;
  193. };
  194. class SKPSrc : public Src {
  195. public:
  196. explicit SKPSrc(Path path);
  197. Error draw(SkCanvas*) const override;
  198. SkISize size() const override;
  199. Name name() const override;
  200. private:
  201. Path fPath;
  202. };
  203. // This class extracts all the paths from an SKP and then removes unwanted paths according to the
  204. // provided l/r trail. It then just draws the remaining paths. (Non-path draws are thrown out.) It
  205. // is useful for finding a reduced repo case for path drawing bugs.
  206. class BisectSrc : public SKPSrc {
  207. public:
  208. explicit BisectSrc(Path path, const char* trail);
  209. Error draw(SkCanvas*) const override;
  210. private:
  211. SkString fTrail;
  212. typedef SKPSrc INHERITED;
  213. };
  214. #if defined(SK_ENABLE_SKOTTIE)
  215. class SkottieSrc final : public Src {
  216. public:
  217. explicit SkottieSrc(Path path);
  218. Error draw(SkCanvas*) const override;
  219. SkISize size() const override;
  220. Name name() const override;
  221. bool veto(SinkFlags) const override;
  222. private:
  223. // Generates a kTileCount x kTileCount filmstrip with evenly distributed frames.
  224. static constexpr int kTileCount = 5;
  225. // Fit kTileCount x kTileCount frames to a 1000x1000 film strip.
  226. static constexpr SkScalar kTargetSize = 1000;
  227. static constexpr SkScalar kTileSize = kTargetSize / kTileCount;
  228. Path fPath;
  229. };
  230. #endif
  231. #if defined(SK_XML)
  232. } // namespace DM
  233. class SkSVGDOM;
  234. namespace DM {
  235. class SVGSrc : public Src {
  236. public:
  237. explicit SVGSrc(Path path);
  238. Error draw(SkCanvas*) const override;
  239. SkISize size() const override;
  240. Name name() const override;
  241. bool veto(SinkFlags) const override;
  242. private:
  243. Name fName;
  244. sk_sp<SkSVGDOM> fDom;
  245. SkScalar fScale;
  246. typedef Src INHERITED;
  247. };
  248. #endif // SK_XML
  249. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  250. class MSKPSrc : public Src {
  251. public:
  252. explicit MSKPSrc(Path path);
  253. int pageCount() const override;
  254. Error draw(SkCanvas* c) const override;
  255. Error draw(int, SkCanvas*) const override;
  256. SkISize size() const override;
  257. SkISize size(int) const override;
  258. Name name() const override;
  259. private:
  260. Path fPath;
  261. mutable SkTArray<SkDocumentPage> fPages;
  262. };
  263. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  264. class NullSink : public Sink {
  265. public:
  266. NullSink() {}
  267. Error draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const override;
  268. const char* fileExtension() const override { return ""; }
  269. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kNull, SinkFlags::kDirect }; }
  270. };
  271. class GPUSink : public Sink {
  272. public:
  273. GPUSink(sk_gpu_test::GrContextFactory::ContextType,
  274. sk_gpu_test::GrContextFactory::ContextOverrides,
  275. SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText,
  276. SkColorType colorType, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace,
  277. bool threaded, const GrContextOptions& grCtxOptions);
  278. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  279. Error onDraw(const Src&, SkBitmap*, SkWStream*, SkString*,
  280. const GrContextOptions& baseOptions) const;
  281. sk_gpu_test::GrContextFactory::ContextType contextType() const { return fContextType; }
  282. const sk_gpu_test::GrContextFactory::ContextOverrides& contextOverrides() {
  283. return fContextOverrides;
  284. }
  285. SkCommandLineConfigGpu::SurfType surfType() const { return fSurfType; }
  286. bool useDIText() const { return fUseDIText; }
  287. bool serial() const override { return !fThreaded; }
  288. const char* fileExtension() const override { return "png"; }
  289. SinkFlags flags() const override {
  290. SinkFlags::Multisampled ms = fSampleCount > 1 ? SinkFlags::kMultisampled
  291. : SinkFlags::kNotMultisampled;
  292. return SinkFlags{ SinkFlags::kGPU, SinkFlags::kDirect, ms };
  293. }
  294. const GrContextOptions& baseContextOptions() const { return fBaseContextOptions; }
  295. private:
  296. sk_gpu_test::GrContextFactory::ContextType fContextType;
  297. sk_gpu_test::GrContextFactory::ContextOverrides fContextOverrides;
  298. SkCommandLineConfigGpu::SurfType fSurfType;
  299. int fSampleCount;
  300. bool fUseDIText;
  301. SkColorType fColorType;
  302. SkAlphaType fAlphaType;
  303. sk_sp<SkColorSpace> fColorSpace;
  304. bool fThreaded;
  305. GrContextOptions fBaseContextOptions;
  306. sk_gpu_test::MemoryCache fMemoryCache;
  307. };
  308. class GPUThreadTestingSink : public GPUSink {
  309. public:
  310. GPUThreadTestingSink(sk_gpu_test::GrContextFactory::ContextType,
  311. sk_gpu_test::GrContextFactory::ContextOverrides,
  312. SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText,
  313. SkColorType colorType, SkAlphaType alphaType,
  314. sk_sp<SkColorSpace> colorSpace, bool threaded,
  315. const GrContextOptions& grCtxOptions);
  316. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  317. const char* fileExtension() const override {
  318. // Suppress writing out results from this config - we just want to do our matching test
  319. return nullptr;
  320. }
  321. private:
  322. std::unique_ptr<SkExecutor> fExecutor;
  323. typedef GPUSink INHERITED;
  324. };
  325. class GPUPersistentCacheTestingSink : public GPUSink {
  326. public:
  327. GPUPersistentCacheTestingSink(sk_gpu_test::GrContextFactory::ContextType,
  328. sk_gpu_test::GrContextFactory::ContextOverrides,
  329. SkCommandLineConfigGpu::SurfType surfType, int samples,
  330. bool diText, SkColorType colorType, SkAlphaType alphaType,
  331. sk_sp<SkColorSpace> colorSpace, bool threaded,
  332. const GrContextOptions& grCtxOptions,
  333. int cacheType);
  334. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  335. const char* fileExtension() const override {
  336. // Suppress writing out results from this config - we just want to do our matching test
  337. return nullptr;
  338. }
  339. private:
  340. int fCacheType;
  341. typedef GPUSink INHERITED;
  342. };
  343. class PDFSink : public Sink {
  344. public:
  345. PDFSink(bool pdfa, SkScalar rasterDpi) : fPDFA(pdfa), fRasterDpi(rasterDpi) {}
  346. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  347. const char* fileExtension() const override { return "pdf"; }
  348. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
  349. bool fPDFA;
  350. SkScalar fRasterDpi;
  351. };
  352. class XPSSink : public Sink {
  353. public:
  354. XPSSink();
  355. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  356. const char* fileExtension() const override { return "xps"; }
  357. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
  358. };
  359. class RasterSink : public Sink {
  360. public:
  361. explicit RasterSink(SkColorType, sk_sp<SkColorSpace> = nullptr);
  362. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  363. const char* fileExtension() const override { return "png"; }
  364. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kRaster, SinkFlags::kDirect }; }
  365. private:
  366. SkColorType fColorType;
  367. sk_sp<SkColorSpace> fColorSpace;
  368. };
  369. class ThreadedSink : public RasterSink {
  370. public:
  371. explicit ThreadedSink(SkColorType, sk_sp<SkColorSpace> = nullptr);
  372. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  373. };
  374. class SKPSink : public Sink {
  375. public:
  376. SKPSink();
  377. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  378. const char* fileExtension() const override { return "skp"; }
  379. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
  380. };
  381. class DebugSink : public Sink {
  382. public:
  383. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  384. const char* fileExtension() const override { return "json"; }
  385. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
  386. };
  387. class SVGSink : public Sink {
  388. public:
  389. SVGSink(int pageIndex = 0);
  390. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  391. const char* fileExtension() const override { return "svg"; }
  392. SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; }
  393. private:
  394. int fPageIndex;
  395. };
  396. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  397. class Via : public Sink {
  398. public:
  399. explicit Via(Sink* sink) : fSink(sink) {}
  400. const char* fileExtension() const override { return fSink->fileExtension(); }
  401. bool serial() const override { return fSink->serial(); }
  402. SinkFlags flags() const override {
  403. SinkFlags flags = fSink->flags();
  404. flags.approach = SinkFlags::kIndirect;
  405. return flags;
  406. }
  407. protected:
  408. std::unique_ptr<Sink> fSink;
  409. };
  410. class ViaMatrix : public Via {
  411. public:
  412. ViaMatrix(SkMatrix, Sink*);
  413. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  414. private:
  415. const SkMatrix fMatrix;
  416. };
  417. class ViaUpright : public Via {
  418. public:
  419. ViaUpright(SkMatrix, Sink*);
  420. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  421. private:
  422. const SkMatrix fMatrix;
  423. };
  424. class ViaSerialization : public Via {
  425. public:
  426. explicit ViaSerialization(Sink* sink) : Via(sink) {}
  427. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  428. };
  429. class ViaPicture : public Via {
  430. public:
  431. explicit ViaPicture(Sink* sink) : Via(sink) {}
  432. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  433. };
  434. class ViaTiles : public Via {
  435. public:
  436. ViaTiles(int w, int h, SkBBHFactory*, Sink*);
  437. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  438. private:
  439. const int fW, fH;
  440. std::unique_ptr<SkBBHFactory> fFactory;
  441. };
  442. class ViaDDL : public Via {
  443. public:
  444. ViaDDL(int numReplays, int numDivisions, Sink* sink);
  445. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  446. private:
  447. const int fNumReplays;
  448. const int fNumDivisions;
  449. };
  450. class ViaSVG : public Via {
  451. public:
  452. explicit ViaSVG(Sink* sink) : Via(sink) {}
  453. Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
  454. };
  455. } // namespace DM
  456. #endif//DMSrcSink_DEFINED