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 8 #ifndef DMSrcSink_DEFINED 9 #define DMSrcSink_DEFINED 10 11 #include "DMGpuSupport.h" 12 #include "SkBBHFactory.h" 13 #include "SkBBoxHierarchy.h" 14 #include "SkBitmap.h" 15 #include "SkBitmapRegionDecoder.h" 16 #include "SkCanvas.h" 17 #include "SkData.h" 18 #include "SkPicture.h" 19 #include "gm.h" 20 21 namespace DM { 22 23 // This is just convenience. It lets you use either return "foo" or return SkStringPrintf(...). 24 struct ImplicitString : public SkString { 25 template <typename T> ImplicitStringImplicitString26 ImplicitString(const T& s) : SkString(s) {} ImplicitStringImplicitString27 ImplicitString() : SkString("") {} 28 }; 29 typedef ImplicitString Name; 30 typedef ImplicitString Path; 31 32 class Error { 33 public: Error(const SkString & s)34 Error(const SkString& s) : fMsg(s), fFatal(!this->isEmpty()) {} Error(const char * s)35 Error(const char* s) : fMsg(s), fFatal(!this->isEmpty()) {} 36 37 Error(const Error&) = default; 38 Error& operator=(const Error&) = default; 39 Nonfatal(const SkString & s)40 static Error Nonfatal(const SkString& s) { return Nonfatal(s.c_str()); } Nonfatal(const char * s)41 static Error Nonfatal(const char* s) { 42 Error e(s); 43 e.fFatal = false; 44 return e; 45 } 46 c_str()47 const char* c_str() const { return fMsg.c_str(); } isEmpty()48 bool isEmpty() const { return fMsg.isEmpty(); } isFatal()49 bool isFatal() const { return fFatal; } 50 51 private: 52 SkString fMsg; 53 bool fFatal; 54 }; 55 56 struct SinkFlags { 57 enum { kNull, kGPU, kVector, kRaster } type; 58 enum { kDirect, kIndirect } approach; 59 }; 60 61 struct Src { ~SrcSrc62 virtual ~Src() {} 63 virtual Error SK_WARN_UNUSED_RESULT draw(SkCanvas*) const = 0; 64 virtual SkISize size() const = 0; 65 virtual Name name() const = 0; modifyGrContextOptionsSrc66 virtual void modifyGrContextOptions(GrContextOptions* options) const {} vetoSrc67 virtual bool veto(SinkFlags) const { return false; } 68 69 // Force Tasks using this Src to run on the main thread? serialSrc70 virtual bool serial() const { return false; } 71 }; 72 73 struct Sink { ~SinkSink74 virtual ~Sink() {} 75 // You may write to either the bitmap or stream. If you write to log, we'll print that out. 76 virtual Error SK_WARN_UNUSED_RESULT draw(const Src&, SkBitmap*, SkWStream*, SkString* log) 77 const = 0; 78 79 // Force Tasks using this Sink to run on the main thread? serialSink80 virtual bool serial() const { return false; } 81 82 // File extension for the content draw() outputs, e.g. "png", "pdf". 83 virtual const char* fileExtension() const = 0; 84 85 virtual SinkFlags flags() const = 0; 86 }; 87 88 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 89 90 class GMSrc : public Src { 91 public: 92 explicit GMSrc(skiagm::GMRegistry::Factory); 93 94 Error draw(SkCanvas*) const override; 95 SkISize size() const override; 96 Name name() const override; 97 void modifyGrContextOptions(GrContextOptions* options) const override; 98 99 private: 100 skiagm::GMRegistry::Factory fFactory; 101 }; 102 103 class CodecSrc : public Src { 104 public: 105 enum Mode { 106 kCodec_Mode, 107 // We choose to test only one mode with zero initialized memory. 108 // This will exercise all of the interesting cases in SkSwizzler 109 // without doubling the size of our test suite. 110 kCodecZeroInit_Mode, 111 kScanline_Mode, 112 kStripe_Mode, // Tests the skipping of scanlines 113 kCroppedScanline_Mode, // Tests (jpeg) cropped scanline optimization 114 kSubset_Mode, // For codecs that support subsets directly. 115 kGen_Mode, // Test SkCodecImageGenerator (includes YUV) 116 }; 117 enum DstColorType { 118 kGetFromCanvas_DstColorType, 119 kIndex8_Always_DstColorType, 120 kGrayscale_Always_DstColorType, 121 }; 122 CodecSrc(Path, Mode, DstColorType, SkAlphaType, float); 123 124 Error draw(SkCanvas*) const override; 125 SkISize size() const override; 126 Name name() const override; veto(SinkFlags)127 bool veto(SinkFlags) const override; 128 bool serial() const override { return fRunSerially; } 129 private: 130 Path fPath; 131 Mode fMode; 132 DstColorType fDstColorType; 133 SkAlphaType fDstAlphaType; 134 float fScale; 135 bool fRunSerially; 136 }; 137 138 class AndroidCodecSrc : public Src { 139 public: 140 enum Mode { 141 kFullImage_Mode, 142 // Splits the image into multiple subsets using a divisor and decodes the subsets 143 // separately. 144 kDivisor_Mode, 145 }; 146 147 AndroidCodecSrc(Path, Mode, CodecSrc::DstColorType, SkAlphaType, int sampleSize); 148 149 Error draw(SkCanvas*) const override; 150 SkISize size() const override; 151 Name name() const override; veto(SinkFlags)152 bool veto(SinkFlags) const override; 153 bool serial() const override { return fRunSerially; } 154 private: 155 Path fPath; 156 Mode fMode; 157 CodecSrc::DstColorType fDstColorType; 158 SkAlphaType fDstAlphaType; 159 int fSampleSize; 160 bool fRunSerially; 161 }; 162 163 // Allows for testing of various implementations of Android's BitmapRegionDecoder 164 class BRDSrc : public Src { 165 public: 166 enum Mode { 167 // Decode the entire image as one region. 168 kFullImage_Mode, 169 // Splits the image into multiple regions using a divisor and decodes the regions 170 // separately. Also, this test adds a border of a few pixels to each of the regions 171 // that it is decoding. This tests the behavior when a client asks for a region that 172 // does not fully fit in the image. 173 kDivisor_Mode, 174 }; 175 176 BRDSrc(Path, SkBitmapRegionDecoder::Strategy, Mode, CodecSrc::DstColorType, uint32_t); 177 178 Error draw(SkCanvas*) const override; 179 SkISize size() const override; 180 Name name() const override; 181 bool veto(SinkFlags) const override; 182 private: 183 Path fPath; 184 SkBitmapRegionDecoder::Strategy fStrategy; 185 Mode fMode; 186 CodecSrc::DstColorType fDstColorType; 187 uint32_t fSampleSize; 188 }; 189 190 class SKPSrc : public Src { 191 public: 192 explicit SKPSrc(Path path); 193 194 Error draw(SkCanvas*) const override; 195 SkISize size() const override; 196 Name name() const override; 197 private: 198 Path fPath; 199 }; 200 201 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 202 203 class NullSink : public Sink { 204 public: NullSink()205 NullSink() {} 206 207 Error draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()208 const char* fileExtension() const override { return ""; } flags()209 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kNull, SinkFlags::kDirect }; } 210 }; 211 212 213 class GPUSink : public Sink { 214 public: 215 GPUSink(GrContextFactory::GLContextType, GrContextFactory::GLContextOptions, 216 int samples, bool diText, bool threaded); 217 218 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; serial()219 bool serial() const override { return !fThreaded; } fileExtension()220 const char* fileExtension() const override { return "png"; } flags()221 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kGPU, SinkFlags::kDirect }; } 222 private: 223 GrContextFactory::GLContextType fContextType; 224 GrContextFactory::GLContextOptions fContextOptions; 225 int fSampleCount; 226 bool fUseDIText; 227 bool fThreaded; 228 }; 229 230 class PDFSink : public Sink { 231 public: 232 PDFSink(const char* rasterizer); 233 234 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()235 const char* fileExtension() const override { return "pdf"; } flags()236 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; } 237 private: 238 const char* fRasterizer; 239 }; 240 241 class XPSSink : public Sink { 242 public: 243 XPSSink(); 244 245 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()246 const char* fileExtension() const override { return "xps"; } flags()247 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; } 248 }; 249 250 class RasterSink : public Sink { 251 public: 252 explicit RasterSink(SkColorType); 253 254 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()255 const char* fileExtension() const override { return "png"; } flags()256 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kRaster, SinkFlags::kDirect }; } 257 private: 258 SkColorType fColorType; 259 }; 260 261 class SKPSink : public Sink { 262 public: 263 SKPSink(); 264 265 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()266 const char* fileExtension() const override { return "skp"; } flags()267 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; } 268 }; 269 270 class SVGSink : public Sink { 271 public: 272 SVGSink(); 273 274 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; fileExtension()275 const char* fileExtension() const override { return "svg"; } flags()276 SinkFlags flags() const override { return SinkFlags{ SinkFlags::kVector, SinkFlags::kDirect }; } 277 }; 278 279 280 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 281 282 class Via : public Sink { 283 public: Via(Sink * sink)284 explicit Via(Sink* sink) : fSink(sink) {} fileExtension()285 const char* fileExtension() const override { return fSink->fileExtension(); } serial()286 bool serial() const override { return fSink->serial(); } flags()287 SinkFlags flags() const override { 288 SinkFlags flags = fSink->flags(); 289 flags.approach = SinkFlags::kIndirect; 290 return flags; 291 } 292 protected: 293 SkAutoTDelete<Sink> fSink; 294 }; 295 296 class ViaMatrix : public Via { 297 public: 298 ViaMatrix(SkMatrix, Sink*); 299 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 300 private: 301 const SkMatrix fMatrix; 302 }; 303 304 class ViaUpright : public Via { 305 public: 306 ViaUpright(SkMatrix, Sink*); 307 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 308 private: 309 const SkMatrix fMatrix; 310 }; 311 312 class ViaRemote : public Via { 313 public: ViaRemote(bool cache,Sink * sink)314 ViaRemote(bool cache, Sink* sink) : Via(sink), fCache(cache) {} 315 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 316 private: 317 bool fCache; 318 }; 319 320 class ViaSerialization : public Via { 321 public: ViaSerialization(Sink * sink)322 explicit ViaSerialization(Sink* sink) : Via(sink) {} 323 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 324 }; 325 326 class ViaPicture : public Via { 327 public: ViaPicture(Sink * sink)328 explicit ViaPicture(Sink* sink) : Via(sink) {} 329 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 330 }; 331 332 class ViaTiles : public Via { 333 public: 334 ViaTiles(int w, int h, SkBBHFactory*, Sink*); 335 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 336 private: 337 const int fW, fH; 338 SkAutoTDelete<SkBBHFactory> fFactory; 339 }; 340 341 class ViaSecondPicture : public Via { 342 public: ViaSecondPicture(Sink * sink)343 explicit ViaSecondPicture(Sink* sink) : Via(sink) {} 344 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 345 }; 346 347 class ViaSingletonPictures : public Via { 348 public: ViaSingletonPictures(Sink * sink)349 explicit ViaSingletonPictures(Sink* sink) : Via(sink) {} 350 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 351 }; 352 353 class ViaTwice : public Via { 354 public: ViaTwice(Sink * sink)355 explicit ViaTwice(Sink* sink) : Via(sink) {} 356 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 357 }; 358 359 class ViaMojo : public Via { 360 public: ViaMojo(Sink * sink)361 explicit ViaMojo(Sink* sink) : Via(sink) {} 362 Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; 363 }; 364 365 } // namespace DM 366 367 #endif//DMSrcSink_DEFINED 368