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