1f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SampleCode.h"
2f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkView.h"
3f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCanvas.h"
4f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkGPipe.h"
5f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkSockets.h"
6f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkNetPipeController.h"
7f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCornerPathEffect.h"
8f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkOSMenu.h"
9f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include <map>
10ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
11ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com/**
12ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Drawing Server
13ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com *
14d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * This simple drawing server can accept connections from multiple drawing
15d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * clients simultaneously. It accumulates drawing data from each client each
16ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * frame, stores it in the appropriate place, and then broadcasts incremental
17ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * changes back to all the clients. Each logical packet, meaning one brush
18ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * stoke in this case can be of two types, append and replace. Append types are
19ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * completed strokes ready to be stored in the fData queue and will no longer be
20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * modified. Replace types are drawing operations that are still in progress on
21d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * the client side, so they are appended to fBuffer. The location and size of
22ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * the buffered data for each client is stored in a map and updated properly.
23ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Each time a new replace drawing call is received from a client, its previous
24ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * buffered data is discarded.
25ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Since the Server keeps all the complete drawing data and the latest buffered
26ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * data, it's able to switch between vector and bitmap drawing
27ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com */
28ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
29f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comclass DrawingServerView : public SampleView {
30f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.compublic:
31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    DrawingServerView(){
32f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fServer = new SkTCPServer(40000);
33f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fServer->suspendWrite();
34f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = fTotalBytesWritten = 0;
35f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fVector = true;
36f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
37f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    ~DrawingServerView() {
38f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        delete fServer;
39f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fData.reset();
40f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBuffer.reset();
41f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fClientMap.clear();
42f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
43d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
44f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void requestMenu(SkOSMenu* menu) {
45f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->setTitle("Drawing Server");
46f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendAction("Clear", this->getSinkID());
47f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendSwitch("Vector", "Vector", this->getSinkID(), fVector);
48f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
50f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprotected:
51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static void readData(int cid, const void* data, size_t size,
52f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                         SkSocket::DataType type, void* context) {
53f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        DrawingServerView* view = (DrawingServerView*)context;
54f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        view->onRead(cid, data, size, type);
55f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
57f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void onRead(int cid, const void* data, size_t size, SkSocket::DataType type) {
58f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (NULL == data && size <= 0)
59f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return;
60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
61f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        ClientState* cs;
62f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        std::map<int, ClientState*>::iterator it = fClientMap.find(cid);
63f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (it == fClientMap.end()) { //New client
64f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs = new ClientState;
65f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs->bufferBase = 0;
66f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs->bufferSize = 0;
67f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fClientMap[cid] = cs;
68f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
69f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        else {
70f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs = it->second;
71f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
73f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (type == SkSocket::kPipeReplace_type) {
74f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fBuffer.remove(cs->bufferBase, cs->bufferSize);
75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
76f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            for (it = fClientMap.begin(); it != fClientMap.end(); ++it) {
77f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                if (cid == it->first)
78f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    continue;
79f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                else {
80f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    if (it->second->bufferBase > cs->bufferBase) {
81f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                        it->second->bufferBase -= cs->bufferSize;
82f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                        SkASSERT(it->second->bufferBase >= 0);
83f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    }
84f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                }
85f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            }
86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
87f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs->bufferBase = fBuffer.count();
88f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            cs->bufferSize = size;
89f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fBuffer.append(size, (const char*)data);
90f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
91f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        else if (type == SkSocket::kPipeAppend_type) {
92f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fData.append(size, (const char*)data);
93f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fServer->resumeWrite();
94f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fServer->writePacket(fData.begin() + fTotalBytesWritten,
95f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                                 fData.count() - fTotalBytesWritten,
96f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                                 SkSocket::kPipeAppend_type);
97f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesWritten = fData.count();
98f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fServer->suspendWrite();
99f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
100f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        else {
101f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            //other types of data
102f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
103f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
105f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool onQuery(SkEvent* evt) {
106f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (SampleCode::TitleQ(*evt)) {
107f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SampleCode::TitleR(evt, "Drawing Server");
108f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
109f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
110f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return this->INHERITED::onQuery(evt);
111f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
112d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
113f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool onEvent(const SkEvent& evt) {
114ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindAction(evt, "Clear")) {
115f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            this->clear();
116f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
117f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
118ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindSwitchState(evt, "Vector", &fVector)) {
119f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            this->clearBitmap();
120f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
121f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
122f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return this->INHERITED::onEvent(evt);
123f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
126f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void onDrawContent(SkCanvas* canvas) {
127f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fCurrMatrix != canvas->getTotalMatrix()) {
128f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesRead = 0;
129f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fCurrMatrix = canvas->getTotalMatrix();
130f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
131f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
132f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fServer->acceptConnections();
133f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fServer->readPacket(readData, this) > 0) {
134f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fServer->resumeWrite();
135f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
136f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        else {
137f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fServer->suspendWrite();
138f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
140f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        size_t bytesRead;
141ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkGPipeReader::Status stat;
142f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkCanvas bufferCanvas(fBase);
143f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkCanvas* tempCanvas;
144f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        while (fTotalBytesRead < fData.count()) {
145ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            if (fVector) {
146f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                tempCanvas = canvas;
147ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            } else {
148f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                tempCanvas = &bufferCanvas;
149ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            }
150f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkGPipeReader reader(tempCanvas);
151ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            stat = reader.playback(fData.begin() + fTotalBytesRead,
152ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                   fData.count() - fTotalBytesRead,
153ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                   &bytesRead);
154f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkASSERT(SkGPipeReader::kError_Status != stat);
155f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesRead += bytesRead;
156f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
157ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (fVector) {
158f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesRead = 0;
159ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        } else {
160f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            canvas->drawBitmap(fBase, 0, 0, NULL);
161ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        }
162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
163f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        size_t totalBytesRead = 0;
164f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        while (totalBytesRead < fBuffer.count()) {
165f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkGPipeReader reader(canvas);
166ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            stat = reader.playback(fBuffer.begin() + totalBytesRead,
167ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                   fBuffer.count() - totalBytesRead,
168ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                   &bytesRead);
169ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            SkASSERT(SkGPipeReader::kError_Status != stat);
170f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            totalBytesRead += bytesRead;
171f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
172d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fServer->writePacket(fBuffer.begin(), fBuffer.count(),
174f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                             SkSocket::kPipeReplace_type);
175f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
176f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->inval(NULL);
177f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
178d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
179f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void onSizeChange() {
180f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->INHERITED::onSizeChange();
181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fBase.setConfig(SkBitmap::kARGB_8888_Config,
182d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                        this->width(),
183ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                        this->height());
184f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBase.allocPixels(NULL);
185f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->clearBitmap();
186f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
187d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
188f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprivate:
189f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void clear() {
190f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fData.reset();
191f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBuffer.reset();
192f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = fTotalBytesWritten = 0;
193f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fClientMap.clear();
194f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->clearBitmap();
195f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
196f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void clearBitmap() {
197f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = 0;
198f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBase.eraseColor(fBGColor);
199f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
200d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
201f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    struct ClientState {
202f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        int bufferBase;
203f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        int bufferSize;
204f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    };
205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
206f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    std::map<int, ClientState*> fClientMap;
207f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTDArray<char>             fData;
208f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTDArray<char>             fBuffer;
209f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    size_t                      fTotalBytesRead;
210f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    size_t                      fTotalBytesWritten;
211f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkMatrix                    fCurrMatrix;
212f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkBitmap                    fBase;
213f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool                        fVector;
214f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTCPServer*                fServer;
215f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    typedef SampleView INHERITED;
216f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com};
217f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
218f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
219f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com///////////////////////////////////////////////////////////////////////////////
220f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
221f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkView* MyFactory() { return new DrawingServerView; }
222f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkViewRegister reg(MyFactory);
223