blob: d12582a12a4cfe8e3ebf8271932f548385023229 [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:
8 DebuggerView(const char* data, size_t size) {
9 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()) {
195 fAtomsToRead = fCommands->selectHighlight(curr.fY);
196 }
197 else
198 handled = false;
199 break;
200 case SkView::Click::kMoved_State:
201 if (fCommandsResizing)
202 fCommands->setSize(curr.fX, this->height());
203 else if (fStateResizing)
204 fState->setSize(this->width(), this->height() - curr.fY);
205 else if (curr.fX < fCommands->width()) {
206 if (curr.fY - prev.fY < 0) {
207 fCommands->scrollDown();
208 }
209 if (curr.fY - prev.fY > 0) {
210 fCommands->scrollUp();
211 }
212 }
213 else
214 handled = false;
215 break;
216 case SkView::Click::kUp_State:
217 fStateResizing = fCommandsResizing = false;
218 break;
219 default:
220 break;
221 }
222
223 fStateOffset = fCommands->width();
224 fState->setSize(this->width() - fStateOffset, fState->height());
225 fState->setLoc(fStateOffset, this->height() - fState->height());
226 if (handled)
227 this->inval(NULL);
228 return handled;
229 }
230
231 virtual void onSizeChange() {
232 this->INHERITED::onSizeChange();
233 fCommands->setSize(CMD_WIDTH, this->height());
234 fCommands->setLoc(0, 0);
235 fState->setSize(this->width() - CMD_WIDTH, INFO_HEIGHT);
236 fState->setLoc(CMD_WIDTH, this->height() - INFO_HEIGHT);
237 }
238
239private:
240 DebuggerCommandsView* fCommands;
241 DebuggerStateView* fState;
242 bool fCommandsResizing;
243 bool fCommandsVisible;
244 bool fStateResizing;
245 bool fStateVisible;
246 float fStateOffset;
247 bool fDisplayClip;
248 int fAtomsToRead;
249 SkTDArray<int> fAtomBounds;
250 SkTDArray<int> fFrameBounds;
251 SkTDArray<char> fData;
252 SkDebugDumper* fDumper;
253
254 typedef SampleView INHERITED;
255};
256
257
258///////////////////////////////////////////////////////////////////////////////
259
260SkView* create_debugger(const char* data, size_t size) {
261 return SkNEW_ARGS(DebuggerView, (data, size));
262};
263
264bool is_debugger(SkView* view) {
265 SkEvent isDebugger(gIsDebuggerQuery);
266 return view->doQuery(&isDebugger);
267}