Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(773)

Side by Side Diff: experimental/nanomsg/picture_demo.cpp

Issue 2287013003: cleanup dead nanomsg and build_overrides (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build_overrides/build.gni ('k') | gyp/most.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 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 "nanomsg/src/nn.h"
9 #include "nanomsg/src/pipeline.h"
10 #include "nanomsg/src/reqrep.h"
11
12 #include "SkCanvas.h"
13 #include "SkCommandLineFlags.h"
14 #include "SkData.h"
15 #include "SkForceLinking.h"
16 #include "SkGraphics.h"
17 #include "SkImageEncoder.h"
18 #include "SkOSFile.h"
19 #include "SkPicture.h"
20 #include "SkRandom.h"
21 #include "SkStream.h"
22
23 __SK_FORCE_IMAGE_DECODER_LINKING;
24
25 // To keep things simple, PictureHeader is fixed-size POD.
26 struct PictureHeader {
27 SkMatrix matrix;
28 SkRect clip;
29 SkXfermode::Mode xfermode;
30 pid_t pid;
31 uint8_t alpha;
32
33 PictureHeader()
34 : matrix(SkMatrix::I())
35 , clip(SkRect::MakeLargest())
36 , xfermode(SkXfermode::kSrcOver_Mode)
37 , pid(getpid())
38 , alpha(0xFF) {}
39 };
40
41 // A little adaptor: nn_iovec wants a non-const pointer for no obvious reason.
42 static struct nn_iovec create_iov(const void* ptr, size_t size) {
43 struct nn_iovec iov = { const_cast<void*>(ptr), size };
44 return iov;
45 }
46
47 static void send_picture(int socket, const PictureHeader& header, const SkData& skp) {
48 // Vectored IO lets us send header and skp contiguously without first
49 // copying them to a contiguous buffer.
50 struct nn_iovec iov[] = {
51 create_iov(&header, sizeof(header)),
52 create_iov(skp.data(), skp.size()),
53 };
54
55 struct nn_msghdr msg;
56 sk_bzero(&msg, sizeof(msg));
57 msg.msg_iov = iov;
58 msg.msg_iovlen = SK_ARRAY_COUNT(iov);
59
60 nn_sendmsg(socket, &msg, 0/*flags*/);
61 }
62
63 static sk_sp<SkPicture> recv_picture(int socket, PictureHeader* header) {
64 static const size_t hSize = sizeof(*header); // It's easy to slip up and us e sizeof(header).
65
66 void* msg;
67 int size = nn_recv(socket, &msg, NN_MSG, 0/*flags*/);
68 SkDebugf("%d bytes", size);
69
70 // msg is first a fixed-size header, then an .skp.
71 memcpy(header, msg, hSize);
72 SkMemoryStream stream((uint8_t*)msg + hSize, size - hSize);
73 sk_sp<SkPicture> pic = SkPicture::MakeFromStream(&stream);
74
75 SkDebugf(" from proccess %d:", header->pid);
76
77 nn_freemsg(msg);
78 return pic;
79 }
80
81 static void client(const char* skpPath, const char* dataEndpoint) {
82 // Read the .skp.
83 sk_sp<SkData> skp(SkData::MakeFromFileName(skpPath));
84 if (!skp) {
85 SkDebugf("Couldn't read %s\n", skpPath);
86 exit(1);
87 }
88 SkMemoryStream stream(skp->data(), skp->size());
89 sk_sp<SkPicture> picture(SkPicture::MakeFromStream(&stream));
90
91 PictureHeader header;
92 SkRandom rand(picture->cullRect().width() * picture->cullRect().height());
93 SkScalar r = rand.nextRangeScalar(0, picture->cullRect().width()),
94 b = rand.nextRangeScalar(0, picture->cullRect().height()),
95 l = rand.nextRangeScalar(0, r),
96 t = rand.nextRangeScalar(0, b);
97 header.clip.setLTRB(l,t,r,b);
98 header.matrix.setTranslate(-l, -t);
99 header.matrix.postRotate(rand.nextRangeScalar(-25, 25));
100 header.alpha = 0x7F;
101
102 //Clients use NN_REQ (request) type sockets.
103 int socket = nn_socket(AF_SP, NN_REQ);
104
105 // Clients connect a socket to an endpoint.
106 nn_connect(socket, dataEndpoint);
107
108 // Send the picture and its header.
109 SkDebugf("Sending %s (%d bytes)...", skpPath, skp->size());
110 send_picture(socket, header, *skp);
111
112 // Wait for ack.
113 uint8_t ack;
114 nn_recv(socket, &ack, sizeof(ack), 0/*flags*/);
115 SkDebugf(" ok.\n");
116 }
117
118 // Wait until socketA or socketB has something to tell us, and return which one.
119 static int poll_in(int socketA, int socketB) {
120 struct nn_pollfd polls[] = {
121 { socketA, NN_POLLIN, 0 },
122 { socketB, NN_POLLIN, 0 },
123 };
124
125 nn_poll(polls, SK_ARRAY_COUNT(polls), -1/*no timeout*/);
126
127 if (polls[0].revents & NN_POLLIN) { return socketA; }
128 if (polls[1].revents & NN_POLLIN) { return socketB; }
129
130 SkFAIL("unreachable");
131 return 0;
132 }
133
134 static void server(const char* dataEndpoint, const char* controlEndpoint, SkCanv as* canvas) {
135 // NN_REP sockets receive a request then make a reply. NN_PULL sockets just receive a request.
136 int data = nn_socket(AF_SP, NN_REP);
137 int control = nn_socket(AF_SP, NN_PULL);
138
139 // Servers bind a socket to an endpoint.
140 nn_bind(data, dataEndpoint);
141 nn_bind(control, controlEndpoint);
142
143 while (true) {
144 int ready = poll_in(data, control);
145
146 // If we got any message on the control socket, we can stop.
147 if (ready == control) {
148 break;
149 }
150
151 // We should have an .skp waiting for us on data socket.
152 PictureHeader header;
153 sk_sp<SkPicture> picture(recv_picture(data, &header));
154
155 SkPaint paint;
156 paint.setAlpha(header.alpha);
157 paint.setXfermodeMode(header.xfermode);
158
159 canvas->saveLayer(NULL, &paint);
160 canvas->concat(header.matrix);
161 canvas->clipRect(header.clip);
162 picture->playback(canvas);
163 canvas->restore();
164 SkDebugf(" drew");
165
166 // Send back an ack.
167 uint8_t ack = 42;
168 nn_send(data, &ack, sizeof(ack), 0/*flags*/);
169 SkDebugf(" and acked.\n");
170 }
171 }
172
173 static void stop(const char* controlEndpoint) {
174 // An NN_PUSH socket can send messages but not receive them.
175 int control = nn_socket(AF_SP, NN_PUSH);
176 nn_connect(control, controlEndpoint);
177
178 // Sending anything (including this 0-byte message) will tell server() to st op.
179 nn_send(control, NULL, 0, 0/*flags*/);
180 }
181
182 DEFINE_string2(skp, r, "", ".skp to send (as client)");
183 DEFINE_string2(png, w, "", ".png to write (as server)");
184 DEFINE_bool(stop, false, "If true, tell server to stop and write its canvas out as a .png.");
185 DEFINE_string(data, "ipc://nanomsg-picture-data", "Endpoint for sending pi ctures.");
186 DEFINE_string(control, "ipc://nanomsg-picture-control", "Endpoint for control ch annel.");
187
188 int main(int argc, char** argv) {
189 SkAutoGraphics ag;
190 SkCommandLineFlags::Parse(argc, argv);
191
192 if (FLAGS_stop) {
193 stop(FLAGS_control[0]);
194 }
195
196 if (!FLAGS_skp.isEmpty()) {
197 client(FLAGS_skp[0], FLAGS_data[0]);
198 }
199
200 if (!FLAGS_png.isEmpty()) {
201 SkBitmap bitmap;
202 bitmap.allocN32Pixels(1000, 1000);
203 SkCanvas canvas(bitmap);
204 canvas.clear(0xFFFFFFFF);
205
206 server(FLAGS_data[0], FLAGS_control[0], &canvas);
207 canvas.flush();
208
209 SkImageEncoder::EncodeFile(FLAGS_png[0], bitmap, SkImageEncoder::kPNG_Ty pe, 100);
210 SkDebugf("Wrote %s.\n", FLAGS_png[0]);
211 }
212
213 return 0;
214 }
OLDNEW
« no previous file with comments | « build_overrides/build.gni ('k') | gyp/most.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698