Home | History | Annotate | Download | only in Networking
      1 #include "SampleCode.h"
      2 #include "SkView.h"
      3 #include "SkCanvas.h"
      4 #include "SkGradientShader.h"
      5 #include "SkGPipe.h"
      6 #include "SkSockets.h"
      7 #include "SkOSMenu.h"
      8 
      9 /**
     10  * A simple networked pipe reader
     11  *
     12  * This view will connect to a user specified server, in this case meaning any
     13  * Skia app that's has a SkTCPServer set up to broadcast its piped drawing data,
     14  * received all the data transmitted and attempt to reproduce the drawing calls.
     15  * This reader will only keep the latest batch of data. In order to keep up with
     16  * the server, which may be producing data at a much higher rate than the reader
     17  * is consuming, the reader will attempt multiple reads and only render the
     18  * latest frame. this behavior can be adjusted by changing MAX_READS_PER_FRAME
     19  * or disabled by setting fSync to false
     20  */
     21 
     22 #define MAX_READS_PER_FRAME 12
     23 
     24 class NetPipeReaderView : public SampleView {
     25 public:
     26     NetPipeReaderView() {
     27         fSocket = NULL;
     28         fSync = true;
     29     }
     30 
     31     ~NetPipeReaderView() {
     32         if (fSocket) {
     33             delete fSocket;
     34         }
     35         fDataArray.reset();
     36     }
     37     virtual void requestMenu(SkOSMenu* menu) {
     38         menu->setTitle("Net Pipe Reader");
     39         menu->appendTextField("Server IP", "Server IP", this->getSinkID(),
     40                               "IP address");
     41         menu->appendSwitch("Sync", "Sync", this->getSinkID(), fSync);
     42     }
     43 
     44 protected:
     45     static void readData(int cid, const void* data, size_t size,
     46                          SkSocket::DataType type, void* context) {
     47         NetPipeReaderView* view = (NetPipeReaderView*)context;
     48         view->onRead(data, size);
     49     }
     50 
     51     void onRead(const void* data, size_t size) {
     52         if (size > 0)
     53             fDataArray.append(size, (const char*)data);
     54     }
     55 
     56     bool onQuery(SkEvent* evt) {
     57         if (SampleCode::TitleQ(*evt)) {
     58             SampleCode::TitleR(evt, "Net Pipe Reader");
     59             return true;
     60         }
     61         return this->INHERITED::onQuery(evt);
     62     }
     63 
     64     bool onEvent(const SkEvent& evt) {
     65         SkString s;
     66         if (SkOSMenu::FindText(evt, "Server IP", &s)) {
     67             if (NULL != fSocket) {
     68                 delete fSocket;
     69             }
     70             fSocket = new SkTCPClient(s.c_str());
     71             fSocket->connectToServer();
     72             SkDebugf("Connecting to %s\n", s.c_str());
     73             return true;
     74         }
     75         if (SkOSMenu::FindSwitchState(evt, "Sync", &fSync))
     76             return true;
     77         return this->INHERITED::onEvent(evt);
     78     }
     79 
     80     void onDrawContent(SkCanvas* canvas) {
     81         if (NULL == fSocket)
     82             return;
     83 
     84         if (fSocket->isConnected()) {
     85             int dataToRemove = fDataArray.count();
     86             if (fSync) {
     87                 int numreads = 0;
     88                 while (fSocket->readPacket(readData, this) > 0 &&
     89                        numreads < MAX_READS_PER_FRAME) {
     90                     // at this point, new data has been read and stored, discard
     91                     // old data since it's not needed anymore
     92                     SkASSERT(fDataArray.count() > dataToRemove);
     93                     fDataArray.remove(0, dataToRemove);
     94                     dataToRemove = fDataArray.count();
     95                     ++numreads;
     96                 }
     97                 // clean up if max reads reached
     98                 if (numreads == MAX_READS_PER_FRAME &&
     99                     fDataArray.count() > dataToRemove)
    100                     fDataArray.remove(0, dataToRemove);
    101             }
    102             else {
    103                 if (fSocket->readPacket(readData, this) > 0)
    104                     fDataArray.remove(0, dataToRemove);
    105             }
    106         }
    107         else
    108             fSocket->connectToServer();
    109 
    110         SkGPipeReader reader(canvas);
    111         size_t bytesRead;
    112         SkGPipeReader::Status fStatus = reader.playback(fDataArray.begin(),
    113                                                         fDataArray.count(),
    114                                                         &bytesRead);
    115         SkASSERT(SkGPipeReader::kError_Status != fStatus);
    116         this->inval(NULL);
    117     }
    118 
    119 private:
    120     bool fSync;
    121     SkTDArray<char> fDataArray;
    122     SkTCPClient* fSocket;
    123     typedef SampleView INHERITED;
    124 };
    125 
    126 ///////////////////////////////////////////////////////////////////////////////
    127 
    128 static SkView* MyFactory() { return new NetPipeReaderView; }
    129 static SkViewRegister reg(MyFactory);
    130