| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "VulkanViewer.h" | 8 #include "VulkanViewer.h" | 
| 9 | 9 | 
| 10 #include "GMSlide.h" | 10 #include "GMSlide.h" | 
| 11 #include "SKPSlide.h" | 11 #include "SKPSlide.h" | 
| 12 | 12 | 
| 13 #include "SkCanvas.h" | 13 #include "SkCanvas.h" | 
| 14 #include "SkCommonFlags.h" | 14 #include "SkCommonFlags.h" | 
| 15 #include "SkOSFile.h" | 15 #include "SkOSFile.h" | 
| 16 #include "SkRandom.h" | 16 #include "SkRandom.h" | 
| 17 #include "SkStream.h" | 17 #include "SkStream.h" | 
| 18 | 18 | 
| 19 Application* Application::Create(int argc, char** argv, void* platformData) { | 19 Application* Application::Create(int argc, char** argv, void* platformData) { | 
| 20     return new VulkanViewer(argc, argv, platformData); | 20     return new VulkanViewer(argc, argv, platformData); | 
| 21 } | 21 } | 
| 22 | 22 | 
| 23 static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t m
     odifiers, | 23 static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t m
     odifiers, | 
| 24                            void* userData) { | 24                            void* userData) { | 
| 25     VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData); | 25     VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData); | 
| 26 | 26 | 
| 27     return vv->onKey(key, state, modifiers); | 27     return vv->onKey(key, state, modifiers); | 
| 28 } | 28 } | 
| 29 | 29 | 
|  | 30 static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) { | 
|  | 31     VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData); | 
|  | 32 | 
|  | 33     return vv->onChar(c, modifiers); | 
|  | 34 } | 
|  | 35 | 
| 30 static void on_paint_handler(SkCanvas* canvas, void* userData) { | 36 static void on_paint_handler(SkCanvas* canvas, void* userData) { | 
| 31     VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData); | 37     VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData); | 
| 32 | 38 | 
| 33     return vv->onPaint(canvas); | 39     return vv->onPaint(canvas); | 
| 34 } | 40 } | 
| 35 | 41 | 
| 36 DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); | 42 DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); | 
| 37 DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifyi
     ng this builder."); | 43 DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifyi
     ng this builder."); | 
