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

Side by Side Diff: bench/benchmain.cpp

Issue 26489003: Insert swapbuffers into GPU benchmarks. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: remote resetGpuContext Created 7 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 | Annotate | Revision Log
« 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 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #if SK_SUPPORT_GPU 9 #if SK_SUPPORT_GPU
10 #include "GrContext.h" 10 #include "GrContext.h"
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 if (kGPU_Backend == config.backend) { 558 if (kGPU_Backend == config.backend) {
559 contextHelper = gContextFactory.getGLContext(config.contextType) ; 559 contextHelper = gContextFactory.getGLContext(config.contextType) ;
560 } 560 }
561 BenchTimer timer(contextHelper); 561 BenchTimer timer(contextHelper);
562 #else 562 #else
563 BenchTimer timer; 563 BenchTimer timer;
564 #endif 564 #endif
565 565
566 double previous = std::numeric_limits<double>::infinity(); 566 double previous = std::numeric_limits<double>::infinity();
567 bool converged = false; 567 bool converged = false;
568 bench->setLoops(0); 568
569 // variables used to compute loopsPerFrame
570 double frameIntervalTime = 0.0f;
571 int frameIntervalTotalLoops = 0;
572
573 bool frameIntervalComputed = false;
574 int loopsPerFrame = 0;
575 int loopsPerIter = 0;
569 if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.na me); } 576 if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.na me); }
570 do { 577 do {
571 // Ramp up 1 -> 4 -> 16 -> ... -> ~1 billion. 578 // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion.
572 const int loops = bench->getLoops(); 579 loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2;
573 if (loops >= (1<<30) || timer.fWall > FLAGS_maxMs) { 580 if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) {
574 // If you find it takes more than a billion loops to get up to 20ms of runtime, 581 // If you find it takes more than a billion loops to get up to 20ms of runtime,
575 // you've got a computer clocked at several THz or have a br oken benchmark. ;) 582 // you've got a computer clocked at several THz or have a br oken benchmark. ;)
576 // "1B ought to be enough for anybody." 583 // "1B ought to be enough for anybody."
577 logger.logError(SkStringPrintf( 584 logger.logError(SkStringPrintf(
578 "Can't get %s %s to converge in %dms.\n", 585 "\nCan't get %s %s to converge in %dms (%d loops)",
579 bench->getName(), config.name, FLAGS_maxMs)); 586 bench->getName(), config.name, FLAGS_maxMs, loopsPerIte r));
580 break; 587 break;
581 } 588 }
582 bench->setLoops(loops == 0 ? 1 : loops * 2);
583 589
584 if ((benchMode == kRecord_BenchMode || benchMode == kPictureReco rd_BenchMode)) { 590 if ((benchMode == kRecord_BenchMode || benchMode == kPictureReco rd_BenchMode)) {
585 // Clear the recorded commands so that they do not accumulat e. 591 // Clear the recorded commands so that they do not accumulat e.
586 canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecord Flags)); 592 canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecord Flags));
587 } 593 }
588 594
589 timer.start(); 595 timer.start();
590 if (NULL != canvas) { 596 if (NULL != canvas) {
591 canvas->save(); 597 canvas->save();
592 } 598 }
593 if (benchMode == kPictureRecord_BenchMode) {
594 recordFrom.draw(canvas);
595 } else {
596 bench->draw(canvas);
597 }
598 599
599 if (kDeferredSilent_BenchMode == benchMode) { 600 // Inner loop that allows us to break the run into smaller
600 static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush(); 601 // chunks (e.g. frames). This is especially useful for the GPU
601 } else if (NULL != canvas) { 602 // as we can flush and/or swap buffers to keep the GPU from
602 canvas->flush(); 603 // queuing up too much work.
604 for (int loopCount = loopsPerIter; loopCount > 0; ) {
605 if (frameIntervalComputed && loopCount > loopsPerFrame) {
606 bench->setLoops(loopsPerFrame);
607 loopCount -= loopsPerFrame;
608 } else {
609 bench->setLoops(loopCount);
610 loopCount = 0;
611 }
612
613 if (benchMode == kPictureRecord_BenchMode) {
614 recordFrom.draw(canvas);
615 } else {
616 bench->draw(canvas);
617 }
618
619 if (kDeferredSilent_BenchMode == benchMode) {
620 static_cast<SkDeferredCanvas*>(canvas.get())->silentFlus h();
621 } else if (NULL != canvas) {
622 canvas->flush();
623 }
624
625 #if SK_SUPPORT_GPU
626 // swap drawing buffers on each frame to prevent the GPU
627 // from queuing up too much work
628 if (NULL != glContext) {
629 glContext->swapBuffers();
630 }
631 #endif
603 } 632 }
604 633
605 if (NULL != canvas) { 634 if (NULL != canvas) {
606 canvas->restore(); 635 canvas->restore();
607 } 636 }
608 637
609 638
610 // Stop truncated timers before GL calls complete, and stop the full timers after. 639 // Stop truncated timers before GL calls complete, and stop the full timers after.
611 timer.truncatedEnd(); 640 timer.truncatedEnd();
612 #if SK_SUPPORT_GPU 641 #if SK_SUPPORT_GPU
613 if (NULL != glContext) { 642 if (NULL != glContext) {
614 context->flush(); 643 context->flush();
615 SK_GL(*glContext, Finish()); 644 SK_GL(*glContext, Finish());
616 } 645 }
617 #endif 646 #endif
618 timer.end(); 647 timer.end();
619 const double current = timer.fWall / bench->getLoops(); 648
649 #if SK_SUPPORT_GPU
650 // currently we only setup the frame interval for the GPU
651 if (!frameIntervalComputed && NULL != glContext) {
652 frameIntervalTime += timer.fWall;
653 frameIntervalTotalLoops += loopsPerIter;
654 if (frameIntervalTime >= FLAGS_minMs) {
655 frameIntervalComputed = true;
656 loopsPerFrame =
657 ((double)frameIntervalTotalLoops / frameIntervalTime ) * FLAGS_minMs;
658 if (loopsPerFrame < 1) {
659 loopsPerFrame = 1;
660 }
661 // SkDebugf(" %s has %d loops in %f ms (normalized to %d )\n",
662 // bench->getName(), frameIntervalTotalLoops,
663 // timer.fWall, loopsPerFrame);
664 }
665 }
666 #endif
667 const double current = timer.fWall / loopsPerIter;
620 if (FLAGS_verbose && current > previous) { SkDebugf("↑"); } 668 if (FLAGS_verbose && current > previous) { SkDebugf("↑"); }
621 if (FLAGS_verbose) { SkDebugf("%.3g ", current); } 669 if (FLAGS_verbose) { SkDebugf("%.3g ", current); }
622 converged = HasConverged(previous, current, timer.fWall); 670 converged = HasConverged(previous, current, timer.fWall);
623 previous = current; 671 previous = current;
624 } while (!kIsDebug && !converged); 672 } while (!kIsDebug && !converged);
625 if (FLAGS_verbose) { SkDebugf("\n"); } 673 if (FLAGS_verbose) { SkDebugf("\n"); }
626 674
627 if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) { 675 if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) {
628 saveFile(bench->getName(), 676 saveFile(bench->getName(),
629 config.name, 677 config.name,
630 FLAGS_outDir[0], 678 FLAGS_outDir[0],
631 device->accessBitmap(false)); 679 device->accessBitmap(false));
632 } 680 }
633 681
634 if (kIsDebug) { 682 if (kIsDebug) {
635 // Let's not mislead ourselves by looking at Debug build bench t imes! 683 // Let's not mislead ourselves by looking at Debug build bench t imes!
636 continue; 684 continue;
637 } 685 }
638 686
639 // Normalize to ms per 1000 iterations. 687 // Normalize to ms per 1000 iterations.
640 const double normalize = 1000.0 / bench->getLoops(); 688 const double normalize = 1000.0 / loopsPerIter;
641 const struct { char shortName; const char* longName; double ms; } ti mes[] = { 689 const struct { char shortName; const char* longName; double ms; } ti mes[] = {
642 {'w', "msecs", normalize * timer.fWall}, 690 {'w', "msecs", normalize * timer.fWall},
643 {'W', "Wmsecs", normalize * timer.fTruncatedWall}, 691 {'W', "Wmsecs", normalize * timer.fTruncatedWall},
644 {'c', "cmsecs", normalize * timer.fCpu}, 692 {'c', "cmsecs", normalize * timer.fCpu},
645 {'C', "Cmsecs", normalize * timer.fTruncatedCpu}, 693 {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
646 {'g', "gmsecs", normalize * timer.fGpu}, 694 {'g', "gmsecs", normalize * timer.fGpu},
647 }; 695 };
648 696
649 SkString result; 697 SkString result;
650 result.appendf(" %s:", config.name); 698 result.appendf(" %s:", config.name);
(...skipping 13 matching lines...) Expand all
664 gContextFactory.destroyContexts(); 712 gContextFactory.destroyContexts();
665 #endif 713 #endif
666 return 0; 714 return 0;
667 } 715 }
668 716
669 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 717 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
670 int main(int argc, char * const argv[]) { 718 int main(int argc, char * const argv[]) {
671 return tool_main(argc, (char**) argv); 719 return tool_main(argc, (char**) argv);
672 } 720 }
673 #endif 721 #endif
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