| Index: tests/PathOpsSkpClipTest.cpp
 | 
| diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp
 | 
| index c0f028c55f0b563b8c1723fea11a8b23192b5b91..da505451da2dd61166ed13372872e03c8d220779 100755
 | 
| --- a/tests/PathOpsSkpClipTest.cpp
 | 
| +++ b/tests/PathOpsSkpClipTest.cpp
 | 
| @@ -27,87 +27,197 @@
 | 
|  #else
 | 
|      #define PATH_SLASH "/"
 | 
|      #define IN_DIR "/skp/2311328-7fc2228/slave"
 | 
| -    #define OUT_DIR "/skpOut/2/"
 | 
| +    #define OUT_DIR "/skpOut/4/"
 | 
|  #endif
 | 
|  
 | 
|  const struct {
 | 
|      int directory;
 | 
|      const char* filename;
 | 
|  } skipOverSept[] = {
 | 
| -    { 9, "http___www_catingueiraonline_com_.skp"},  // infinite loop
 | 
| -    {13, "http___www_galaxystwo_com_.skp"},  // infinite loop
 | 
| -    {15, "http___www_giffingtool_com_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {15, "http___www_thaienews_blogspot_com_.skp"},  // infinite loop
 | 
| -    {17, "http___www_gruposejaumdivulgador_com_br_.skp"}, // calcCoincidentWinding asserts zeroSpan
 | 
| +    { 3, "http___www_americascup_com_.skp"},  // !simple->closed()
 | 
|      {18, "http___www_argus_presse_fr_.skp"},  // can't find winding of remaining vertical edge
 | 
| -    {21, "http___www_fashionscandal_com_.skp"},  // infinite loop
 | 
| -    {21, "http___www_kenlevine_blogspot_com_.skp"},  // infinite loop
 | 
| -    {25, "http___www_defense_studies_blogspot_com_.skp"},  // infinite loop
 | 
| -    {27, "http___www_brokeroutpost_com_.skp"},  // suspect infinite loop
 | 
| -    {28, "http___www_jaimebatistadasilva_blogspot_com_br_.skp"},  // suspect infinite loop
 | 
| -    {28, "http___www_odia_com_br_.skp"},  // !simple->isClosed()
 | 
| -    {29, "http___www_hubbyscook_com_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {30, "http___www_spankystokes_com_.skp"},  // suspect infinite loop
 | 
| -    {32, "http___www_adalbertoday_blogspot_com_br_.skp"},  // suspect infinite loop
 | 
| -    {32, "http___www_galery_annisa_com_.skp"},  // suspect infinite loop
 | 
| -    {33, "http___www_pindosiya_com_.skp"},  // line quad intersection SkIntersections::assert
 | 
| -    {36, "http___www_educationalcraft_com_.skp"},  // cubic / cubic near end / assert in SkIntersections::insert (missing skp test)
 | 
| -    {36, "http___www_shaam_org_.skp"},  // suspect infinite loop
 | 
| -    {36, "http___www_my_pillow_book_blogspot_gr_.skp"},  // suspect infinite loop
 | 
| -    {39, "http___www_opbeat_com_.skp"},  // suspect infinite loop
 | 
| -    {40, "http___www_phototransferapp_com_.skp"},  // !simple->isClosed()
 | 
| -    {41, "http___www_freeismylife_com_.skp"},  // suspect infinite loop
 | 
| -    {41, "http___www_accordidelmomento_com_.skp"},  // suspect infinite loop
 | 
| -    {41, "http___www_evolvehq_com_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {44, "http___www_contextualnewsfeeds_com_.skp"},  // !simple->isClosed()
 | 
| +    {31, "http___www_narayana_verlag_de_.skp"},  // !simple->closed()
 | 
| +    {36, "http___www_educationalcraft_com_.skp"},  // cubic / cubic near end / assert in SkIntersections::insert
 | 
|      {44, "http___www_cooksnaps_com_.skp"},  // !simple->isClosed()
 | 
| -    {44, "http___www_helha_be_.skp"},  // !simple->isClosed()
 | 
| -    {45, "http___www_blondesmakemoney_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {46, "http___www_cheaphealthygood_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {47, "http___www_ajitvadakayil_blogspot_in_.skp"},  // suspect infinite loop
 | 
| -    {49, "http___www_karnivool_com_au_.skp"},  // SkOpAngle::setSector SkASSERT(fSectorStart >= 0);
 | 
| -    {49, "http___www_tunero_de_.skp"},  // computeonesumreverse calls markwinding with 0 winding
 | 
| -    {49, "http___www_thaienews_blogspot_sg_.skp"},  // suspect infinite loop
 | 
| -    {50, "http___www_docgelo_com_.skp"},  // rightAngleWinding (probably same as argus_presse)
 | 
| +    {48, "http___www_narayana_publishers_com_.skp"},  // !simple->isClosed()
 | 
| +    {51, "http___www_freedominthe50states_org_.skp"},  // corrupt dash data
 | 
| +    {52, "http___www_aceinfographics_com_.skp"},  // right angle winding assert
 | 
|      {53, "http___www_lojaanabotafogo_com_br_.skp"},  // rrect validate assert
 | 
| -    {54, "http___www_odecktestanswer2013_blogspot_in_.skp"},  // suspect infinite loop
 | 
| -    {54, "http___www_cleristonsilva_com_br_.skp"},  // suspect infinite loop
 | 
| -    {56, "http___www_simplysaru_com_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {57, "http___www_koukfamily_blogspot_gr_.skp"},  // suspect infinite loop
 | 
| -    {57, "http___www_dinar2010_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {58, "http___www_artblart_com_.skp"},  // rightAngleWinding
 | 
| -    {59, "http___www_accrispin_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {59, "http___www_vicisitudysordidez_blogspot_com_es_.skp"},  // suspect infinite loop
 | 
| -    {60, "http___www_thehousingbubbleblog_com_.skp"},  // suspect infinite loop
 | 
| -    {61, "http___www_jessicaslens_wordpress_com_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {61, "http___www_partsdata_de_.skp"},  // cubic-cubic intersection reduce checkLinear assert
 | 
| -    {62, "http___www_blondesmakemoney_blogspot_com_au_.skp"},  // suspect infinite loop
 | 
| -    {62, "http___www_intellibriefs_blogspot_in_.skp"},  // suspect infinite loop
 | 
| -    {63, "http___www_tankerenemy_com_.skp"},  // suspect infinite loop
 | 
| -    {65, "http___www_kpopexplorer_net_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {65, "http___www_bestthingsinbeauty_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {65, "http___www_wartepop_blogspot_com_br_.skp"},  // !simple->isClosed()
 | 
| -    {65, "http___www_eolake_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {67, "http___www_cacadordemisterio_blogspot_com_br_.skp"},  // suspect infinite loop
 | 
| -    {69, "http___www_misnotasyapuntes_blogspot_mx_.skp"},  // suspect infinite loop
 | 
| -    {69, "http___www_awalkintheparknyc_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {71, "http___www_lokado_de_.skp"},  // joinCoincidence / findT / assert
 | 
| -    {72, "http___www_karlosdesanjuan_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {73, "http___www_cyberlawsinindia_blogspot_in_.skp"},  // suspect infinite loop
 | 
| -    {73, "http___www_taxiemmovimento_blogspot_com_br_.skp"},  // suspect infinite loop
 | 
| -    {74, "http___www_giveusliberty1776_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {75, "http___www_e_cynical_blogspot_gr_.skp"},  // suspect infinite loop
 | 
| -    {76, "http___www_seopack_blogspot_com_.skp"},  // SkOpAngle::setSector SkASSERT(fSectorStart >= 0);
 | 
| -    {77, "http___www_sunsky_russia_com_.skp"},  // joinCoincidence / findT / assert (no op test, already fixed hopefully)
 | 
| -    {78, "http___www_bisnisonlineinfo_com_.skp"},  // suspect infinite loop
 | 
| -    {79, "http___www_danielsgroupcpa_com_.skp"},  // joinCoincidence / findT / assert (no op test, already fixed hopefully)
 | 
| -    {80, "http___www_clinique_portugal_com_.skp"},  // suspect infinite loop
 | 
| -    {81, "http___www_europebusines_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {82, "http___www_apopsignomi_blogspot_gr_.skp"},  // suspect infinite loop
 | 
| -    {85, "http___www_ajitvadakayil_blogspot_com_.skp"},  // suspect infinite loop
 | 
| -    {86, "http___www_madhousefamilyreviews_blogspot_co_uk_.skp"},  // suspect infinite loop
 | 
| +    {57, "http___www_vantageproduction_com_.skp"},  // !isClosed()
 | 
| +    {64, "http___www_etiqadd_com_.skp"},  // !simple->closed()
 | 
| +    {84, "http___www_swapspacesystems_com_.skp"},  // !simple->closed()
 | 
| +    {90, "http___www_tcmevents_org_.skp"},  // !simple->closed()
 | 
| +    {96, "http___www_paseoitaigara_com_br_.skp"},  // !simple->closed()
 | 
| +    {98, "http___www_mortgagemarketguide_com_.skp"},  // !simple->closed()
 | 
| +    {99, "http___www_kitcheninspirations_wordpress_com_.skp"},  // checkSmall / bumpSpan
 | 
|  };
 | 
|  
 | 
| +/* stats
 | 
| +97 http___www_brandyandvinca_com_.skp pixelError=3
 | 
| +95 http___www_into_asia_com_.skp pixelError=12
 | 
| +93 http___www_lunarplanner_com_.skp pixelError=14
 | 
| +98 http___www_lovelyitalia_com_.skp pixelError=17
 | 
| +90 http___www_inter_partner_blogspot_com_.skp pixelError=18
 | 
| +99 http___www_maxarea_com_.skp pixelError=26
 | 
| +98 http___www_maroonsnet_org_.skp pixelError=33
 | 
| +92 http___www_belinaart_ru_.skp pixelError=50
 | 
| +100 http___www_chroot_ro_.skp pixelError=62
 | 
| +99 http___www_hsbrands_com_.skp pixelError=98
 | 
| +95 http___www_tournamentindicator_com_.skp pixelError=122
 | 
| +93 http___www_businesses_com_au_.skp pixelError=162
 | 
| +90 http___www_regenesys_net_.skp pixelError=182
 | 
| +88 http___www_1863544208148625103_c18eac63985503fa85b06358959c1ba27fc36f82_blogspot_com_.skp pixelError=186
 | 
| +97 http___www_pregacoesevangelica_com_br_.skp pixelError=240
 | 
| +77 http___www_zhenggang_org_.skp pixelError=284
 | 
| +96 http___slidesharemailer_com_.skp pixelError=522
 | 
| +94 http___www_gensteel_com_.skp pixelError=555
 | 
| +68 http___www_jf_eti_br_.skp pixelError=610
 | 
| +83 http___www_swishiat_com_.skp pixelError=706
 | 
| +96 http___www_matusikmissive_com_au_.skp pixelError=2580
 | 
| +95 http___www_momentumnation_com_.skp pixelError=3938
 | 
| +92 http___www_rssowl_com_.skp pixelError=5113
 | 
| +96 http___www_sexxygirl_tv_.skp pixelError=7605
 | 
| +99 http___www_georgevalah_wordpress_com_.skp pixelError=8386
 | 
| +78 http___www_furbo_org_.skp pixelError=8656
 | 
| +78 http___www_djxhemary_wordpress_com_.skp pixelError=8976
 | 
| +100 http___www_mindcontrolblackassassins_com_.skp pixelError=31950
 | 
| +98 http___bababillgates_free_fr_.skp pixelError=40237
 | 
| +98 http___hepatite_ro_.skp pixelError=44370
 | 
| +86 http___www_somethingwagging_com_.skp pixelError=47794
 | 
| +84 http___www_beverageuniverse_com_.skp pixelError=65450
 | 
| +50 http___www_aveksa_com_.skp pixelError=68194
 | 
| +10 http___www_publiker_pl_.skp pixelError=89997
 | 
| +61 http___www_dominos_co_id_.skp pixelError=476868
 | 
| +87 http___www_du_edu_om_.skp time=46
 | 
| +87 http___www_bigload_de_.skp time=46
 | 
| +100 http___www_home_forum_com_.skp time=48
 | 
| +97 http___www_hotamateurchat_com_.skp time=48
 | 
| +97 http___www_myrsky_com_cn_.skp time=48
 | 
| +98 http___www_techiegeex_com_.skp time=49
 | 
| +82 http___www_fashionoutletsofchicago_com_.skp time=50
 | 
| +77 http___www_dynamischbureau_nl_.skp time=50
 | 
| +82 http___www_mayihelpu_co_in_.skp time=50
 | 
| +84 http___www_vbox7_com_user_history_viewers_.skp time=50
 | 
| +85 http___www_ktokogda_com_.skp time=50
 | 
| +85 http___www_propertyturkeysale_com_.skp time=50
 | 
| +85 http___www_51play_com_.skp time=50
 | 
| +86 http___www_bayalarm_com_.skp time=50
 | 
| +87 http___www_eaglepictures_com_.skp time=50
 | 
| +88 http___www_atlasakvaryum_com_.skp time=50
 | 
| +91 http___www_pioneerchryslerjeep_com_.skp time=50
 | 
| +94 http___www_thepulsemag_com_.skp time=50
 | 
| +95 http___www_dcshoes_com_ph_.skp time=50
 | 
| +96 http___www_montrealmassage_ca_.skp time=50
 | 
| +96 http___www_jkshahclasses_com_.skp time=50
 | 
| +96 http___www_webcamconsult_com_.skp time=51
 | 
| +100 http___www_bsoscblog_com_.skp time=52
 | 
| +95 http___www_flaktwoods_com_.skp time=53
 | 
| +91 http___www_qivivo_com_.skp time=54
 | 
| +90 http___www_unitender_com_.skp time=56
 | 
| +97 http___www_casinogaming_com_.skp time=56
 | 
| +97 http___www_rootdownload_com_.skp time=56
 | 
| +94 http___www_aspa_ev_de_.skp time=57
 | 
| +98 http___www_tenpieknyswiat_pl_.skp time=57
 | 
| +93 http___www_transocean_de_.skp time=58
 | 
| +94 http___www_vdo2_blogspot_com_.skp time=58
 | 
| +94 http___www_asmaissexy_com_br_.skp time=58
 | 
| +100 http___www_prefeiturasjm_com_br_.skp time=60
 | 
| +100 http___www_eduinsuranceclick_blogspot_com_.skp time=60
 | 
| +96 http___www_bobdunsire_com_.skp time=61
 | 
| +96 http___www_omgkettlecorn_com_.skp time=61
 | 
| +85 http___www_fbbsessions_com_.skp time=62
 | 
| +86 http___www_hector_ru_.skp time=62
 | 
| +87 http___www_wereldsupporter_nl_.skp time=62
 | 
| +90 http___www_arello_com_.skp time=62
 | 
| +93 http___www_bayerplastics_com_.skp time=62
 | 
| +93 http___www_superandolamovida_com_ar_.skp time=62
 | 
| +96 http___www_med_rbf_ru_.skp time=62
 | 
| +81 http___www_carnegiescience_edu_.skp time=65
 | 
| +87 http___www_asanewengland_com_.skp time=65
 | 
| +92 http___www_turkce_karakter_appspot_com_.skp time=65
 | 
| +94 http___www_k3a_org_.skp time=65
 | 
| +96 http___www_powermaccenter_com_.skp time=65
 | 
| +98 http___www_avto49_ru_.skp time=67
 | 
| +100 http___www_hetoldeambaecht_nl_.skp time=68
 | 
| +95 http___www_marine_ie_.skp time=69
 | 
| +96 http___www_quebecvapeboutique_com_.skp time=69
 | 
| +95 http___www_brays_ingles_com_.skp time=70
 | 
| +100 http___www_lacondesa_com_.skp time=72
 | 
| +95 http___www_timbarrathai_com_au_.skp time=76
 | 
| +95 http___www_cuissedegrenouille_com_.skp time=76
 | 
| +95 http___www_iwama51_ru_.skp time=76
 | 
| +99 http___www_fotoantologia_it_.skp time=76
 | 
| +92 http___www_indian_architects_com_.skp time=78
 | 
| +92 http___www_totalwomanspa_com_.skp time=78
 | 
| +100 http___www_fachverband_spielhallen_de_.skp time=83
 | 
| +93 http___www_golshanemehr_ir_.skp time=84
 | 
| +95 http___www_maryesses_com_.skp time=84
 | 
| +99 http___www_ddcorp_ca_.skp time=89
 | 
| +90 http___www_brontops_com_.skp time=89
 | 
| +94 http___www_robgolding_com_.skp time=89
 | 
| +91 http___www_tecban_com_br_.skp time=91
 | 
| +98 http___www_costamesakarate_com_.skp time=100
 | 
| +95 http___www_monsexyblog_com_.skp time=103
 | 
| +97 http___www_stornowaygazette_co_uk_.skp time=103
 | 
| +93 http___www_fitforaframe_com_.skp time=104
 | 
| +98 http___www_intentionoftheday_com_.skp time=113
 | 
| +100 http___www_tailgateclothing_com_.skp time=117
 | 
| +95 http___www_senbros_com_.skp time=118
 | 
| +93 http___www_lettoblog_com_.skp time=121
 | 
| +94 http___www_maxineschallenge_com_au_.skp time=125
 | 
| +95 http___www_savvycard_net_.skp time=127
 | 
| +95 http___www_open_ac_mu_.skp time=129
 | 
| +96 http___www_avgindia_in_.skp time=135
 | 
| +97 http___www_stocktonseaview_com_.skp time=135
 | 
| +96 http___www_distroller_com_.skp time=142
 | 
| +94 http___www_travoggalop_dk_.skp time=144
 | 
| +100 http___www_history_im_.skp time=144
 | 
| +94 http___www_playradio_sk_.skp time=145
 | 
| +92 http___www_linglongglass_com_.skp time=151
 | 
| +97 http___www_bizzna_com_.skp time=151
 | 
| +96 http___www_spiros_ws_.skp time=154
 | 
| +91 http___www_rosen_meents_co_il_.skp time=156
 | 
| +81 http___www_hoteldeluxeportland_com_.skp time=158
 | 
| +92 http___www_freetennis_org_.skp time=161
 | 
| +93 http___www_aircharternetwork_com_au_.skp time=161
 | 
| +94 http___www_austinparks_org_.skp time=165
 | 
| +89 http___www_bevvy_co_.skp time=168
 | 
| +91 http___www_sosyalhile_net_.skp time=168
 | 
| +98 http___www_minvih_gob_ve_.skp time=171
 | 
| +89 http___www_streetfoodmtl_com_.skp time=172
 | 
| +92 http___www_loveslatinas_tumblr_com_.skp time=178
 | 
| +93 http___www_madbites_co_in_.skp time=180
 | 
| +94 http___www_rocktarah_ir_.skp time=185
 | 
| +97 http___www_penthouselife_com_.skp time=185
 | 
| +96 http___www_appymonkey_com_.skp time=196
 | 
| +92 http___www_pasargadhotels_com_.skp time=203
 | 
| +99 http___www_marina_mil_pe_.skp time=203
 | 
| +89 http___www_kays_co_uk_.skp time=205
 | 
| +77 http___www_334588_com_.skp time=211
 | 
| +83 http___www_trendbad24_de_.skp time=211
 | 
| +81 http___www_cdnetworks_co_kr_.skp time=216
 | 
| +94 http___www_schellgames_com_.skp time=223
 | 
| +95 http___www_juliaweddingnews_cn_.skp time=230
 | 
| +92 http___www_xcrafters_pl_.skp time=253
 | 
| +93 http___www_pondoo_com_.skp time=253
 | 
| +96 http___www_helsinkicapitalpartners_fi_.skp time=255
 | 
| +88 http___www_nadtexican_com_.skp time=259
 | 
| +85 http___www_canstockphoto_hu_.skp time=266
 | 
| +78 http___www_ecovacs_com_cn_.skp time=271
 | 
| +93 http___www_brookfieldplaceny_com_.skp time=334
 | 
| +93 http___www_fmastrengthtraining_com_.skp time=337
 | 
| +94 http___www_turtleonthebeach_com_.skp time=394
 | 
| +90 http___www_temptationthemovie_com_.skp time=413
 | 
| +95 http___www_patongsawaddi_com_.skp time=491
 | 
| +91 http___www_online_radio_appspot_com_.skp time=511
 | 
| +68 http___www_richardmiller_co_uk_.skp time=528
 | 
| +63 http___www_eschrade_com_.skp time=543
 | 
| +55 http___www_interaction_inf_br_.skp time=625
 | 
| +38 http___www_huskyliners_com_.skp time=632
 | 
| +86 http___granda_net_.skp time=1067
 | 
| +24 http___www_cocacolafm_com_br_.skp time=1081
 | 
| +*/
 | 
| +
 | 
|  size_t skipOverSeptCount = sizeof(skipOverSept) / sizeof(skipOverSept[0]);
 | 
|  
 | 
|  enum TestStep {
 | 
| @@ -116,7 +226,7 @@ enum TestStep {
 | 
|  };
 | 
|  
 | 
|  enum {
 | 
| -    kMaxLength = 128,
 | 
| +    kMaxLength = 256,
 | 
|      kMaxFiles = 128,
 | 
|      kSmallLimit = 1000,
 | 
|  };
 | 
| @@ -190,6 +300,13 @@ public:
 | 
|      }
 | 
|  };
 | 
|  
 | 
| +class SortByName : public TestResult {
 | 
| +public:
 | 
| +    bool operator<(const SortByName& rh) const {
 | 
| +        return strcmp(fFilename, rh.fFilename) < 0;
 | 
| +    }
 | 
| +};
 | 
| +
 | 
|  struct TestState {
 | 
|      void init(int dirNo, skiatest::Reporter* reporter) {
 | 
|          fReporter = reporter;
 | 
| @@ -217,11 +334,6 @@ struct TestRunner {
 | 
|  
 | 
|  class TestRunnable : public SkRunnable {
 | 
|  public:
 | 
| -    TestRunnable(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
 | 
| -        fState.init(dirNo, runner->fReporter);
 | 
| -        fTestFun = testFun;
 | 
| -    }
 | 
| -
 | 
|      virtual void run() SK_OVERRIDE {
 | 
|          SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
 | 
|          (*fTestFun)(&fState);
 | 
| @@ -231,6 +343,33 @@ public:
 | 
|      void (*fTestFun)(TestState*);
 | 
|  };
 | 
|  
 | 
| +
 | 
| +class TestRunnableDir : public TestRunnable {
 | 
| +public:
 | 
| +    TestRunnableDir(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
 | 
| +        fState.init(dirNo, runner->fReporter);
 | 
| +        fTestFun = testFun;
 | 
| +    }
 | 
| +
 | 
| +};
 | 
| +
 | 
| +class TestRunnableFile : public TestRunnable {
 | 
| +public:
 | 
| +    TestRunnableFile(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner) {
 | 
| +        fState.init(dirNo, runner->fReporter);
 | 
| +        strcpy(fState.fResult.fFilename, name);
 | 
| +        fTestFun = testFun;
 | 
| +    }
 | 
| +};
 | 
| +
 | 
| +class TestRunnableEncode : public TestRunnableFile {
 | 
| +public:
 | 
| +    TestRunnableEncode(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner)
 | 
| +        : TestRunnableFile(testFun, dirNo, name, runner) {
 | 
| +        fState.fResult.fTestStep = kEncodeFiles;
 | 
| +    }
 | 
| +};
 | 
| +
 | 
|  TestRunner::~TestRunner() {
 | 
|      for (int index = 0; index < fRunnables.count(); index++) {
 | 
|          SkDELETE(fRunnables[index]);
 | 
| @@ -272,6 +411,16 @@ static SkString make_in_dir_name(int dirNo) {
 | 
|      return dirName;
 | 
|  }
 | 
|  
 | 
| +static SkString make_stat_dir_name(int dirNo) {
 | 
| +    SkString dirName(outStatusDir);
 | 
| +    dirName.appendf("%d", dirNo);
 | 
| +    if (!sk_exists(dirName.c_str())) {
 | 
| +        SkDebugf("could not read dir %s\n", dirName.c_str());
 | 
| +        return SkString();
 | 
| +    }
 | 
| +    return dirName;
 | 
| +}
 | 
| +
 | 
|  static bool make_one_out_dir(const char* outDirStr) {
 | 
|      SkString outDir = make_filepath(0, outDirStr, "");
 | 
|      if (!sk_exists(outDir.c_str())) {
 | 
| @@ -675,32 +824,79 @@ static bool initTest() {
 | 
|      return make_out_dirs();
 | 
|  }
 | 
|  
 | 
| +static bool initUberTest(int firstDirNo, int lastDirNo) {
 | 
| +    if (!initTest()) {
 | 
| +        return false;
 | 
| +    }
 | 
| +    for (int index = firstDirNo; index <= lastDirNo; ++index) {
 | 
| +        SkString statusDir(outStatusDir);
 | 
| +        statusDir.appendf("%d", index);
 | 
| +        if (!make_one_out_dir(statusDir.c_str())) {
 | 
| +            return false;
 | 
| +        }
 | 
| +    }
 | 
| +    return true;
 | 
| +}
 | 
| +
 | 
| +
 | 
| +static void testSkpClipEncode(TestState* data) {
 | 
| +    data->fResult.testOne();
 | 
| +    if (data->fReporter->verbose()) {
 | 
| +       SkDebugf("+");
 | 
| +    }
 | 
| +}
 | 
| +
 | 
|  static void encodeFound(skiatest::Reporter* reporter, TestState& state) {
 | 
|      if (reporter->verbose()) {
 | 
| -        SkTDArray<SortByPixel*> worst;
 | 
| -        for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
| -            *worst.append() = &state.fPixelWorst[index];
 | 
| -        }
 | 
| -        SkTQSort<SortByPixel>(worst.begin(), worst.end() - 1);
 | 
| -        for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
| -            const TestResult& result = *worst[index];
 | 
| -            SkDebugf("%d %s pixelError=%d\n", result.fDirNo, result.fFilename, result.fPixelError);
 | 
| +        if (state.fPixelWorst.count()) {
 | 
| +            SkTDArray<SortByPixel*> worst;
 | 
| +            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
| +                *worst.append() = &state.fPixelWorst[index];
 | 
| +            }
 | 
| +            SkTQSort<SortByPixel>(worst.begin(), worst.end() - 1);
 | 
| +            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
| +                const TestResult& result = *worst[index];
 | 
| +                SkDebugf("%d %s pixelError=%d\n", result.fDirNo, result.fFilename, result.fPixelError);
 | 
| +            }
 | 
|          }
 | 
| -        SkTDArray<SortByTime*> slowest;
 | 
| -        for (int index = 0; index < state.fSlowest.count(); ++index) {
 | 
| -            *slowest.append() = &state.fSlowest[index];
 | 
| +        if (state.fSlowest.count()) {
 | 
| +            SkTDArray<SortByTime*> slowest;
 | 
| +            for (int index = 0; index < state.fSlowest.count(); ++index) {
 | 
| +                *slowest.append() = &state.fSlowest[index];
 | 
| +            }
 | 
| +            if (slowest.count() > 0) {
 | 
| +                SkTQSort<SortByTime>(slowest.begin(), slowest.end() - 1);
 | 
| +                for (int index = 0; index < slowest.count(); ++index) {
 | 
| +                    const TestResult& result = *slowest[index];
 | 
| +                    SkDebugf("%d %s time=%d\n", result.fDirNo, result.fFilename, result.fTime);
 | 
| +                }
 | 
| +            }
 | 
|          }
 | 
| -        SkTQSort<SortByTime>(slowest.begin(), slowest.end() - 1);
 | 
| -        for (int index = 0; index < slowest.count(); ++index) {
 | 
| -            const TestResult& result = *slowest[index];
 | 
| -            SkDebugf("%d %s time=%d\n", result.fDirNo, result.fFilename, result.fTime);
 | 
| +    }
 | 
| +
 | 
| +    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
 | 
| +    TestRunner testRunner(reporter, threadCount);
 | 
| +    for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
| +        const TestResult& result = state.fPixelWorst[index];
 | 
| +        SkString filename(result.fFilename);
 | 
| +        if (!filename.endsWith(".skp")) {
 | 
| +            filename.append(".skp");
 | 
|          }
 | 
| +        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableEncode,
 | 
| +                (&testSkpClipEncode, result.fDirNo, filename.c_str(), &testRunner));
 | 
|      }
 | 
| +    testRunner.render();
 | 
| +#if 0
 | 
|      for (int index = 0; index < state.fPixelWorst.count(); ++index) {
 | 
|          const TestResult& result = state.fPixelWorst[index];
 | 
| -        TestResult::Test(result.fDirNo, result.fFilename, kEncodeFiles);
 | 
| -        if (state.fReporter->verbose()) SkDebugf("+");
 | 
| +        SkString filename(result.fFilename);
 | 
| +        if (!filename.endsWith(".skp")) {
 | 
| +            filename.append(".skp");
 | 
| +        }
 | 
| +        TestResult::Test(result.fDirNo, filename.c_str(), kEncodeFiles);
 | 
| +        if (reporter->verbose()) SkDebugf("+");
 | 
|      }
 | 
| +#endif
 | 
|  }
 | 
|  
 | 
|  DEF_TEST(PathOpsSkpClip, reporter) {
 | 
| @@ -732,19 +928,177 @@ DEF_TEST(PathOpsSkpClipThreaded, reporter) {
 | 
|      }
 | 
|      int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
 | 
|      TestRunner testRunner(reporter, threadCount);
 | 
| -    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
 | 
| -        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnable,
 | 
| +    const int firstDirNo = 1;
 | 
| +    for (int dirNo = firstDirNo; dirNo <= 100; ++dirNo) {
 | 
| +        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableDir,
 | 
|                  (&testSkpClipMain, dirNo, &testRunner));
 | 
|      }
 | 
|      testRunner.render();
 | 
|      TestState state;
 | 
|      state.init(0, reporter);
 | 
| -    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
 | 
| +    for (int dirNo = firstDirNo; dirNo <= 100; ++dirNo) {
 | 
|          TestState& testState = testRunner.fRunnables[dirNo - 1]->fState;
 | 
| +        SkASSERT(testState.fResult.fDirNo == dirNo);
 | 
|          for (int inner = 0; inner < testState.fPixelWorst.count(); ++inner) {
 | 
| -            SkASSERT(testState.fResult.fDirNo == dirNo);
 | 
|              addError(&state, testState.fPixelWorst[inner]);
 | 
|          }
 | 
| +        for (int inner = 0; inner < testState.fSlowest.count(); ++inner) {
 | 
| +            addError(&state, testState.fSlowest[inner]);
 | 
| +        }
 | 
| +    }
 | 
| +    encodeFound(reporter, state);
 | 
| +}
 | 
| +
 | 
| +static void testSkpClipUber(TestState* data) {
 | 
| +    data->fResult.testOne();
 | 
| +    SkString dirName = make_stat_dir_name(data->fResult.fDirNo);
 | 
| +    if (!dirName.size()) {
 | 
| +        return;
 | 
| +    }
 | 
| +    SkString statName(data->fResult.fFilename);
 | 
| +    SkASSERT(statName.endsWith(".skp"));
 | 
| +    statName.remove(statName.size() - 4, 4);
 | 
| +    statName.appendf(".%d.%d.skp", data->fResult.fPixelError, data->fResult.fTime);
 | 
| +    SkString statusFile = make_filepath(data->fResult.fDirNo, outStatusDir, statName.c_str());
 | 
| +    SkFILE* file = sk_fopen(statusFile.c_str(), kWrite_SkFILE_Flag);
 | 
| +    if (!file) {
 | 
| +            SkDebugf("failed to create %s", statusFile.c_str());
 | 
| +            return;
 | 
| +    }
 | 
| +    sk_fclose(file);
 | 
| +    if (data->fReporter->verbose()) {
 | 
| +        if (data->fResult.fPixelError || data->fResult.fTime) {
 | 
| +            SkDebugf("%s", data->fResult.progress().c_str());
 | 
| +        } else {
 | 
| +            SkDebugf(".");
 | 
| +        }
 | 
| +    }
 | 
| +}
 | 
| +
 | 
| +static bool buildTests(skiatest::Reporter* reporter, int firstDirNo, int lastDirNo, SkTDArray<TestResult>* tests,
 | 
| +        SkTDArray<SortByName*>* sorted) {
 | 
| +    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
 | 
| +        SkString dirName = make_stat_dir_name(dirNo);
 | 
| +        if (!dirName.size()) {
 | 
| +            return false;
 | 
| +        }
 | 
| +        SkOSFile::Iter iter(dirName.c_str(), "skp");
 | 
| +        SkString filename;
 | 
| +        while (iter.next(&filename)) {
 | 
| +            TestResult test;
 | 
| +            test.init(dirNo);
 | 
| +            SkString spaceFile(filename);
 | 
| +            char* spaces = spaceFile.writable_str();
 | 
| +            int spaceSize = (int) spaceFile.size();
 | 
| +            for (int index = 0; index < spaceSize; ++index) {
 | 
| +                if (spaces[index] == '.') {
 | 
| +                    spaces[index] = ' ';
 | 
| +                }
 | 
| +            }
 | 
| +            int success = sscanf(spaces, "%s %d %d skp", test.fFilename,
 | 
| +                    &test.fPixelError, &test.fTime);
 | 
| +            if (success < 3) {
 | 
| +                SkDebugf("failed to scan %s matched=%d\n", filename.c_str(), success);
 | 
| +                return false;
 | 
| +            }
 | 
| +            *tests[dirNo - firstDirNo].append() = test;
 | 
| +        }
 | 
| +        if (!sorted) {
 | 
| +            continue;
 | 
| +        }
 | 
| +        SkTDArray<TestResult>& testSet = tests[dirNo - firstDirNo];
 | 
| +        int count = testSet.count();
 | 
| +        for (int index = 0; index < count; ++index) {
 | 
| +            *sorted[dirNo - firstDirNo].append() = (SortByName*) &testSet[index];
 | 
| +        }
 | 
| +        if (sorted[dirNo - firstDirNo].count()) {
 | 
| +            SkTQSort<SortByName>(sorted[dirNo - firstDirNo].begin(),
 | 
| +                    sorted[dirNo - firstDirNo].end() - 1);
 | 
| +            if (reporter->verbose()) {
 | 
| +                SkDebugf("+");
 | 
| +            }
 | 
| +       }
 | 
| +    }
 | 
| +    return true;
 | 
| +}
 | 
| +
 | 
| +bool Less(const SortByName& a, const SortByName& b);
 | 
| +bool Less(const SortByName& a, const SortByName& b) {
 | 
| +    return a < b;
 | 
| +}
 | 
| +
 | 
| +DEF_TEST(PathOpsSkpClipUberThreaded, reporter) {
 | 
| +    const int firstDirNo = 1;
 | 
| +    const int lastDirNo = 100;
 | 
| +    if (!initUberTest(firstDirNo, lastDirNo)) {
 | 
| +        return;
 | 
| +    }
 | 
| +    const int dirCount = lastDirNo - firstDirNo + 1;
 | 
| +    SkTDArray<TestResult> tests[dirCount];
 | 
| +    SkTDArray<SortByName*> sorted[dirCount];
 | 
| +    if (!buildTests(reporter, firstDirNo, lastDirNo, tests, sorted)) {
 | 
| +        return;
 | 
| +    }
 | 
| +    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
 | 
| +    TestRunner testRunner(reporter, threadCount);
 | 
| +    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
 | 
| +        SkString dirName = make_in_dir_name(dirNo);
 | 
| +        if (!dirName.size()) {
 | 
| +            continue;
 | 
| +        }
 | 
| +        SkOSFile::Iter iter(dirName.c_str(), "skp");
 | 
| +        SkString filename;
 | 
| +        while (iter.next(&filename)) {
 | 
| +            int count;
 | 
| +            SortByName name;
 | 
| +            for (size_t index = 0; index < skipOverSeptCount; ++index) {
 | 
| +                if (skipOverSept[index].directory == dirNo
 | 
| +                        && strcmp(filename.c_str(), skipOverSept[index].filename) == 0) {
 | 
| +                    goto checkEarlyExit;
 | 
| +                }
 | 
| +            }
 | 
| +            name.init(dirNo);
 | 
| +            strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
 | 
| +            count = sorted[dirNo - firstDirNo].count();
 | 
| +            if (SkTSearch<SortByName, Less>(sorted[dirNo - firstDirNo].begin(),
 | 
| +                    count, &name, sizeof(&name)) < 0) {
 | 
| +                *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableFile,
 | 
| +                        (&testSkpClipUber, dirNo, filename.c_str(), &testRunner));
 | 
| +            }
 | 
| +    checkEarlyExit:
 | 
| +            ;
 | 
| +        }
 | 
| +
 | 
| +    }
 | 
| +    testRunner.render();
 | 
| +    SkTDArray<TestResult> results[dirCount];
 | 
| +    if (!buildTests(reporter, firstDirNo, lastDirNo, results, NULL)) {
 | 
| +        return;
 | 
| +    }
 | 
| +    SkTDArray<TestResult> allResults;
 | 
| +    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
 | 
| +        SkTDArray<TestResult>& array = results[dirNo - firstDirNo];
 | 
| +        allResults.append(array.count(), array.begin());
 | 
| +    }
 | 
| +    int allCount = allResults.count();
 | 
| +    SkTDArray<SortByPixel*> pixels;
 | 
| +    SkTDArray<SortByTime*> times;
 | 
| +    for (int index = 0; index < allCount; ++index) {
 | 
| +        *pixels.append() = (SortByPixel*) &allResults[index];
 | 
| +        *times.append() = (SortByTime*) &allResults[index];
 | 
| +    }
 | 
| +    TestState state;
 | 
| +    if (pixels.count()) {
 | 
| +        SkTQSort<SortByPixel>(pixels.begin(), pixels.end() - 1);
 | 
| +        for (int inner = 0; inner < kMaxFiles; ++inner) {
 | 
| +            *state.fPixelWorst.append() = *pixels[allCount - inner - 1];
 | 
| +        }
 | 
| +    }
 | 
| +    if (times.count()) {
 | 
| +        SkTQSort<SortByTime>(times.begin(), times.end() - 1);
 | 
| +        for (int inner = 0; inner < kMaxFiles; ++inner) {
 | 
| +            *state.fSlowest.append() = *times[allCount - inner - 1];
 | 
| +        }
 | 
|      }
 | 
|      encodeFound(reporter, state);
 | 
|  }
 | 
| 
 |