1902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
2902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com/*
3902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * Copyright 2012 Google Inc.
4902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com *
5902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * Use of this source code is governed by a BSD-style license that can be
6902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com * found in the LICENSE file.
7902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com */
8902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
9607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com#include "SkDebugger.h"
10770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
112d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#include "SkString.h"
122d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
13902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com
145a2315e750f65a8b61faa509a65840c622f04424kkinnunenSkDebugger::SkDebugger()
155a2315e750f65a8b61faa509a65840c622f04424kkinnunen    : fPicture(NULL)
165a2315e750f65a8b61faa509a65840c622f04424kkinnunen    , fIndex(-1) {
17607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    // Create this some other dynamic way?
18a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    fDebugCanvas = new SkDebugCanvas(0, 0);
19607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com}
20607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com
21607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.comSkDebugger::~SkDebugger() {
22607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    // Need to inherit from SkRef object in order for following to work
23607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    SkSafeUnref(fDebugCanvas);
24607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    SkSafeUnref(fPicture);
25607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com}
26607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com
27607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.comvoid SkDebugger::loadPicture(SkPicture* picture) {
28a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkRefCnt_SafeAssign(fPicture, picture);
29a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips
30607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    delete fDebugCanvas;
31a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    fDebugCanvas = new SkDebugCanvas(SkScalarCeilToInt(this->pictureCull().width()),
32a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips                                     SkScalarCeilToInt(this->pictureCull().height()));
3357f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setPicture(picture);
34c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips    picture->playback(fDebugCanvas);
3557f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setPicture(NULL);
36607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    fIndex = fDebugCanvas->getSize() - 1;
37607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com}
38607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com
3925bc2f86c2b94ee1f0921d90e6629d8cb22f69b7robertphillips@google.comSkPicture* SkDebugger::copyPicture() {
4025bc2f86c2b94ee1f0921d90e6629d8cb22f69b7robertphillips@google.com    // We can't just call clone here since we want to removed the "deleted"
4125bc2f86c2b94ee1f0921d90e6629d8cb22f69b7robertphillips@google.com    // commands. Playing back will strip those out.
4284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com    SkPictureRecorder recorder;
43a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkCanvas* canvas = recorder.beginRecording(this->pictureCull().width(),
44a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips                                               this->pictureCull().height());
4557f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org
4657f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    bool vizMode = fDebugCanvas->getMegaVizMode();
4757f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setMegaVizMode(false);
4857f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    bool overDraw = fDebugCanvas->getOverdrawViz();
4957f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setOverdrawViz(false);
502a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org    bool pathOps = fDebugCanvas->getAllowSimplifyClip();
512a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org    fDebugCanvas->setAllowSimplifyClip(false);
5257f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org
53607357fde8a9c4c70549d4223e0bd1181b012e0echudy@google.com    fDebugCanvas->draw(canvas);
5457f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org
5557f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setMegaVizMode(vizMode);
5657f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org    fDebugCanvas->setOverdrawViz(overDraw);
572a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org    fDebugCanvas->setAllowSimplifyClip(pathOps);
5857f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org
5984b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com    return recorder.endRecording();
60902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com}
612d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
622d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.comvoid SkDebugger::getOverviewText(const SkTDArray<double>* typeTimes,
632d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com                                 double totTime,
64e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com                                 SkString* overview,
65e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com                                 int numRuns) {
662d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    const SkTDArray<SkDrawCommand*>& commands = this->getDrawCommands();
672d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
682d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    SkTDArray<int> counts;
699bafc30c7900375d316d47e24412ddfd8bd0b1f2robertphillips    counts.setCount(SkDrawCommand::kOpTypeCount);
709bafc30c7900375d316d47e24412ddfd8bd0b1f2robertphillips    for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) {
712d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        counts[i] = 0;
722d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    }
732d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
742d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    for (int i = 0; i < commands.count(); i++) {
752d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        counts[commands[i]->getType()]++;
762d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    }
772d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
782d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    overview->reset();
792d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    int total = 0;
802d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#ifdef SK_DEBUG
812d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    double totPercent = 0, tempSum = 0;
822d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#endif
839bafc30c7900375d316d47e24412ddfd8bd0b1f2robertphillips    for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) {
842d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        if (0 == counts[i]) {
852d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            // if there were no commands of this type then they should've consumed no time
862d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            SkASSERT(NULL == typeTimes || 0.0 == (*typeTimes)[i]);
872d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            continue;
882d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        }
892d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
909bafc30c7900375d316d47e24412ddfd8bd0b1f2robertphillips        overview->append(SkDrawCommand::GetCommandString((SkDrawCommand::OpType) i));
912d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append(": ");
92e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com        overview->appendS32(counts[i]);
9349f085dddff10473b6ebf832a974288300224e60bsalomon        if (typeTimes && totTime >= 0.0) {
942d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            overview->append(" - ");
95e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com            overview->appendf("%.2f", (*typeTimes)[i]/(float)numRuns);
962d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            overview->append("ms");
972d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            overview->append(" - ");
982d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            double percent = 100.0*(*typeTimes)[i]/totTime;
99e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com            overview->appendf("%.2f", percent);
1002d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            overview->append("%");
1012d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#ifdef SK_DEBUG
1022d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            totPercent += percent;
1032d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com            tempSum += (*typeTimes)[i];
1042d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#endif
1052d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        }
1062d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append("<br/>");
1072d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        total += counts[i];
1082d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    }
1092d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#ifdef SK_DEBUG
11049f085dddff10473b6ebf832a974288300224e60bsalomon    if (typeTimes) {
11191274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com        SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(totPercent),
112e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com                                     SkDoubleToScalar(100.0)));
11391274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com        SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(tempSum),
114e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com                                     SkDoubleToScalar(totTime)));
1152d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    }
1162d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#endif
1172d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
1182d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    if (totTime > 0.0) {
1192d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append("Total Time: ");
120e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com        overview->appendf("%.2f", totTime/(float)numRuns);
1212d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append("ms");
1222d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#ifdef SK_DEBUG
1232d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append(" ");
124e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com        overview->appendScalar(SkDoubleToScalar(totPercent));
1252d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append("% ");
1262d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com#endif
1272d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com        overview->append("<br/>");
1282d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    }
1292d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
1302d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    SkString totalStr;
1312d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    totalStr.append("Total Draw Commands: ");
132e428f9b1132c12299c204a333192495d7e748511robertphillips@google.com    totalStr.appendScalar(SkDoubleToScalar(total));
1332d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    totalStr.append("<br/>");
1342d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    overview->insert(0, totalStr);
1352d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com
136a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->append("<br/>SkPicture L: ");
137a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->appendScalar(this->pictureCull().fLeft);
138a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->append(" T: ");
139a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->appendScalar(this->pictureCull().fTop);
140a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->append(" R: ");
141a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->appendScalar(this->pictureCull().fRight);
142a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->append(" B: ");
143a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    overview->appendScalar(this->pictureCull().fBottom);
1442d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com    overview->append("<br/>");
1452d9dbd4f78314b4b36f67d6ebbf3e0f2d9a163e3borenet@google.com}
1462a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org
1472a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.orgvoid SkDebugger::getClipStackText(SkString* clipStack) {
1482a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org    clipStack->set(fDebugCanvas->clipStackData());
1492a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org}
150