OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkDebuggerGUI.h" | 8 #include "SkDebuggerGUI.h" |
9 #include "SkForceLinking.h" | 9 #include "SkForceLinking.h" |
10 #include "SkGraphics.h" | 10 #include "SkGraphics.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 149 } |
150 | 150 |
151 void SkDebuggerGUI::showDeletes() { | 151 void SkDebuggerGUI::showDeletes() { |
152 fDeletesActivated = !fDeletesActivated; | 152 fDeletesActivated = !fDeletesActivated; |
153 for (int row = 0; row < fListWidget.count(); row++) { | 153 for (int row = 0; row < fListWidget.count(); row++) { |
154 QListWidgetItem *item = fListWidget.item(row); | 154 QListWidgetItem *item = fListWidget.item(row); |
155 item->setHidden(fDebugger.isCommandVisible(row) && fDeletesActivated); | 155 item->setHidden(fDebugger.isCommandVisible(row) && fDeletesActivated); |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 // The timed picture playback uses the SkPictureData's profiling stubs | 159 // The timed picture playback just steps through every operation timing |
160 // to time individual commands. The offsets are needed to map SkPicture | 160 // each one individually. Note that each picture should be replayed multiple |
161 // offsets to individual commands. | 161 // times (via calls to 'draw') before each command's time is accessed via 'time'
. |
162 class SkTimedPicturePlayback : public SkPicturePlayback { | 162 class SkTimedPicturePlayback : public SkPicturePlayback { |
163 public: | 163 public: |
164 | 164 |
165 SkTimedPicturePlayback(const SkPicture* picture, const SkTDArray<bool>& dele
tedCommands) | 165 SkTimedPicturePlayback(const SkPicture* picture, const SkTDArray<bool>& dele
tedCommands) |
166 : INHERITED(picture) | 166 : INHERITED(picture) |
167 , fSkipCommands(deletedCommands) | 167 , fSkipCommands(deletedCommands) |
168 , fTot(0.0) | 168 , fTot(0.0) |
169 , fCurCommand(0) { | 169 , fCurCommand(0) { |
170 fTimes.setCount(deletedCommands.count()); | 170 fTimes.setCount(deletedCommands.count()); |
171 fTypeTimes.setCount(LAST_DRAWTYPE_ENUM+1); | 171 fTypeTimes.setCount(LAST_DRAWTYPE_ENUM+1); |
172 this->resetTimes(); | 172 this->resetTimes(); |
173 } | 173 } |
174 | 174 |
| 175 virtual void draw(SkCanvas* canvas, SkDrawPictureCallback* callback) SK_OVER
RIDE { |
| 176 AutoResetOpID aroi(this); |
| 177 SkASSERT(0 == fCurOffset); |
| 178 |
| 179 SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData(
)->size()); |
| 180 |
| 181 // Record this, so we can concat w/ it if we encounter a setMatrix() |
| 182 SkMatrix initialMatrix = canvas->getTotalMatrix(); |
| 183 |
| 184 SkAutoCanvasRestore acr(canvas, false); |
| 185 |
| 186 int opIndex = -1; |
| 187 |
| 188 while (!reader.eof()) { |
| 189 if (NULL != callback && callback->abortDrawing()) { |
| 190 return; |
| 191 } |
| 192 |
| 193 fCurOffset = reader.offset(); |
| 194 uint32_t size; |
| 195 DrawType op = ReadOpAndSize(&reader, &size); |
| 196 if (NOOP == op) { |
| 197 // NOOPs are to be ignored - do not propagate them any further |
| 198 reader.setOffset(fCurOffset + size); |
| 199 continue; |
| 200 } |
| 201 |
| 202 opIndex++; |
| 203 |
| 204 if (this->preDraw(opIndex, op)) { |
| 205 // This operation is disabled in the debugger's GUI |
| 206 reader.setOffset(fCurOffset + size); |
| 207 continue; |
| 208 } |
| 209 |
| 210 this->handleOp(&reader, op, size, canvas, initialMatrix); |
| 211 |
| 212 this->postDraw(opIndex); |
| 213 } |
| 214 } |
| 215 |
175 void resetTimes() { | 216 void resetTimes() { |
176 for (int i = 0; i < fTimes.count(); ++i) { | 217 for (int i = 0; i < fTimes.count(); ++i) { |
177 fTimes[i] = 0.0; | 218 fTimes[i] = 0.0; |
178 } | 219 } |
179 for (int i = 0; i < fTypeTimes.count(); ++i) { | 220 for (int i = 0; i < fTypeTimes.count(); ++i) { |
180 fTypeTimes[i] = 0.0f; | 221 fTypeTimes[i] = 0.0f; |
181 } | 222 } |
182 fTot = 0.0; | 223 fTot = 0.0; |
183 } | 224 } |
184 | 225 |
185 int count() const { return fTimes.count(); } | 226 int count() const { return fTimes.count(); } |
186 | 227 |
| 228 // Return the fraction of the total time consumed by the index-th operation |
187 double time(int index) const { return fTimes[index] / fTot; } | 229 double time(int index) const { return fTimes[index] / fTot; } |
188 | 230 |
189 const SkTDArray<double>* typeTimes() const { return &fTypeTimes; } | 231 const SkTDArray<double>* typeTimes() const { return &fTypeTimes; } |
190 | 232 |
191 double totTime() const { return fTot; } | 233 double totTime() const { return fTot; } |
192 | 234 |
193 protected: | 235 protected: |
194 SysTimer fTimer; | 236 SysTimer fTimer; |
195 SkTDArray<bool> fSkipCommands; // has the command been deleted in the GUI? | 237 SkTDArray<bool> fSkipCommands; // has the command been deleted in the GUI? |
196 SkTDArray<double> fTimes; // sum of time consumed for each command | 238 SkTDArray<double> fTimes; // sum of time consumed for each command |
197 SkTDArray<double> fTypeTimes; // sum of time consumed for each type of comma
nd (e.g., drawPath) | 239 SkTDArray<double> fTypeTimes; // sum of time consumed for each type of comma
nd (e.g., drawPath) |
198 double fTot; // total of all times in 'fTimes' | 240 double fTot; // total of all times in 'fTimes' |
| 241 |
199 int fCurType; | 242 int fCurType; |
200 int fCurCommand; // the current command being executed/timed | 243 int fCurCommand; // the current command being executed/timed |
201 | 244 |
202 #ifdef SK_DEVELOPER | 245 bool preDraw(int opIndex, int type) { |
203 virtual bool preDraw(int opIndex, int type) SK_OVERRIDE { | |
204 fCurCommand = opIndex; | 246 fCurCommand = opIndex; |
205 | 247 |
206 if (fSkipCommands[fCurCommand]) { | 248 if (fSkipCommands[fCurCommand]) { |
207 return true; | 249 return true; |
208 } | 250 } |
209 | 251 |
210 fCurType = type; | 252 fCurType = type; |
211 // The SkDebugCanvas doesn't recognize these types. This class needs to | 253 // The SkDebugCanvas doesn't recognize these types. This class needs to |
212 // convert or else we'll wind up with a mismatch between the type counts | 254 // convert or else we'll wind up with a mismatch between the type counts |
213 // the debugger displays and the profile times. | 255 // the debugger displays and the profile times. |
214 if (DRAW_POS_TEXT_TOP_BOTTOM == type) { | 256 if (DRAW_POS_TEXT_TOP_BOTTOM == type) { |
215 fCurType = DRAW_POS_TEXT; | 257 fCurType = DRAW_POS_TEXT; |
216 } else if (DRAW_POS_TEXT_H_TOP_BOTTOM == type) { | 258 } else if (DRAW_POS_TEXT_H_TOP_BOTTOM == type) { |
217 fCurType = DRAW_POS_TEXT_H; | 259 fCurType = DRAW_POS_TEXT_H; |
218 } | 260 } |
219 | 261 |
220 #if defined(SK_BUILD_FOR_WIN32) | 262 #if defined(SK_BUILD_FOR_WIN32) |
221 // CPU timer doesn't work well on Windows | 263 // CPU timer doesn't work well on Windows |
222 fTimer.startWall(); | 264 fTimer.startWall(); |
223 #else | 265 #else |
224 fTimer.startCpu(); | 266 fTimer.startCpu(); |
225 #endif | 267 #endif |
226 | 268 |
227 return false; | 269 return false; |
228 } | 270 } |
229 | 271 |
230 virtual void postDraw(int opIndex) SK_OVERRIDE { | 272 void postDraw(int opIndex) { |
231 #if defined(SK_BUILD_FOR_WIN32) | 273 #if defined(SK_BUILD_FOR_WIN32) |
232 // CPU timer doesn't work well on Windows | 274 // CPU timer doesn't work well on Windows |
233 double time = fTimer.endWall(); | 275 double time = fTimer.endWall(); |
234 #else | 276 #else |
235 double time = fTimer.endCpu(); | 277 double time = fTimer.endCpu(); |
236 #endif | 278 #endif |
237 | 279 |
238 SkASSERT(opIndex == fCurCommand); | 280 SkASSERT(opIndex == fCurCommand); |
239 SkASSERT(fCurType <= LAST_DRAWTYPE_ENUM); | 281 SkASSERT(fCurType <= LAST_DRAWTYPE_ENUM); |
240 | 282 |
241 fTimes[fCurCommand] += time; | 283 fTimes[fCurCommand] += time; |
242 fTypeTimes[fCurType] += time; | 284 fTypeTimes[fCurType] += time; |
243 fTot += time; | 285 fTot += time; |
244 } | 286 } |
245 #endif | |
246 | 287 |
247 private: | 288 private: |
248 typedef SkPicturePlayback INHERITED; | 289 typedef SkPicturePlayback INHERITED; |
249 }; | 290 }; |
250 | 291 |
251 #if 0 | 292 #if 0 |
252 // Wrap SkPicture to allow installation of an SkTimedPicturePlayback object | 293 // Wrap SkPicture to allow installation of an SkTimedPicturePlayback object |
253 class SkTimedPicture : public SkPicture { | 294 class SkTimedPicture : public SkPicture { |
254 public: | 295 public: |
255 static SkTimedPicture* CreateTimedPicture(SkStream* stream, | 296 static SkTimedPicture* CreateTimedPicture(SkStream* stream, |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 } | 1108 } |
1068 | 1109 |
1069 // NOTE(chudy): Makes first item unselectable. | 1110 // NOTE(chudy): Makes first item unselectable. |
1070 QStandardItemModel* model = qobject_cast<QStandardItemModel*>( | 1111 QStandardItemModel* model = qobject_cast<QStandardItemModel*>( |
1071 fFilter.model()); | 1112 fFilter.model()); |
1072 QModelIndex firstIndex = model->index(0, fFilter.modelColumn(), | 1113 QModelIndex firstIndex = model->index(0, fFilter.modelColumn(), |
1073 fFilter.rootModelIndex()); | 1114 fFilter.rootModelIndex()); |
1074 QStandardItem* firstItem = model->itemFromIndex(firstIndex); | 1115 QStandardItem* firstItem = model->itemFromIndex(firstIndex); |
1075 firstItem->setSelectable(false); | 1116 firstItem->setSelectable(false); |
1076 } | 1117 } |
OLD | NEW |