blob: 27fc8c6a2aace7e6f4937a341e45ede9bc3026ae [file] [log] [blame]
yangsu@google.comef7bdfa2011-08-12 14:27:47 +00001#include "SampleCode.h"
yangsu@google.comef7bdfa2011-08-12 14:27:47 +00002#include "SkOSMenu.h"
3
4#include "DebuggerViews.h"
5static const char gIsDebuggerQuery[] = "is-debugger";
6class DebuggerView : public SampleView {
7public:
robertphillips@google.com6853e802012-04-16 15:50:18 +00008 DebuggerView(const char* data, size_t size) {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +00009 fData.append(size, data);
10 fCommandsVisible = true;
11 fCommandsResizing = false;
12 fStateVisible = true;
13 fStateResizing = false;
14
15 fCommands = new DebuggerCommandsView;
16 fCommands->setVisibleP(fCommandsVisible);
17 this->attachChildToFront(fCommands)->unref();
18
19
20 fState = new DebuggerStateView;
21 fState->setVisibleP(fStateVisible);
22 this->attachChildToFront(fState)->unref();
23
24 fAtomsToRead = 0;
25 fDisplayClip = false;
26
27 fDumper = new SkDebugDumper(this->getSinkID(), fCommands->getSinkID(),
28 fState->getSinkID());
29
30 fDumper->unload();
31 fAtomBounds.reset();
32 fFrameBounds.reset();
33
34 SkDumpCanvas* dumpCanvas = new SkDumpCanvas(fDumper);
35 SkGPipeReader* dumpReader = new SkGPipeReader(dumpCanvas);
36
37
38 if (size > 0) {
39 int offset = 0;
40 int frameBound = 0;
41 size_t bytesRead;
epoger@google.com17b78942011-08-26 14:40:38 +000042 while (static_cast<unsigned>(offset) < size) {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000043 SkGPipeReader::Status s = dumpReader->playback(data + offset,
44 size - offset,
45 &bytesRead,
46 true);
47 SkASSERT(SkGPipeReader::kError_Status != s);
48 offset += bytesRead;
49
50 if (SkGPipeReader::kDone_Status == s) {
51 fDumper->dump(dumpCanvas, SkDumpCanvas::kNULL_Verb,
52 "End of Frame", NULL);
53 delete dumpReader;
54 delete dumpCanvas;
55 dumpCanvas = new SkDumpCanvas(fDumper);
56 dumpReader = new SkGPipeReader(dumpCanvas);
57 frameBound = offset;
58 }
59 fAtomBounds.append(1, &offset);
60 fFrameBounds.append(1, &frameBound);
61 }
62 }
63
64 delete dumpReader;
65 delete dumpCanvas;
66
67 fDumper->load();
68 }
69
70 ~DebuggerView() {
71 fAtomBounds.reset();
72 fFrameBounds.reset();
73 delete fDumper;
74 }
75
76 virtual void requestMenu(SkOSMenu* menu) {
77 menu->setTitle("Debugger");
78 menu->appendSwitch("Show Commands", "Commands", this->getSinkID(), fCommandsVisible);
79 menu->appendSwitch("Show State", "State", this->getSinkID(), fStateVisible);
80 menu->appendSwitch("Display Clip", "Clip", this->getSinkID(), fDisplayClip);
81 }
82
83
84 void goToAtom(int atom) {
85 if (atom != fAtomsToRead) {
86 fAtomsToRead = atom;
87 this->inval(NULL);
88 }
89 }
90
91protected:
92 virtual bool onQuery(SkEvent* evt) {
93 if (SampleCode::TitleQ(*evt)) {
94 SampleCode::TitleR(evt, "Debugger");
95 return true;
96 }
97 if (evt->isType(gIsDebuggerQuery)) {
98 return true;
99 }
100 return this->INHERITED::onQuery(evt);
101 }
102
103 virtual bool onEvent(const SkEvent& evt) {
104 if (SkOSMenu::FindSwitchState(evt, "Commands", &fCommandsVisible) ||
105 SkOSMenu::FindSwitchState(evt, "State", &fStateVisible)) {
106 fCommands->setVisibleP(fCommandsVisible);
107 fState->setVisibleP(fStateVisible);
108 fStateOffset = (fCommandsVisible) ? fCommands->width() : 0;
109 fState->setSize(this->width() - fStateOffset, fState->height());
110 fState->setLoc(fStateOffset, this->height() - fState->height());
111 this->inval(NULL);
112 return true;
113 }
114 if (SkOSMenu::FindSwitchState(evt, "Clip", &fDisplayClip)) {
115 this->inval(NULL);
116 return true;
117 }
118 return this->INHERITED::onEvent(evt);
119 }
120
121 virtual void onDrawContent(SkCanvas* canvas) {
122 if (fData.count() <= 0)
123 return;
124 SkAutoCanvasRestore acr(canvas, true);
125 canvas->translate(fStateOffset, 0);
126
127 int lastFrameBound = fFrameBounds[fAtomsToRead];
128 int toBeRead = fAtomBounds[fAtomsToRead] - lastFrameBound;
129 int firstChunk = (fAtomsToRead > 0) ? fAtomBounds[fAtomsToRead - 1] - lastFrameBound: 0;
130 if (toBeRead > 0) {
131 SkDumpCanvas* dumpCanvas = new SkDumpCanvas(fDumper);
132 SkGPipeReader* dumpReader = new SkGPipeReader(dumpCanvas);
133 SkGPipeReader* reader = new SkGPipeReader(canvas);
134 fDumper->disable();
135
136 int offset = 0;
137 size_t bytesRead;
138 SkGPipeReader::Status s;
139 //Read the first chunk
140 if (offset < firstChunk && firstChunk < toBeRead) {
141 s = dumpReader->playback(fData.begin() + offset, firstChunk - offset, NULL, false);
142 SkASSERT(SkGPipeReader::kError_Status != s);
143 s = reader->playback(fData.begin() + offset, firstChunk - offset, &bytesRead, false);
144 SkASSERT(SkGPipeReader::kError_Status != s);
145 if (SkGPipeReader::kDone_Status == s){
146 delete dumpReader;
147 delete dumpCanvas;
148 dumpCanvas = new SkDumpCanvas(fDumper);
149 dumpReader = new SkGPipeReader(dumpCanvas);
150 delete reader;
151 reader = new SkGPipeReader(canvas);
152 }
153 offset += bytesRead;
154 }
155 SkASSERT(offset == firstChunk);
156 //Then read the current atom
157 fDumper->enable();
158 s = dumpReader->playback(fData.begin() + offset, toBeRead - offset, NULL, true);
159 SkASSERT(SkGPipeReader::kError_Status != s);
160 s = reader->playback(fData.begin() + offset, toBeRead - offset, &bytesRead, true);
161 SkASSERT(SkGPipeReader::kError_Status != s);
162
163 delete reader;
164 delete dumpReader;
165 delete dumpCanvas;
166
167 if (fDisplayClip) {
168 SkPaint p;
169 p.setColor(0x440000AA);
170 SkPath path;
171 canvas->getTotalClip().getBoundaryPath(&path);
172 canvas->drawPath(path, p);
173 }
174 }
175 }
176
177 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
178 return new Click(this);
179 }
180
181 virtual bool onClick(SkView::Click* click) {
182 SkPoint prev = click->fPrev;
183 SkPoint curr = click->fCurr;
184 bool handled = true;
185 switch (click->fState) {
186 case SkView::Click::kDown_State:
187 if (SkScalarAbs(curr.fX - fCommands->width()) <= SKDEBUGGER_RESIZEBARSIZE) {
188 fCommandsResizing = true;
189 }
190 else if (SkScalarAbs(curr.fY - (this->height() - fState->height())) <= SKDEBUGGER_RESIZEBARSIZE &&
191 curr.fX > fCommands->width()) {
192 fStateResizing = true;
193 }
194 else if (curr.fX < fCommands->width()) {
robertphillips@google.com6853e802012-04-16 15:50:18 +0000195 fAtomsToRead = fCommands->selectHighlight(
196 SkScalarFloorToInt(curr.fY));
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000197 }
198 else
199 handled = false;
200 break;
201 case SkView::Click::kMoved_State:
202 if (fCommandsResizing)
203 fCommands->setSize(curr.fX, this->height());
204 else if (fStateResizing)
205 fState->setSize(this->width(), this->height() - curr.fY);
206 else if (curr.fX < fCommands->width()) {
207 if (curr.fY - prev.fY < 0) {
208 fCommands->scrollDown();
209 }
210 if (curr.fY - prev.fY > 0) {
211 fCommands->scrollUp();
212 }
213 }
214 else
215 handled = false;
216 break;
217 case SkView::Click::kUp_State:
218 fStateResizing = fCommandsResizing = false;
219 break;
220 default:
221 break;
222 }
223
224 fStateOffset = fCommands->width();
225 fState->setSize(this->width() - fStateOffset, fState->height());
226 fState->setLoc(fStateOffset, this->height() - fState->height());
227 if (handled)
228 this->inval(NULL);
229 return handled;
230 }
231
232 virtual void onSizeChange() {
233 this->INHERITED::onSizeChange();
234 fCommands->setSize(CMD_WIDTH, this->height());
235 fCommands->setLoc(0, 0);
robertphillips@google.com6853e802012-04-16 15:50:18 +0000236 fState->setSize(this->width() - CMD_WIDTH, SkFloatToScalar(INFO_HEIGHT));
237 fState->setLoc(CMD_WIDTH, this->height() - SkFloatToScalar(INFO_HEIGHT));
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000238 }
239
240private:
241 DebuggerCommandsView* fCommands;
242 DebuggerStateView* fState;
243 bool fCommandsResizing;
244 bool fCommandsVisible;
245 bool fStateResizing;
246 bool fStateVisible;
247 float fStateOffset;
248 bool fDisplayClip;
249 int fAtomsToRead;
250 SkTDArray<int> fAtomBounds;
251 SkTDArray<int> fFrameBounds;
252 SkTDArray<char> fData;
253 SkDebugDumper* fDumper;
254
255 typedef SampleView INHERITED;
256};
257
258
259///////////////////////////////////////////////////////////////////////////////
260
261SkView* create_debugger(const char* data, size_t size) {
262 return SkNEW_ARGS(DebuggerView, (data, size));
263};
264
265bool is_debugger(SkView* view) {
266 SkEvent isDebugger(gIsDebuggerQuery);
267 return view->doQuery(&isDebugger);
268}