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 "SkCanvas.h"
16#include "SkCodec.h"
17#include "SkData.h"
18#include "SkGPipe.h"
19#include "SkPicture.h"
20#include "gm.h"
21
22namespace DM {
23
24// This is just convenience.  It lets you use either return "foo" or return SkStringPrintf(...).
25struct ImplicitString : public SkString {
26    template <typename T>
27    ImplicitString(const T& s) : SkString(s) {}
28};
29typedef ImplicitString Name;
30typedef ImplicitString Path;
31
32class Error {
33public:
34    Error(const SkString& s) : fMsg(s), fFatal(!this->isEmpty()) {}
35    Error(const char* s)     : fMsg(s), fFatal(!this->isEmpty()) {}
36
37    Error(const Error&)            = default;
38    Error& operator=(const Error&) = default;
39
40    static Error Nonfatal(const SkString& s) { return Nonfatal(s.c_str()); }
41    static Error Nonfatal(const char* s) {
42        Error e(s);
43        e.fFatal = false;
44        return e;
45    }
46
47    const char* c_str() const { return fMsg.c_str(); }
48    bool isEmpty() const { return fMsg.isEmpty(); }
49    bool isFatal() const { return fFatal; }
50
51private:
52    SkString fMsg;
53    bool     fFatal;
54};
55
56struct Src {
57    // All Srcs must be thread safe.
58    virtual ~Src() {}
59    virtual Error SK_WARN_UNUSED_RESULT draw(SkCanvas*) const = 0;
60    virtual SkISize size() const = 0;
61    virtual Name name() const = 0;
62};
63
64struct Sink {
65    virtual ~Sink() {}
66    // You may write to either the bitmap or stream.  If you write to log, we'll print that out.
67    virtual Error SK_WARN_UNUSED_RESULT draw(const Src&, SkBitmap*, SkWStream*, SkString* log)
68        const = 0;
69    // Sinks in the same enclave (except kAnyThread_Enclave) will run serially on the same thread.
70    virtual int enclave() const = 0;
71
72    // File extension for the content draw() outputs, e.g. "png", "pdf".
73    virtual const char* fileExtension() const  = 0;
74};
75
76enum { kAnyThread_Enclave, kGPU_Enclave };
77static const int kNumEnclaves = kGPU_Enclave + 1;
78
79/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
80
81class GMSrc : public Src {
82public:
83    explicit GMSrc(skiagm::GMRegistry::Factory);
84
85    Error draw(SkCanvas*) const override;
86    SkISize size() const override;
87    Name name() const override;
88private:
89    skiagm::GMRegistry::Factory fFactory;
90};
91
92class CodecSrc : public Src {
93public:
94    enum Mode {
95        kNormal_Mode,
96        kScanline_Mode,
97    };
98    enum DstColorType {
99        kGetFromCanvas_DstColorType,
100        kIndex8_Always_DstColorType,
101        kGrayscale_Always_DstColorType,
102    };
103    CodecSrc(Path, Mode, DstColorType);
104
105    Error draw(SkCanvas*) const override;
106    SkISize size() const override;
107    Name name() const override;
108private:
109    Path                   fPath;
110    Mode                   fMode;
111    DstColorType           fDstColorType;
112};
113
114
115class ImageSrc : public Src {
116public:
117    // divisor == 0 means decode the whole image
118    // divisor > 0 means decode in subsets, dividing into a divisor x divisor grid.
119    explicit ImageSrc(Path path, int divisor = 0);
120
121    Error draw(SkCanvas*) const override;
122    SkISize size() const override;
123    Name name() const override;
124private:
125    Path fPath;
126    const int  fDivisor;
127};
128
129class SKPSrc : public Src {
130public:
131    explicit SKPSrc(Path path);
132
133    Error draw(SkCanvas*) const override;
134    SkISize size() const override;
135    Name name() const override;
136private:
137    Path fPath;
138};
139
140/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
141
142class NullSink : public Sink {
143public:
144    NullSink() {}
145
146    Error draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const override;
147    int enclave() const override { return kAnyThread_Enclave; }
148    const char* fileExtension() const override { return ""; }
149};
150
151
152class GPUSink : public Sink {
153public:
154    GPUSink(GrContextFactory::GLContextType, GrGLStandard, int samples, bool dfText, bool threaded);
155
156    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
157    int enclave() const override;
158    const char* fileExtension() const override { return "png"; }
159private:
160    GrContextFactory::GLContextType fContextType;
161    GrGLStandard                    fGpuAPI;
162    int                             fSampleCount;
163    bool                            fUseDFText;
164    bool                            fThreaded;
165};
166
167class PDFSink : public Sink {
168public:
169    PDFSink();
170
171    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
172    int enclave() const override { return kAnyThread_Enclave; }
173    const char* fileExtension() const override { return "pdf"; }
174};
175
176class XPSSink : public Sink {
177public:
178    XPSSink();
179
180    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
181    int enclave() const override { return kAnyThread_Enclave; }
182    const char* fileExtension() const override { return "xps"; }
183};
184
185class RasterSink : public Sink {
186public:
187    explicit RasterSink(SkColorType);
188
189    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
190    int enclave() const override { return kAnyThread_Enclave; }
191    const char* fileExtension() const override { return "png"; }
192private:
193    SkColorType    fColorType;
194};
195
196class SKPSink : public Sink {
197public:
198    SKPSink();
199
200    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
201    int enclave() const override { return kAnyThread_Enclave; }
202    const char* fileExtension() const override { return "skp"; }
203};
204
205class SVGSink : public Sink {
206public:
207    SVGSink();
208
209    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
210    int enclave() const override { return kAnyThread_Enclave; }
211    const char* fileExtension() const override { return "svg"; }
212};
213
214
215/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
216
217class Via : public Sink {
218public:
219    explicit Via(Sink* sink) : fSink(sink) {}
220    const char* fileExtension() const override { return fSink->fileExtension(); }
221    int               enclave() const override { return fSink->enclave(); }
222protected:
223    SkAutoTDelete<Sink> fSink;
224};
225
226class ViaMatrix : public Via {
227public:
228    ViaMatrix(SkMatrix, Sink*);
229    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
230private:
231    const SkMatrix fMatrix;
232};
233
234class ViaUpright : public Via {
235public:
236    ViaUpright(SkMatrix, Sink*);
237    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
238private:
239    const SkMatrix fMatrix;
240};
241
242class ViaPipe : public Via {
243public:
244    explicit ViaPipe(Sink* sink) : Via(sink) {}
245    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
246};
247
248class ViaDeferred : public Via {
249public:
250    explicit ViaDeferred(Sink* sink) : Via(sink) {}
251    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
252};
253
254class ViaSerialization : public Via {
255public:
256    explicit ViaSerialization(Sink* sink) : Via(sink) {}
257    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
258};
259
260class ViaTiles : public Via {
261public:
262    ViaTiles(int w, int h, SkBBHFactory*, Sink*);
263    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
264private:
265    const int                   fW, fH;
266    SkAutoTDelete<SkBBHFactory> fFactory;
267};
268
269class ViaSecondPicture : public Via {
270public:
271    explicit ViaSecondPicture(Sink* sink) : Via(sink) {}
272    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
273};
274
275class ViaSingletonPictures : public Via {
276public:
277    explicit ViaSingletonPictures(Sink* sink) : Via(sink) {}
278    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
279};
280
281class ViaTwice : public Via {
282public:
283    explicit ViaTwice(Sink* sink) : Via(sink) {}
284    Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
285};
286
287}  // namespace DM
288
289#endif//DMSrcSink_DEFINED
290