| Index: experimental/nanomsg/picture_demo.cpp
|
| diff --git a/experimental/nanomsg/picture_demo.cpp b/experimental/nanomsg/picture_demo.cpp
|
| deleted file mode 100644
|
| index a0b83a2579c77f859144fba478cd4f98b6da5784..0000000000000000000000000000000000000000
|
| --- a/experimental/nanomsg/picture_demo.cpp
|
| +++ /dev/null
|
| @@ -1,214 +0,0 @@
|
| -/*
|
| - * Copyright 2014 Google Inc.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -#include "nanomsg/src/nn.h"
|
| -#include "nanomsg/src/pipeline.h"
|
| -#include "nanomsg/src/reqrep.h"
|
| -
|
| -#include "SkCanvas.h"
|
| -#include "SkCommandLineFlags.h"
|
| -#include "SkData.h"
|
| -#include "SkForceLinking.h"
|
| -#include "SkGraphics.h"
|
| -#include "SkImageEncoder.h"
|
| -#include "SkOSFile.h"
|
| -#include "SkPicture.h"
|
| -#include "SkRandom.h"
|
| -#include "SkStream.h"
|
| -
|
| -__SK_FORCE_IMAGE_DECODER_LINKING;
|
| -
|
| -// To keep things simple, PictureHeader is fixed-size POD.
|
| -struct PictureHeader {
|
| - SkMatrix matrix;
|
| - SkRect clip;
|
| - SkXfermode::Mode xfermode;
|
| - pid_t pid;
|
| - uint8_t alpha;
|
| -
|
| - PictureHeader()
|
| - : matrix(SkMatrix::I())
|
| - , clip(SkRect::MakeLargest())
|
| - , xfermode(SkXfermode::kSrcOver_Mode)
|
| - , pid(getpid())
|
| - , alpha(0xFF) {}
|
| -};
|
| -
|
| -// A little adaptor: nn_iovec wants a non-const pointer for no obvious reason.
|
| -static struct nn_iovec create_iov(const void* ptr, size_t size) {
|
| - struct nn_iovec iov = { const_cast<void*>(ptr), size };
|
| - return iov;
|
| -}
|
| -
|
| -static void send_picture(int socket, const PictureHeader& header, const SkData& skp) {
|
| - // Vectored IO lets us send header and skp contiguously without first
|
| - // copying them to a contiguous buffer.
|
| - struct nn_iovec iov[] = {
|
| - create_iov(&header, sizeof(header)),
|
| - create_iov(skp.data(), skp.size()),
|
| - };
|
| -
|
| - struct nn_msghdr msg;
|
| - sk_bzero(&msg, sizeof(msg));
|
| - msg.msg_iov = iov;
|
| - msg.msg_iovlen = SK_ARRAY_COUNT(iov);
|
| -
|
| - nn_sendmsg(socket, &msg, 0/*flags*/);
|
| -}
|
| -
|
| -static sk_sp<SkPicture> recv_picture(int socket, PictureHeader* header) {
|
| - static const size_t hSize = sizeof(*header); // It's easy to slip up and use sizeof(header).
|
| -
|
| - void* msg;
|
| - int size = nn_recv(socket, &msg, NN_MSG, 0/*flags*/);
|
| - SkDebugf("%d bytes", size);
|
| -
|
| - // msg is first a fixed-size header, then an .skp.
|
| - memcpy(header, msg, hSize);
|
| - SkMemoryStream stream((uint8_t*)msg + hSize, size - hSize);
|
| - sk_sp<SkPicture> pic = SkPicture::MakeFromStream(&stream);
|
| -
|
| - SkDebugf(" from proccess %d:", header->pid);
|
| -
|
| - nn_freemsg(msg);
|
| - return pic;
|
| -}
|
| -
|
| -static void client(const char* skpPath, const char* dataEndpoint) {
|
| - // Read the .skp.
|
| - sk_sp<SkData> skp(SkData::MakeFromFileName(skpPath));
|
| - if (!skp) {
|
| - SkDebugf("Couldn't read %s\n", skpPath);
|
| - exit(1);
|
| - }
|
| - SkMemoryStream stream(skp->data(), skp->size());
|
| - sk_sp<SkPicture> picture(SkPicture::MakeFromStream(&stream));
|
| -
|
| - PictureHeader header;
|
| - SkRandom rand(picture->cullRect().width() * picture->cullRect().height());
|
| - SkScalar r = rand.nextRangeScalar(0, picture->cullRect().width()),
|
| - b = rand.nextRangeScalar(0, picture->cullRect().height()),
|
| - l = rand.nextRangeScalar(0, r),
|
| - t = rand.nextRangeScalar(0, b);
|
| - header.clip.setLTRB(l,t,r,b);
|
| - header.matrix.setTranslate(-l, -t);
|
| - header.matrix.postRotate(rand.nextRangeScalar(-25, 25));
|
| - header.alpha = 0x7F;
|
| -
|
| - //Clients use NN_REQ (request) type sockets.
|
| - int socket = nn_socket(AF_SP, NN_REQ);
|
| -
|
| - // Clients connect a socket to an endpoint.
|
| - nn_connect(socket, dataEndpoint);
|
| -
|
| - // Send the picture and its header.
|
| - SkDebugf("Sending %s (%d bytes)...", skpPath, skp->size());
|
| - send_picture(socket, header, *skp);
|
| -
|
| - // Wait for ack.
|
| - uint8_t ack;
|
| - nn_recv(socket, &ack, sizeof(ack), 0/*flags*/);
|
| - SkDebugf(" ok.\n");
|
| -}
|
| -
|
| -// Wait until socketA or socketB has something to tell us, and return which one.
|
| -static int poll_in(int socketA, int socketB) {
|
| - struct nn_pollfd polls[] = {
|
| - { socketA, NN_POLLIN, 0 },
|
| - { socketB, NN_POLLIN, 0 },
|
| - };
|
| -
|
| - nn_poll(polls, SK_ARRAY_COUNT(polls), -1/*no timeout*/);
|
| -
|
| - if (polls[0].revents & NN_POLLIN) { return socketA; }
|
| - if (polls[1].revents & NN_POLLIN) { return socketB; }
|
| -
|
| - SkFAIL("unreachable");
|
| - return 0;
|
| -}
|
| -
|
| -static void server(const char* dataEndpoint, const char* controlEndpoint, SkCanvas* canvas) {
|
| - // NN_REP sockets receive a request then make a reply. NN_PULL sockets just receive a request.
|
| - int data = nn_socket(AF_SP, NN_REP);
|
| - int control = nn_socket(AF_SP, NN_PULL);
|
| -
|
| - // Servers bind a socket to an endpoint.
|
| - nn_bind(data, dataEndpoint);
|
| - nn_bind(control, controlEndpoint);
|
| -
|
| - while (true) {
|
| - int ready = poll_in(data, control);
|
| -
|
| - // If we got any message on the control socket, we can stop.
|
| - if (ready == control) {
|
| - break;
|
| - }
|
| -
|
| - // We should have an .skp waiting for us on data socket.
|
| - PictureHeader header;
|
| - sk_sp<SkPicture> picture(recv_picture(data, &header));
|
| -
|
| - SkPaint paint;
|
| - paint.setAlpha(header.alpha);
|
| - paint.setXfermodeMode(header.xfermode);
|
| -
|
| - canvas->saveLayer(NULL, &paint);
|
| - canvas->concat(header.matrix);
|
| - canvas->clipRect(header.clip);
|
| - picture->playback(canvas);
|
| - canvas->restore();
|
| - SkDebugf(" drew");
|
| -
|
| - // Send back an ack.
|
| - uint8_t ack = 42;
|
| - nn_send(data, &ack, sizeof(ack), 0/*flags*/);
|
| - SkDebugf(" and acked.\n");
|
| - }
|
| -}
|
| -
|
| -static void stop(const char* controlEndpoint) {
|
| - // An NN_PUSH socket can send messages but not receive them.
|
| - int control = nn_socket(AF_SP, NN_PUSH);
|
| - nn_connect(control, controlEndpoint);
|
| -
|
| - // Sending anything (including this 0-byte message) will tell server() to stop.
|
| - nn_send(control, NULL, 0, 0/*flags*/);
|
| -}
|
| -
|
| -DEFINE_string2(skp, r, "", ".skp to send (as client)");
|
| -DEFINE_string2(png, w, "", ".png to write (as server)");
|
| -DEFINE_bool(stop, false, "If true, tell server to stop and write its canvas out as a .png.");
|
| -DEFINE_string(data, "ipc://nanomsg-picture-data", "Endpoint for sending pictures.");
|
| -DEFINE_string(control, "ipc://nanomsg-picture-control", "Endpoint for control channel.");
|
| -
|
| -int main(int argc, char** argv) {
|
| - SkAutoGraphics ag;
|
| - SkCommandLineFlags::Parse(argc, argv);
|
| -
|
| - if (FLAGS_stop) {
|
| - stop(FLAGS_control[0]);
|
| - }
|
| -
|
| - if (!FLAGS_skp.isEmpty()) {
|
| - client(FLAGS_skp[0], FLAGS_data[0]);
|
| - }
|
| -
|
| - if (!FLAGS_png.isEmpty()) {
|
| - SkBitmap bitmap;
|
| - bitmap.allocN32Pixels(1000, 1000);
|
| - SkCanvas canvas(bitmap);
|
| - canvas.clear(0xFFFFFFFF);
|
| -
|
| - server(FLAGS_data[0], FLAGS_control[0], &canvas);
|
| - canvas.flush();
|
| -
|
| - SkImageEncoder::EncodeFile(FLAGS_png[0], bitmap, SkImageEncoder::kPNG_Type, 100);
|
| - SkDebugf("Wrote %s.\n", FLAGS_png[0]);
|
| - }
|
| -
|
| - return 0;
|
| -}
|
|
|