| 38 DEFINE_string2(match, m, nullptr, | 44 DEFINE_string2(match, m, nullptr, | 
| 39                "[~][^]substring[$] [...] of bench name to run.\n" | 45                "[~][^]substring[$] [...] of bench name to run.\n" | 
| 40                "Multiple matches may be separated by spaces.\n" | 46                "Multiple matches may be separated by spaces.\n" | 
| 41                "~ causes a matching bench to always be skipped\n" | 47                "~ causes a matching bench to always be skipped\n" | 
| 42                "^ requires the start of the bench to match\n" | 48                "^ requires the start of the bench to match\n" | 
| 43                "$ requires the end of the bench to match\n" | 49                "$ requires the end of the bench to match\n" | 
| 44                "^ and $ requires an exact match\n" | 50                "^ and $ requires an exact match\n" | 
| 45                "If a bench does not match any list entry,\n" | 51                "If a bench does not match any list entry,\n" | 
| 46                "it is skipped unless some list entry starts with ~"); | 52                "it is skipped unless some list entry starts with ~"); | 
| 47 DEFINE_string(skps, "skps", "Directory to read skps from."); | 53 DEFINE_string(skps, "skps", "Directory to read skps from."); | 
| 48 | 54 | 
| 49 | 55 VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) | 
| 50 | 56     : fCurrentMeasurement(0) | 
| 51 | 57     , fDisplayStats(false) | 
| 52 | 58 { | 
| 53 |  | 
| 54 VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) : fCurrent
     Measurement(0) { |  | 
| 55     memset(fMeasurements, 0, sizeof(fMeasurements)); | 59     memset(fMeasurements, 0, sizeof(fMeasurements)); | 
| 56 | 60 | 
| 57     SkDebugf("Command line arguments: "); | 61     SkDebugf("Command line arguments: "); | 
| 58     for (int i = 1; i < argc; ++i) { | 62     for (int i = 1; i < argc; ++i) { | 
| 59         SkDebugf("%s ", argv[i]); | 63         SkDebugf("%s ", argv[i]); | 
| 60     } | 64     } | 
| 61     SkDebugf("\n"); | 65     SkDebugf("\n"); | 
| 62 | 66 | 
| 63     SkCommandLineFlags::Parse(argc, argv); | 67     SkCommandLineFlags::Parse(argc, argv); | 
| 64 | 68 | 
| 65     fWindow = Window::CreateNativeWindow(platformData); | 69     fWindow = Window::CreateNativeWindow(platformData); | 
| 66     fWindow->attach(Window::kVulkan_BackendType, 0, nullptr); | 70     fWindow->attach(Window::kVulkan_BackendType, 0, nullptr); | 
| 67 | 71 | 
| 68     // register callbacks | 72     // register callbacks | 
| 69     fWindow->registerKeyFunc(on_key_handler, this); | 73     fWindow->registerKeyFunc(on_key_handler, this); | 
|  | 74     fWindow->registerCharFunc(on_char_handler, this); | 
| 70     fWindow->registerPaintFunc(on_paint_handler, this); | 75     fWindow->registerPaintFunc(on_paint_handler, this); | 
| 71 | 76 | 
| 72     // set up slides | 77     // set up slides | 
| 73     this->initSlides(); | 78     this->initSlides(); | 
| 74 | 79 | 
| 75     // set up first frame | 80     // set up first frame | 
| 76     SkString title("VulkanViewer: "); |  | 
| 77     title.append(fSlides[0]->getName()); |  | 
| 78     fCurrentSlide = 0; | 81     fCurrentSlide = 0; | 
| 79     fWindow->setTitle(title.c_str()); | 82     setupCurrentSlide(-1); | 
|  | 83     fLocalMatrix.reset(); | 
|  | 84 | 
| 80     fWindow->show(); | 85     fWindow->show(); | 
| 81 } | 86 } | 
| 82 | 87 | 
| 83 static sk_sp<SkPicture> read_picture(const char path[]) { |  | 
| 84     if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { |  | 
| 85         return nullptr; |  | 
| 86     } |  | 
| 87 |  | 
| 88     SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); |  | 
| 89     if (stream.get() == nullptr) { |  | 
| 90         SkDebugf("Could not read %s.\n", path); |  | 
| 91         return nullptr; |  | 
| 92     } |  | 
| 93 |  | 
| 94     auto pic = SkPicture::MakeFromStream(stream.get()); |  | 
| 95     if (!pic) { |  | 
| 96         SkDebugf("Could not read %s as an SkPicture.\n", path); |  | 
| 97     } |  | 
| 98     return pic; |  | 
| 99 } |  | 
| 100 |  | 
| 101 |  | 
| 102 static sk_sp<SKPSlide> loadSKP(const SkString& path) { |  | 
| 103     sk_sp<SkPicture> pic = read_picture(path.c_str()); |  | 
| 104     if (!pic) { |  | 
| 105         return nullptr; |  | 
| 106     } |  | 
| 107 |  | 
| 108     SkString name = SkOSPath::Basename(path.c_str()); |  | 
| 109     return sk_sp<SKPSlide>(new SKPSlide(name.c_str(), pic)); |  | 
| 110 } |  | 
| 111 |  | 
| 112 void VulkanViewer::initSlides() { | 88 void VulkanViewer::initSlides() { | 
| 113     const skiagm::GMRegistry* gms(skiagm::GMRegistry::Head()); | 89     const skiagm::GMRegistry* gms(skiagm::GMRegistry::Head()); | 
| 114     while (gms) { | 90     while (gms) { | 
| 115         SkAutoTDelete<skiagm::GM> gm(gms->factory()(nullptr)); | 91         SkAutoTDelete<skiagm::GM> gm(gms->factory()(nullptr)); | 
| 116 | 92 | 
| 117         if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) { | 93         if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) { | 
| 118             sk_sp<Slide> slide(new GMSlide(gm.release())); | 94             sk_sp<Slide> slide(new GMSlide(gm.release())); | 
| 119             fSlides.push_back(slide); | 95             fSlides.push_back(slide); | 
| 120         } | 96         } | 
| 121 | 97 | 
| 122         gms = gms->next(); | 98         gms = gms->next(); | 
| 123     } | 99     } | 
| 124 | 100 | 
| 125     // reverse array | 101     // reverse array | 
| 126     for (int i = 0; i < fSlides.count()/2; ++i) { | 102     for (int i = 0; i < fSlides.count()/2; ++i) { | 
| 127         sk_sp<Slide> temp = fSlides[i]; | 103         sk_sp<Slide> temp = fSlides[i]; | 
| 128         fSlides[i] = fSlides[fSlides.count() - i - 1]; | 104         fSlides[i] = fSlides[fSlides.count() - i - 1]; | 
| 129         fSlides[fSlides.count() - i - 1] = temp; | 105         fSlides[fSlides.count() - i - 1] = temp; | 
| 130     } | 106     } | 
| 131 | 107 | 
| 132     // SKPs | 108     // SKPs | 
| 133     for (int i = 0; i < FLAGS_skps.count(); i++) { | 109     for (int i = 0; i < FLAGS_skps.count(); i++) { | 
| 134         if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { | 110         if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { | 
|  | 111             if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) { | 
|  | 112                 continue; | 
|  | 113             } | 
|  | 114 | 
| 135             SkString path(FLAGS_skps[i]); | 115             SkString path(FLAGS_skps[i]); | 
| 136             sk_sp<SKPSlide> slide = loadSKP(path); | 116             sk_sp<SKPSlide> slide(new SKPSlide(SkOSPath::Basename(path.c_str()),
      path)); | 
| 137             if (slide) { | 117             if (slide) { | 
| 138                 fSlides.push_back(slide); | 118                 fSlides.push_back(slide); | 
| 139             } | 119             } | 
| 140         } else { | 120         } else { | 
| 141             SkOSFile::Iter it(FLAGS_skps[i], ".skp"); | 121             SkOSFile::Iter it(FLAGS_skps[i], ".skp"); | 
| 142             SkString path; | 122             SkString skpName; | 
| 143             while (it.next(&path)) { | 123             while (it.next(&skpName)) { | 
| 144                 SkString skpName = SkOSPath::Join(FLAGS_skps[i], path.c_str()); | 124                 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, skpName.c_str())
     ) { | 
| 145                 sk_sp<SKPSlide> slide = loadSKP(skpName); | 125                     continue; | 
|  | 126                 } | 
|  | 127 | 
|  | 128                 SkString path = SkOSPath::Join(FLAGS_skps[i], skpName.c_str()); | 
|  | 129                 sk_sp<SKPSlide> slide(new SKPSlide(skpName, path)); | 
| 146                 if (slide) { | 130                 if (slide) { | 
| 147                     fSlides.push_back(slide); | 131                     fSlides.push_back(slide); | 
| 148                 } | 132                 } | 
| 149             } | 133             } | 
| 150         } | 134         } | 
| 151     } | 135     } | 
| 152 } | 136 } | 
| 153 | 137 | 
| 154 | 138 | 
| 155 VulkanViewer::~VulkanViewer() { | 139 VulkanViewer::~VulkanViewer() { | 
| 156     fWindow->detach(); | 140     fWindow->detach(); | 
| 157     delete fWindow; | 141     delete fWindow; | 
| 158 } | 142 } | 
| 159 | 143 | 
|  | 144 void VulkanViewer::setupCurrentSlide(int previousSlide) { | 
|  | 145     SkString title("VulkanViewer: "); | 
|  | 146     title.append(fSlides[fCurrentSlide]->getName()); | 
|  | 147     fSlides[fCurrentSlide]->load(); | 
|  | 148     if (previousSlide >= 0) { | 
|  | 149         fSlides[previousSlide]->unload(); | 
|  | 150     } | 
|  | 151     fWindow->setTitle(title.c_str()); | 
|  | 152     fWindow->inval(); | 
|  | 153 } | 
|  | 154 | 
|  | 155 #define MAX_ZOOM_LEVEL  8 | 
|  | 156 #define MIN_ZOOM_LEVEL  -8 | 
|  | 157 | 
|  | 158 void VulkanViewer::changeZoomLevel(float delta) { | 
|  | 159     fZoomLevel += delta; | 
|  | 160     if (fZoomLevel > 0) { | 
|  | 161         fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL); | 
|  | 162         fZoomScale = fZoomLevel + SK_Scalar1; | 
|  | 163     } else if (fZoomLevel < 0) { | 
|  | 164         fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL); | 
|  | 165         fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel); | 
|  | 166     } else { | 
|  | 167         fZoomScale = SK_Scalar1; | 
|  | 168     } | 
|  | 169     this->updateMatrix(); | 
|  | 170 } | 
|  | 171 | 
|  | 172 void VulkanViewer::updateMatrix(){ | 
|  | 173     SkMatrix m; | 
|  | 174     m.reset(); | 
|  | 175 | 
|  | 176     if (fZoomLevel) { | 
|  | 177         SkPoint center; | 
|  | 178         //m = this->getLocalMatrix();//.invert(&m); | 
|  | 179         m.mapXY(fZoomCenterX, fZoomCenterY, ¢er); | 
|  | 180         SkScalar cx = center.fX; | 
|  | 181         SkScalar cy = center.fY; | 
|  | 182 | 
|  | 183         m.setTranslate(-cx, -cy); | 
|  | 184         m.postScale(fZoomScale, fZoomScale); | 
|  | 185         m.postTranslate(cx, cy); | 
|  | 186     } | 
|  | 187 | 
|  | 188     // TODO: add gesture support | 
|  | 189     // Apply any gesture matrix | 
|  | 190     //m.preConcat(fGesture.localM()); | 
|  | 191     //m.preConcat(fGesture.globalM()); | 
|  | 192 | 
|  | 193     fLocalMatrix = m; | 
|  | 194 } | 
|  | 195 | 
| 160 bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t mod
     ifiers) { | 196 bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t mod
     ifiers) { | 
| 161     if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_Mo
     difierKey)) { | 197     if (Window::kDown_InputState == state) { | 
| 162         if (key == Window::kRight_Key) { | 198         switch (key) { | 
| 163             fCurrentSlide++; | 199             case Window::kRight_Key: { | 
| 164             if (fCurrentSlide >= fSlides.count()) { | 200                 int previousSlide = fCurrentSlide; | 
| 165                 fCurrentSlide = 0; | 201                 fCurrentSlide++; | 
|  | 202                 if (fCurrentSlide >= fSlides.count()) { | 
|  | 203                     fCurrentSlide = 0; | 
|  | 204                 } | 
|  | 205                 setupCurrentSlide(previousSlide); | 
|  | 206                 return true; | 
| 166             } | 207             } | 
| 167             SkString title("VulkanViewer: "); | 208 | 
| 168             title.append(fSlides[fCurrentSlide]->getName()); | 209             case Window::kLeft_Key: { | 
| 169             fWindow->setTitle(title.c_str()); | 210                 int previousSlide = fCurrentSlide; | 
| 170         } else if (key == Window::kLeft_Key) { | 211                 fCurrentSlide--; | 
| 171             fCurrentSlide--; | 212                 if (fCurrentSlide < 0) { | 
| 172             if (fCurrentSlide < 0) { | 213                     fCurrentSlide = fSlides.count() - 1; | 
| 173                 fCurrentSlide = fSlides.count()-1; | 214                 } | 
|  | 215                 SkString title("VulkanViewer: "); | 
|  | 216                 title.append(fSlides[fCurrentSlide]->getName()); | 
|  | 217                 fWindow->setTitle(title.c_str()); | 
|  | 218                 setupCurrentSlide(previousSlide); | 
|  | 219                 return true; | 
| 174             } | 220             } | 
| 175             SkString title("VulkanViewer: "); | 221 | 
| 176             title.append(fSlides[fCurrentSlide]->getName()); | 222             case Window::kUp_Key: { | 
| 177             fWindow->setTitle(title.c_str()); | 223                 this->changeZoomLevel(1.f / 32.f); | 
|  | 224                 return true; | 
|  | 225             } | 
|  | 226 | 
|  | 227             case Window::kDown_Key: { | 
|  | 228                 this->changeZoomLevel(-1.f / 32.f); | 
|  | 229                 return true; | 
|  | 230             } | 
|  | 231 | 
|  | 232             default: | 
|  | 233                 break; | 
| 178         } | 234         } | 
| 179     } | 235     } | 
| 180 | 236 | 
| 181     return true; | 237     return false; | 
|  | 238 } | 
|  | 239 | 
|  | 240 bool VulkanViewer::onChar(SkUnichar c, uint32_t modifiers) { | 
|  | 241     if ('s' == c) { | 
|  | 242         fDisplayStats = !fDisplayStats; | 
|  | 243         return true; | 
|  | 244     } | 
|  | 245 | 
|  | 246     return false; | 
| 182 } | 247 } | 
| 183 | 248 | 
| 184 void VulkanViewer::onPaint(SkCanvas* canvas) { | 249 void VulkanViewer::onPaint(SkCanvas* canvas) { | 
| 185 | 250 | 
| 186     canvas->clear(SK_ColorWHITE); | 251     canvas->clear(SK_ColorWHITE); | 
| 187 | 252 | 
| 188     canvas->save(); | 253     int count = canvas->save(); | 
|  | 254     canvas->setMatrix(fLocalMatrix); | 
|  | 255 | 
| 189     fSlides[fCurrentSlide]->draw(canvas); | 256     fSlides[fCurrentSlide]->draw(canvas); | 
| 190     canvas->restore(); | 257     canvas->restoreToCount(count); | 
| 191 | 258 | 
| 192     drawStats(canvas); | 259     if (fDisplayStats) { | 
|  | 260         drawStats(canvas); | 
|  | 261     } | 
| 193 } | 262 } | 
| 194 | 263 | 
| 195 void VulkanViewer::drawStats(SkCanvas* canvas) { | 264 void VulkanViewer::drawStats(SkCanvas* canvas) { | 
| 196     static const float kPixelPerMS = 2.0f; | 265     static const float kPixelPerMS = 2.0f; | 
| 197     static const int kDisplayWidth = 130; | 266     static const int kDisplayWidth = 130; | 
| 198     static const int kDisplayHeight = 100; | 267     static const int kDisplayHeight = 100; | 
| 199     static const int kDisplayPadding = 10; | 268     static const int kDisplayPadding = 10; | 
| 200     static const int kGraphPadding = 3; | 269     static const int kGraphPadding = 3; | 
| 201     static const SkScalar kBaseMS = 1000.f / 60.f;  // ms/frame to hit 60 fps | 270     static const SkScalar kBaseMS = 1000.f / 60.f;  // ms/frame to hit 60 fps | 
| 202 | 271 | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 233 | 302 | 
| 234     canvas->restore(); | 303     canvas->restore(); | 
| 235 } | 304 } | 
| 236 | 305 | 
| 237 void VulkanViewer::onIdle(double ms) { | 306 void VulkanViewer::onIdle(double ms) { | 
| 238     // Record measurements | 307     // Record measurements | 
| 239     fMeasurements[fCurrentMeasurement++] = ms; | 308     fMeasurements[fCurrentMeasurement++] = ms; | 
| 240     fCurrentMeasurement &= (kMeasurementCount - 1);  // fast mod | 309     fCurrentMeasurement &= (kMeasurementCount - 1);  // fast mod | 
| 241     SkASSERT(fCurrentMeasurement < kMeasurementCount); | 310     SkASSERT(fCurrentMeasurement < kMeasurementCount); | 
| 242 | 311 | 
| 243     fWindow->onPaint(); | 312     fAnimTimer.updateTime(); | 
|  | 313     if (fDisplayStats || fSlides[fCurrentSlide]->animate(fAnimTimer)) { | 
|  | 314         fWindow->inval(); | 
|  | 315     } | 
| 244 } | 316 } | 
| OLD | NEW | 
|---|