OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 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 "GrCaps.h" | |
9 #include "GrContextFactory.h" | |
10 #include "SkCanvas.h" | |
11 #include "SkCommandLineFlags.h" | |
12 #include "SkOSFile.h" | |
13 #include <SkPicture.h> | |
14 #include "SkStream.h" | |
15 #include "SkSurface.h" | |
16 | |
17 // temporary junk | |
18 #include "SkGradientShader.h" | |
19 | |
20 #include <stdio.h> | |
21 #include <sys/types.h> | |
22 #include <sys/select.h> | |
23 #include <sys/stat.h> | |
24 #include <sys/socket.h> | |
25 #include <fcntl.h> | |
26 #include <microhttpd.h> | |
27 | |
28 // To get image decoders linked in we have to do the below magic | |
29 #include "SkForceLinking.h" | |
30 #include "SkImageDecoder.h" | |
31 __SK_FORCE_IMAGE_DECODER_LINKING; | |
32 | |
33 // TODO make this configurable | |
34 #define PORT 8888 | |
35 | |
36 DEFINE_string(dir, "skps", "Directory to read skp."); | |
37 DEFINE_string(name, "desk_carsvg", "skp to load."); | |
38 DEFINE_bool(useTemplate, true, "whether or not to use the skdebugger template st ring."); | |
39 | |
40 // TODO probably want to make this configurable | |
41 static const int kImageWidth = 1920; | |
42 static const int kImageHeight = 1080; | |
43 | |
44 // TODO factor this out into functions, also handle CPU path | |
45 SkData* setupAndDrawToCanvas(const char* path, SkString* error) { | |
46 GrContextOptions grContextOpts; | |
47 SkAutoTDelete<GrContextFactory> factory(new GrContextFactory(grContextOpts)) ; | |
48 | |
49 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType, | |
50 GrContextFactory::kNone_GLContextOptions); | |
51 int maxRTSize = context->caps()->maxRenderTargetSize(); | |
52 SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), | |
53 SkTMin(kImageHeight, maxRTSize), | |
54 kN32_SkColorType, kPremul_SkAlphaType); | |
55 uint32_t flags = 0; | |
56 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); | |
57 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, | |
58 SkSurface::kNo_Bu dgeted, info, | |
59 0, &props)); | |
60 SkASSERT(surface.get()); | |
61 | |
62 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex tType, | |
63 GrContextFactory::kNone_GLContextO ptions).fGLContext; | |
64 gl->makeCurrent(); | |
65 | |
66 // draw | |
67 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); | |
68 if (stream.get() == nullptr) { | |
69 error->appendf("Could not read %s.\n", path); | |
70 return nullptr; | |
71 } | |
72 | |
73 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get())); | |
74 if (pic.get() == nullptr) { | |
75 error->appendf("Could not read %s as an SkPicture.\n", path); | |
76 return nullptr; | |
77 } | |
78 | |
79 SkCanvas* canvas = surface->getCanvas(); | |
80 canvas->drawPicture(pic); | |
81 | |
82 // capture pixels | |
83 SkBitmap bmp; | |
84 bmp.setInfo(canvas->imageInfo()); | |
85 if (!canvas->readPixels(&bmp, 0, 0)) { | |
86 error->appendf("Can't read canvas pixels.\n"); | |
87 return nullptr; | |
88 } | |
89 | |
90 // write to png | |
91 SkData* data = SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 10 0); | |
92 if (!data) { | |
93 error->appendf("Can't encode a PNG.\n"); | |
94 return nullptr; | |
95 } | |
96 return data; | |
97 } | |
98 | |
99 SkString generateTemplate(SkString source) { | |
ethannicholas
2016/01/22 17:09:51
Is the fact that the HTML is hard-coded here just
mtklein
2016/01/22 17:11:57
(If not, you don't really need a server.)
| |
100 SkString debuggerTemplate; | |
101 debuggerTemplate.appendf( | |
102 "<!DOCTYPE html>\n" | |
103 "<html>\n" | |
104 "<head>\n" | |
105 " <title>SkDebugger</title>\n" | |
106 " <meta charset=\"utf-8\" />\n" | |
107 " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=egde,chrome=1\">\ n" | |
108 " <meta name=\"viewport\" content=\"width=device-width, initial-scale =1.0\">\n" | |
109 " <script src=\"%s/res/js/core.js\" type=\"text/javascript\" charset= \"utf-8\"></script>\n" | |
110 " <link href=\"%s/res/vul/elements.html\" rel=\"import\" />\n" | |
111 "</head>\n" | |
112 "<body class=\"fullbleed layout vertical\">\n" | |
113 " <debugger-app-sk>This is the app." | |
114 " </debugger-app-sk>\n" | |
115 "</body>\n" | |
116 "</html>", source.c_str(), source.c_str()); | |
117 return debuggerTemplate; | |
118 | |
119 } | |
120 | |
121 int answer_to_connection(void* cls, struct MHD_Connection* connection, | |
122 const char* url, const char* method, const char* versio n, | |
123 const char* upload_data, size_t* upload_data_size, | |
124 void** con_cls) { | |
125 printf ("New %s request for %s using version %s\n", method, url, version); | |
126 | |
127 struct MHD_Response* response; | |
128 | |
129 // serve html to root | |
130 // TODO better url handling | |
131 int ret; | |
132 if (0 == strcmp("/", url)) { | |
133 SkString debuggerTemplate = generateTemplate(SkString("http://debugger.s kia.org")); | |
134 | |
135 response = MHD_create_response_from_buffer(debuggerTemplate.size(), | |
136 (void*)const_cast<char*>(debu ggerTemplate.c_str()), | |
137 MHD_RESPMEM_MUST_COPY); | |
138 ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
139 MHD_destroy_response(response); | |
140 return MHD_YES; | |
141 } | |
142 | |
143 // otherwise serve an image | |
144 // TODO take from post | |
145 SkString resourceName; | |
146 resourceName.appendf("%s/%s.skp", FLAGS_dir[0], FLAGS_name[0]); | |
147 SkDebugf("Loading skp: %s\n", resourceName.c_str()); | |
148 | |
149 SkString error; | |
150 SkAutoTUnref<SkData> data(setupAndDrawToCanvas(resourceName.c_str(), &error) ); | |
151 if (!data) { | |
152 // TODO send error | |
153 return MHD_YES; | |
154 } | |
155 | |
156 response = MHD_create_response_from_buffer(data->size(), const_cast<void*>(d ata->data()), | |
157 MHD_RESPMEM_MUST_COPY); | |
158 MHD_add_response_header(response, "Content-Type", "image/png"); | |
159 ret = MHD_queue_response(connection, MHD_HTTP_OK, response); | |
160 MHD_destroy_response(response); | |
161 return ret; | |
162 } | |
163 | |
164 int skiaserve_main() { | |
165 struct MHD_Daemon* daemon; | |
166 daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL, | |
167 &answer_to_connection, NULL, MHD_OPTION_END); | |
168 if (NULL == daemon) { | |
169 return 1; | |
170 } | |
171 | |
172 getchar(); | |
173 MHD_stop_daemon(daemon); | |
174 return 0; | |
175 } | |
176 | |
177 #if !defined SK_BUILD_FOR_IOS | |
178 int main(int argc, char** argv) { | |
179 SkCommandLineFlags::Parse(argc, argv); | |
180 return skiaserve_main(); | |
181 } | |
182 #endif | |
OLD | NEW |