OLD | NEW |
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 | 9 |
10 #include "BenchTimer.h" | 10 #include "BenchTimer.h" |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 continue; | 775 continue; |
776 } | 776 } |
777 | 777 |
778 bool loggedBenchStart = false; | 778 bool loggedBenchStart = false; |
779 | 779 |
780 AutoPrePostDraw appd(bench); | 780 AutoPrePostDraw appd(bench); |
781 | 781 |
782 for (int x = 0; x < configs.count(); ++x) { | 782 for (int x = 0; x < configs.count(); ++x) { |
783 int configIndex = configs[x]; | 783 int configIndex = configs[x]; |
784 | 784 |
| 785 bool setupFailed = false; |
| 786 |
785 if (kNonRendering_Backend == gConfigs[configIndex].fBackend) { | 787 if (kNonRendering_Backend == gConfigs[configIndex].fBackend) { |
786 if (bench->isRendering()) { | 788 if (bench->isRendering()) { |
787 continue; | 789 continue; |
788 } | 790 } |
789 } else { | 791 } else { |
790 if (!bench->isRendering()) { | 792 if (!bench->isRendering()) { |
791 continue; | 793 continue; |
792 } | 794 } |
793 } | 795 } |
794 | 796 |
(...skipping 14 matching lines...) Expand all Loading... |
809 glContext = gContextFactory.getGLContext(gConfigs[configIndex].f
ContextType); | 811 glContext = gContextFactory.getGLContext(gConfigs[configIndex].f
ContextType); |
810 } | 812 } |
811 #endif | 813 #endif |
812 SkDevice* device = NULL; | 814 SkDevice* device = NULL; |
813 SkCanvas* canvas = NULL; | 815 SkCanvas* canvas = NULL; |
814 SkPicture pictureRecordFrom; | 816 SkPicture pictureRecordFrom; |
815 SkPicture pictureRecordTo; | 817 SkPicture pictureRecordTo; |
816 | 818 |
817 if (kNonRendering_Backend != backend) { | 819 if (kNonRendering_Backend != backend) { |
818 device = make_device(outConfig, dim, backend, sampleCount, conte
xt); | 820 device = make_device(outConfig, dim, backend, sampleCount, conte
xt); |
| 821 if (NULL == device) { |
| 822 SkString error; |
| 823 error.printf("Device creation failure for config %s. Will sk
ip.\n", configName); |
| 824 logger.logError(error.c_str()); |
| 825 setupFailed = true; |
| 826 } else { |
| 827 switch(benchMode) { |
| 828 case kDeferredSilent_benchModes: |
| 829 case kDeferred_benchModes: |
| 830 canvas = |
| 831 #if SK_DEFERRED_CANVAS_USES_FACTORIES |
| 832 SkDeferredCanvas::Create(device); |
| 833 #else |
| 834 SkNEW_ARGS(SkDeferredCanvas, (device)); |
| 835 #endif |
| 836 break; |
| 837 case kRecord_benchModes: |
| 838 canvas = pictureRecordTo.beginRecording(dim.fX, dim.
fY, |
| 839 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 840 canvas->ref(); |
| 841 break; |
| 842 case kPictureRecord_benchModes: { |
| 843 // This sets up picture-to-picture recording. |
| 844 // The C++ drawing calls for the benchmark are recor
ded into |
| 845 // pictureRecordFrom. As the benchmark, we will time
how |
| 846 // long it takes to playback pictureRecordFrom into |
| 847 // pictureRecordTo. |
| 848 SkCanvas* tempCanvas = pictureRecordFrom.beginRecord
ing(dim.fX, dim.fY, |
| 849 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 850 bench->draw(tempCanvas); |
| 851 pictureRecordFrom.endRecording(); |
| 852 canvas = pictureRecordTo.beginRecording(dim.fX, dim.
fY, |
| 853 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 854 canvas->ref(); |
| 855 break; |
| 856 } |
| 857 case kNormal_benchModes: |
| 858 canvas = new SkCanvas(device); |
| 859 break; |
| 860 default: |
| 861 SkASSERT(0); |
| 862 } |
| 863 device->unref(); |
| 864 canvas->clear(SK_ColorWHITE); |
| 865 } |
| 866 } |
| 867 SkAutoUnref canvasUnref(canvas); |
| 868 if (!setupFailed) { |
| 869 if (NULL != canvas) { |
| 870 if (doClip) { |
| 871 performClip(canvas, dim.fX, dim.fY); |
| 872 } |
| 873 if (doScale) { |
| 874 performScale(canvas, dim.fX, dim.fY); |
| 875 } |
| 876 if (doRotate) { |
| 877 performRotate(canvas, dim.fX, dim.fY); |
| 878 } |
| 879 } |
819 | 880 |
820 switch(benchMode) { | 881 if (!loggedBenchStart) { |
821 case kDeferredSilent_benchModes: | 882 loggedBenchStart = true; |
822 case kDeferred_benchModes: | 883 SkString str; |
823 canvas = | 884 str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, ben
ch->getName()); |
824 #if SK_DEFERRED_CANVAS_USES_FACTORIES | 885 logger.logProgress(str); |
825 SkDeferredCanvas::Create(device); | 886 } |
826 #else | 887 |
827 SkNEW_ARGS(SkDeferredCanvas, (device)); | 888 // warm up caches if needed |
| 889 if (repeatDraw > 1 && NULL != canvas) { |
| 890 #if SK_SUPPORT_GPU |
| 891 // purge the GPU resources to reduce variance |
| 892 if (NULL != context) { |
| 893 context->freeGpuResources(); |
| 894 } |
828 #endif | 895 #endif |
829 break; | 896 SkAutoCanvasRestore acr(canvas, true); |
830 case kRecord_benchModes: | 897 if (benchMode == kPictureRecord_benchModes) { |
| 898 pictureRecordFrom.draw(canvas); |
| 899 } else { |
| 900 bench->draw(canvas); |
| 901 } |
| 902 |
| 903 if (kDeferredSilent_benchModes == benchMode) { |
| 904 static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); |
| 905 } else { |
| 906 canvas->flush(); |
| 907 } |
| 908 #if SK_SUPPORT_GPU |
| 909 if (NULL != context) { |
| 910 context->flush(); |
| 911 SK_GL(*glContext, Finish()); |
| 912 } |
| 913 #endif |
| 914 } |
| 915 |
| 916 // record timer values for each repeat, and their sum |
| 917 TimerData timerData(perIterTimeformat, normalTimeFormat); |
| 918 for (int i = 0; i < repeatDraw; i++) { |
| 919 if ((benchMode == kRecord_benchModes || benchMode == kPictur
eRecord_benchModes)) { |
| 920 // This will clear the recorded commands so that they do
not |
| 921 // accumulate. |
831 canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 922 canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, |
832 SkPicture::kUsePathBoundsForClip_RecordingFlag); | 923 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
833 canvas->ref(); | |
834 break; | |
835 case kPictureRecord_benchModes: { | |
836 // This sets up picture-to-picture recording. | |
837 // The C++ drawing calls for the benchmark are recorded
into | |
838 // pictureRecordFrom. As the benchmark, we will time how | |
839 // long it takes to playback pictureRecordFrom into | |
840 // pictureRecordTo. | |
841 SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(
dim.fX, dim.fY, | |
842 SkPicture::kUsePathBoundsForClip_RecordingFlag); | |
843 bench->draw(tempCanvas); | |
844 pictureRecordFrom.endRecording(); | |
845 canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | |
846 SkPicture::kUsePathBoundsForClip_RecordingFlag); | |
847 canvas->ref(); | |
848 break; | |
849 } | 924 } |
850 case kNormal_benchModes: | 925 |
851 canvas = new SkCanvas(device); | 926 timer->start(bench->getDurationScale()); |
852 break; | 927 if (NULL != canvas) { |
853 default: | 928 canvas->save(); |
854 SkASSERT(0); | 929 } |
| 930 if (benchMode == kPictureRecord_benchModes) { |
| 931 pictureRecordFrom.draw(canvas); |
| 932 } else { |
| 933 bench->draw(canvas); |
| 934 } |
| 935 |
| 936 if (kDeferredSilent_benchModes == benchMode) { |
| 937 static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); |
| 938 } else if (NULL != canvas) { |
| 939 canvas->flush(); |
| 940 } |
| 941 |
| 942 if (NULL != canvas) { |
| 943 canvas->restore(); |
| 944 } |
| 945 |
| 946 // stop the truncated timer after the last canvas call but |
| 947 // don't wait for all the GL calls to complete |
| 948 timer->truncatedEnd(); |
| 949 #if SK_SUPPORT_GPU |
| 950 if (NULL != glContext) { |
| 951 context->flush(); |
| 952 SK_GL(*glContext, Finish()); |
| 953 } |
| 954 #endif |
| 955 // stop the inclusive and gpu timers once all the GL calls |
| 956 // have completed |
| 957 timer->end(); |
| 958 |
| 959 timerData.appendTimes(timer, repeatDraw - 1 == i); |
| 960 |
855 } | 961 } |
856 device->unref(); | 962 if (repeatDraw > 1) { |
857 canvas->clear(SK_ColorWHITE); | 963 SkString result = timerData.getResult( |
858 } | 964 logPerIter, printMin, repeatDraw, config
Name, |
859 SkAutoUnref canvasUnref(canvas); | 965 timerWall, truncatedTimerWall, timerCpu, |
860 | 966 truncatedTimerCpu, |
861 if (NULL != canvas) { | 967 timerGpu && NULL != context); |
862 if (doClip) { | 968 logger.logProgress(result); |
863 performClip(canvas, dim.fX, dim.fY); | |
864 } | 969 } |
865 if (doScale) { | 970 if (outDir.size() > 0 && kNonRendering_Backend != backend) { |
866 performScale(canvas, dim.fX, dim.fY); | 971 saveFile(bench->getName(), configName, outDir.c_str(), |
867 } | 972 device->accessBitmap(false)); |
868 if (doRotate) { | |
869 performRotate(canvas, dim.fX, dim.fY); | |
870 } | 973 } |
871 } | 974 } |
872 | 975 if (loggedBenchStart) { |
873 if (!loggedBenchStart) { | 976 logger.logProgress(SkString("\n")); |
874 loggedBenchStart = true; | |
875 SkString str; | |
876 str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, bench->
getName()); | |
877 logger.logProgress(str); | |
878 } | 977 } |
879 | |
880 // warm up caches if needed | |
881 if (repeatDraw > 1 && NULL != canvas) { | |
882 #if SK_SUPPORT_GPU | |
883 // purge the GPU resources to reduce variance | |
884 if (NULL != context) { | |
885 context->freeGpuResources(); | |
886 } | |
887 #endif | |
888 SkAutoCanvasRestore acr(canvas, true); | |
889 if (benchMode == kPictureRecord_benchModes) { | |
890 pictureRecordFrom.draw(canvas); | |
891 } else { | |
892 bench->draw(canvas); | |
893 } | |
894 | |
895 if (kDeferredSilent_benchModes == benchMode) { | |
896 static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | |
897 } else { | |
898 canvas->flush(); | |
899 } | |
900 #if SK_SUPPORT_GPU | |
901 if (NULL != context) { | |
902 context->flush(); | |
903 SK_GL(*glContext, Finish()); | |
904 } | |
905 #endif | |
906 } | |
907 | |
908 // record timer values for each repeat, and their sum | |
909 TimerData timerData(perIterTimeformat, normalTimeFormat); | |
910 for (int i = 0; i < repeatDraw; i++) { | |
911 if ((benchMode == kRecord_benchModes || benchMode == kPictureRec
ord_benchModes)) { | |
912 // This will clear the recorded commands so that they do not | |
913 // accumulate. | |
914 canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | |
915 SkPicture::kUsePathBoundsForClip_RecordingFlag); | |
916 } | |
917 | |
918 timer->start(bench->getDurationScale()); | |
919 if (NULL != canvas) { | |
920 canvas->save(); | |
921 } | |
922 if (benchMode == kPictureRecord_benchModes) { | |
923 pictureRecordFrom.draw(canvas); | |
924 } else { | |
925 bench->draw(canvas); | |
926 } | |
927 | |
928 if (kDeferredSilent_benchModes == benchMode) { | |
929 static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | |
930 } else if (NULL != canvas) { | |
931 canvas->flush(); | |
932 } | |
933 | |
934 if (NULL != canvas) { | |
935 canvas->restore(); | |
936 } | |
937 | |
938 // stop the truncated timer after the last canvas call but | |
939 // don't wait for all the GL calls to complete | |
940 timer->truncatedEnd(); | |
941 #if SK_SUPPORT_GPU | |
942 if (NULL != glContext) { | |
943 context->flush(); | |
944 SK_GL(*glContext, Finish()); | |
945 } | |
946 #endif | |
947 // stop the inclusive and gpu timers once all the GL calls | |
948 // have completed | |
949 timer->end(); | |
950 | |
951 timerData.appendTimes(timer, repeatDraw - 1 == i); | |
952 | |
953 } | |
954 if (repeatDraw > 1) { | |
955 SkString result = timerData.getResult(logPerIter, printMin, repe
atDraw, configName, | |
956 timerWall, truncatedTimerW
all, timerCpu, | |
957 truncatedTimerCpu, | |
958 timerGpu && NULL != contex
t); | |
959 logger.logProgress(result); | |
960 } | |
961 if (outDir.size() > 0 && kNonRendering_Backend != backend) { | |
962 saveFile(bench->getName(), configName, outDir.c_str(), | |
963 device->accessBitmap(false)); | |
964 } | |
965 } | |
966 if (loggedBenchStart) { | |
967 logger.logProgress(SkString("\n")); | |
968 } | 978 } |
969 } | 979 } |
970 #if SK_SUPPORT_GPU | 980 #if SK_SUPPORT_GPU |
971 #if GR_CACHE_STATS | 981 #if GR_CACHE_STATS |
972 for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) { | 982 for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) { |
973 GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextTy
pe)i; | 983 GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextTy
pe)i; |
974 GrContext* context = gContextFactory.get(ctxType); | 984 GrContext* context = gContextFactory.get(ctxType); |
975 if (NULL != context) { | 985 if (NULL != context) { |
976 SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContex
tTypeName(ctxType)); | 986 SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContex
tTypeName(ctxType)); |
977 context->printCacheStats(); | 987 context->printCacheStats(); |
978 SkDebugf("\n"); | 988 SkDebugf("\n"); |
979 } | 989 } |
980 } | 990 } |
981 #endif | 991 #endif |
982 // Destroy the GrContext before the inst tracking printing at main() exit oc
curs. | 992 // Destroy the GrContext before the inst tracking printing at main() exit oc
curs. |
983 gContextFactory.destroyContexts(); | 993 gContextFactory.destroyContexts(); |
984 #endif | 994 #endif |
985 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { | 995 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { |
986 SkDELETE(timers[i]); | 996 SkDELETE(timers[i]); |
987 } | 997 } |
988 | 998 |
989 return 0; | 999 return 0; |
990 } | 1000 } |
991 | 1001 |
992 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1002 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
993 int main(int argc, char * const argv[]) { | 1003 int main(int argc, char * const argv[]) { |
994 return tool_main(argc, (char**) argv); | 1004 return tool_main(argc, (char**) argv); |
995 } | 1005 } |
996 #endif | 1006 #endif |
OLD | NEW |