1 /*
2  * Copyright 2017 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 #include "ok.h"
9 #include "gm.h"
10 #include "SkOSFile.h"
11 #include "SkPicture.h"
12 #include <vector>
13 
14 struct GMStream : Stream {
15     const skiagm::GMRegistry* registry = skiagm::GMRegistry::Head();
16 
CreateGMStream17     static std::unique_ptr<Stream> Create(Options) {
18         GMStream stream;
19         return move_unique(stream);
20     }
21 
22     struct GMSrc : Src {
23         skiagm::GM* (*factory)(void*);
24         std::unique_ptr<skiagm::GM> gm;
25 
initGMStream::GMSrc26         void init() {
27             if (gm) { return; }
28             gm.reset(factory(nullptr));
29         }
30 
nameGMStream::GMSrc31         std::string name() override {
32             this->init();
33             return gm->getName();
34         }
35 
sizeGMStream::GMSrc36         SkISize size() override {
37             this->init();
38             return gm->getISize();
39         }
40 
drawGMStream::GMSrc41         bool draw(SkCanvas* canvas) override {
42             this->init();
43             canvas->clear(0xffffffff);
44             canvas->concat(gm->getInitialTransform());
45             gm->draw(canvas);
46             return true;
47         }
48     };
49 
nextGMStream50     std::unique_ptr<Src> next() override {
51         if (!registry) {
52             return nullptr;
53         }
54         GMSrc src;
55         src.factory = registry->factory();
56         registry = registry->next();
57         return move_unique(src);
58     }
59 };
60 static Register gm{"gm", GMStream::Create};
61 
62 struct SKPStream : Stream {
63     std::string dir;
64     std::vector<std::string> skps;
65 
CreateSKPStream66     static std::unique_ptr<Stream> Create(Options options) {
67         SKPStream stream;
68         stream.dir = options("dir", "skps");
69         SkOSFile::Iter it{stream.dir.c_str(), ".skp"};
70         for (SkString path; it.next(&path); ) {
71             stream.skps.push_back(path.c_str());
72         }
73         return move_unique(stream);
74     }
75 
76     struct SKPSrc : Src {
77         std::string dir, path;
78         sk_sp<SkPicture> pic;
79 
initSKPStream::SKPSrc80         void init() {
81             if (pic) { return; }
82             auto skp = SkData::MakeFromFileName((dir+"/"+path).c_str());
83             pic = SkPicture::MakeFromData(skp.get());
84         }
85 
nameSKPStream::SKPSrc86         std::string name() override {
87             return path;
88         }
89 
sizeSKPStream::SKPSrc90         SkISize size() override {
91             this->init();
92             return pic->cullRect().roundOut().size();
93         }
94 
drawSKPStream::SKPSrc95         bool draw(SkCanvas* canvas) override {
96             this->init();
97             canvas->clear(0xffffffff);
98             pic->playback(canvas);
99             return true;
100         }
101     };
102 
nextSKPStream103     std::unique_ptr<Src> next() override {
104         if (skps.empty()) {
105             return nullptr;
106         }
107         SKPSrc src;
108         src.dir  = dir;
109         src.path = skps.back();
110         skps.pop_back();
111         return move_unique(src);
112     }
113 };
114 static Register skp{"skp", SKPStream::Create};
115