Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: tools/skpbench/skpbench.cpp

Issue 2376043002: skpbench: use double buffering instead of triple (Closed)
Patch Set: rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrContextFactory.h" 8 #include "GrContextFactory.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkOSFile.h" 10 #include "SkOSFile.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 Sample() : fFrames(0), fDuration(0) {} 53 Sample() : fFrames(0), fDuration(0) {}
54 double seconds() const { return std::chrono::duration<double>(fDuration).cou nt(); } 54 double seconds() const { return std::chrono::duration<double>(fDuration).cou nt(); }
55 double ms() const { return std::chrono::duration<double, std::milli>(fDurati on).count(); } 55 double ms() const { return std::chrono::duration<double, std::milli>(fDurati on).count(); }
56 double value() const { return FLAGS_fps ? fFrames / this->seconds() : this-> ms() / fFrames; } 56 double value() const { return FLAGS_fps ? fFrames / this->seconds() : this-> ms() / fFrames; }
57 static const char* metric() { return FLAGS_fps ? "fps" : "ms"; } 57 static const char* metric() { return FLAGS_fps ? "fps" : "ms"; }
58 58
59 int fFrames; 59 int fFrames;
60 clock::duration fDuration; 60 clock::duration fDuration;
61 }; 61 };
62 62
63 class GpuSync {
64 public:
65 GpuSync(const SkGpuFenceSync* fenceSync);
66 ~GpuSync();
67
68 void syncToPreviousFrame();
69
70 private:
71 void updateFence();
72
73 const SkGpuFenceSync* const fFenceSync;
74 SkPlatformGpuFence fFence;
75 };
76
63 enum class ExitErr { 77 enum class ExitErr {
64 kOk = 0, 78 kOk = 0,
65 kUsage = 64, 79 kUsage = 64,
66 kData = 65, 80 kData = 65,
67 kUnavailable = 69, 81 kUnavailable = 69,
68 kIO = 74, 82 kIO = 74,
69 kSoftware = 70 83 kSoftware = 70
70 }; 84 };
71 85
72 static void draw_skp_and_flush(SkCanvas*, const SkPicture*); 86 static void draw_skp_and_flush(SkCanvas*, const SkPicture*);
73 static SkPlatformGpuFence insert_verified_fence(const SkGpuFenceSync*);
74 static void wait_fence_and_delete(const SkGpuFenceSync*, SkPlatformGpuFence);
75 static bool mkdir_p(const SkString& name); 87 static bool mkdir_p(const SkString& name);
76 static SkString join(const SkCommandLineFlags::StringArray&); 88 static SkString join(const SkCommandLineFlags::StringArray&);
77 static void exitf(ExitErr, const char* format, ...); 89 static void exitf(ExitErr, const char* format, ...);
78 90
79 static void run_benchmark(const SkGpuFenceSync* sync, SkCanvas* canvas, const Sk Picture* skp, 91 static void run_benchmark(const SkGpuFenceSync* fenceSync, SkCanvas* canvas, con st SkPicture* skp,
80 std::vector<Sample>* samples) { 92 std::vector<Sample>* samples) {
81 using clock = Sample::clock; 93 using clock = Sample::clock;
82 const clock::duration sampleDuration = std::chrono::milliseconds(FLAGS_sampl eMs); 94 const clock::duration sampleDuration = std::chrono::milliseconds(FLAGS_sampl eMs);
83 const clock::duration benchDuration = std::chrono::milliseconds(FLAGS_durati on); 95 const clock::duration benchDuration = std::chrono::milliseconds(FLAGS_durati on);
84 96
85 // Prime the graphics pipe. 97 draw_skp_and_flush(canvas, skp);
86 SkPlatformGpuFence frameN_minus_2, frameN_minus_1; 98 GpuSync gpuSync(fenceSync);
87 {
88 draw_skp_and_flush(canvas, skp);
89 SkPlatformGpuFence frame0 = insert_verified_fence(sync);
90 99
91 draw_skp_and_flush(canvas, skp); 100 draw_skp_and_flush(canvas, skp);
92 frameN_minus_2 = insert_verified_fence(sync); 101 gpuSync.syncToPreviousFrame();
93
94 draw_skp_and_flush(canvas, skp);
95 frameN_minus_1 = insert_verified_fence(sync);
96
97 wait_fence_and_delete(sync, frame0);
98 }
99 102
100 clock::time_point now = clock::now(); 103 clock::time_point now = clock::now();
101 const clock::time_point endTime = now + benchDuration; 104 const clock::time_point endTime = now + benchDuration;
102 105
103 do { 106 do {
104 clock::time_point sampleStart = now; 107 clock::time_point sampleStart = now;
105 samples->emplace_back(); 108 samples->emplace_back();
106 Sample& sample = samples->back(); 109 Sample& sample = samples->back();
107 110
108 do { 111 do {
109 draw_skp_and_flush(canvas, skp); 112 draw_skp_and_flush(canvas, skp);
110 113 gpuSync.syncToPreviousFrame();
111 // Sync the GPU.
112 wait_fence_and_delete(sync, frameN_minus_2);
113 frameN_minus_2 = frameN_minus_1;
114 frameN_minus_1 = insert_verified_fence(sync);
115 114
116 now = clock::now(); 115 now = clock::now();
117 sample.fDuration = now - sampleStart; 116 sample.fDuration = now - sampleStart;
118 ++sample.fFrames; 117 ++sample.fFrames;
119 } while (sample.fDuration < sampleDuration); 118 } while (sample.fDuration < sampleDuration);
120 } while (now < endTime || 0 == samples->size() % 2); 119 } while (now < endTime || 0 == samples->size() % 2);
121
122 sync->deleteFence(frameN_minus_2);
123 sync->deleteFence(frameN_minus_1);
124 } 120 }
125 121
126 void print_result(const std::vector<Sample>& samples, const char* config, const char* bench) { 122 void print_result(const std::vector<Sample>& samples, const char* config, const char* bench) {
127 if (0 == (samples.size() % 2)) { 123 if (0 == (samples.size() % 2)) {
128 exitf(ExitErr::kSoftware, "attempted to gather stats on even number of s amples"); 124 exitf(ExitErr::kSoftware, "attempted to gather stats on even number of s amples");
129 } 125 }
130 126
131 Sample accum = Sample(); 127 Sample accum = Sample();
132 std::vector<double> values; 128 std::vector<double> values;
133 values.reserve(samples.size()); 129 values.reserve(samples.size());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 265 }
270 266
271 exit(0); 267 exit(0);
272 } 268 }
273 269
274 static void draw_skp_and_flush(SkCanvas* canvas, const SkPicture* skp) { 270 static void draw_skp_and_flush(SkCanvas* canvas, const SkPicture* skp) {
275 canvas->drawPicture(skp); 271 canvas->drawPicture(skp);
276 canvas->flush(); 272 canvas->flush();
277 } 273 }
278 274
279 static SkPlatformGpuFence insert_verified_fence(const SkGpuFenceSync* sync) {
280 SkPlatformGpuFence fence = sync->insertFence();
281 if (kInvalidPlatformGpuFence == fence) {
282 exitf(ExitErr::kUnavailable, "failed to insert fence");
283 }
284 return fence;
285 }
286
287 static void wait_fence_and_delete(const SkGpuFenceSync* sync, SkPlatformGpuFence fence) {
288 if (kInvalidPlatformGpuFence == fence) {
289 exitf(ExitErr::kSoftware, "attempted to wait on invalid fence");
290 }
291 if (!sync->waitFence(fence)) {
292 exitf(ExitErr::kUnavailable, "failed to wait for fence");
293 }
294 sync->deleteFence(fence);
295 }
296
297 bool mkdir_p(const SkString& dirname) { 275 bool mkdir_p(const SkString& dirname) {
298 if (dirname.isEmpty()) { 276 if (dirname.isEmpty()) {
299 return true; 277 return true;
300 } 278 }
301 return mkdir_p(SkOSPath::Dirname(dirname.c_str())) && sk_mkdir(dirname.c_str ()); 279 return mkdir_p(SkOSPath::Dirname(dirname.c_str())) && sk_mkdir(dirname.c_str ());
302 } 280 }
303 281
304 static SkString join(const SkCommandLineFlags::StringArray& stringArray) { 282 static SkString join(const SkCommandLineFlags::StringArray& stringArray) {
305 SkString joined; 283 SkString joined;
306 for (int i = 0; i < FLAGS_config.count(); ++i) { 284 for (int i = 0; i < FLAGS_config.count(); ++i) {
307 joined.appendf(i ? " %s" : "%s", FLAGS_config[i]); 285 joined.appendf(i ? " %s" : "%s", FLAGS_config[i]);
308 } 286 }
309 return joined; 287 return joined;
310 } 288 }
311 289
312 static void exitf(ExitErr err, const char* format, ...) { 290 static void exitf(ExitErr err, const char* format, ...) {
313 fprintf(stderr, ExitErr::kSoftware == err ? "INTERNAL ERROR: " : "ERROR: "); 291 fprintf(stderr, ExitErr::kSoftware == err ? "INTERNAL ERROR: " : "ERROR: ");
314 va_list args; 292 va_list args;
315 va_start(args, format); 293 va_start(args, format);
316 vfprintf(stderr, format, args); 294 vfprintf(stderr, format, args);
317 va_end(args); 295 va_end(args);
318 fprintf(stderr, ExitErr::kSoftware == err ? "; this should never happen.\n": ".\n"); 296 fprintf(stderr, ExitErr::kSoftware == err ? "; this should never happen.\n": ".\n");
319 exit((int)err); 297 exit((int)err);
320 } 298 }
299
300 GpuSync::GpuSync(const SkGpuFenceSync* fenceSync)
301 : fFenceSync(fenceSync) {
302 this->updateFence();
303 }
304
305 GpuSync::~GpuSync() {
306 fFenceSync->deleteFence(fFence);
307 }
308
309 void GpuSync::syncToPreviousFrame() {
310 if (kInvalidPlatformGpuFence == fFence) {
311 exitf(ExitErr::kSoftware, "attempted to sync with invalid fence");
312 }
313 if (!fFenceSync->waitFence(fFence)) {
314 exitf(ExitErr::kUnavailable, "failed to wait for fence");
315 }
316 fFenceSync->deleteFence(fFence);
317 this->updateFence();
318 }
319
320 void GpuSync::updateFence() {
321 fFence = fFenceSync->insertFence();
322 if (kInvalidPlatformGpuFence == fFence) {
323 exitf(ExitErr::kUnavailable, "failed to insert fence");
324 }
325 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698