12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642 |
- #if !UNITY_2019_1_OR_NEWER
- #define UNITY_PRE_2019_1
- #endif
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- #if !UNITY_2020_1_OR_NEWER
- using System.Reflection;
- #endif
- using System.Text.RegularExpressions;
- using System.Threading;
- using UnityEditor.IMGUI.Controls;
- using UnityEditorInternal;
- using UnityEngine;
- using UnityEngine.Profiling;
- using Debug = UnityEngine.Debug;
- #if UNITY_2017_1_OR_NEWER
- using ProfilerCommon = UnityEditorInternal.ProfilerDriver;
- #else
- using ProfilerCommon = UnityEngine.Profiling.Profiler;
- #endif
- #if UNITY_2018_3_OR_NEWER
- using ProfilerMarkerAbstracted = Unity.Profiling.ProfilerMarker;
- #else
- using ProfilerMarkerAbstracted = UnityEditor.Performance.ProfileAnalyzer.FakeScopedMarker;
- #endif
- namespace UnityEditor.Performance.ProfileAnalyzer
- {
- enum ThreadRange
- {
- Median,
- UpperQuartile,
- Max
- };
- enum ActiveTab
- {
- Summary,
- Compare,
- };
- enum ActiveView
- {
- Single,
- Left,
- Right
- }
- enum ThreadActivity
- {
- None,
- Analyze,
- AnalyzeDone,
- Compare,
- CompareDone,
- Load,
- LoadDone
- };
- enum TopTenDisplay
- {
- Normalized,
- LongestTime,
- };
- enum NameFilterOperation
- {
- All, // AND
- Any, // OR
- };
- /// <summary>
- /// Main profile Analyzer UI window
- /// </summary>
- public class ProfileAnalyzerWindow : EditorWindow
- {
- internal static class Styles
- {
- public static readonly GUIContent emptyString = new GUIContent("", "");
- public static readonly GUIContent dash = new GUIContent("-", "");
- public static readonly GUIContent thread = new GUIContent("Thread", "");
- public static readonly GUIContent noThread = new GUIContent("", "Thread not present on this data set");
- public static readonly GUIContent max = new GUIContent("Max", "The peak value in the data set");
- public static readonly GUIContent upperQuartile = new GUIContent("Upper Quartile", "The middle value between the median and the highest value of the data set. I.e. at 75% of the ordered data.");
- public static readonly GUIContent mean = new GUIContent("Mean", "The average value in the data set");
- public static readonly GUIContent median = new GUIContent("Median", "The central value in the data set");
- public static readonly GUIContent lowerQuartile = new GUIContent("Lower Quartile", "The middle number between the smallest number and the median of the data set. I.e. at 25% of the ordered data.");
- public static readonly GUIContent min = new GUIContent("Min", "The minimum value in the data set");
- public static readonly GUIContent individualMin = new GUIContent("Individual Min", "The minimum value in the data set for an individual marker instance (not the total in the frame)");
- public static readonly GUIContent individualMax = new GUIContent("Individual Max", "The maximum value in the data set for an individual marker instance (not the total in the frame)");
- public static readonly GUIContent export = new GUIContent("Export", "Export profiler data as CSV files");
- public static readonly GUIContent pullOpen = new GUIContent("Pull Data", "Pull data from Unity profiler.\nFirst you must open Unity profiler to pull data from it");
- public static readonly GUIContent pullRange = new GUIContent("Pull Data", "Pull data from Unity profiler.\nFirst you must use the Unity profiler to capture data from application");
- public static readonly GUIContent pullRecording = new GUIContent("Pull Data", "Pull data from Unity profiler.\nStop Unity profiler recording to enable pulling data");
- public static readonly GUIContent pull = new GUIContent("Pull Data", "Pull data from Unity profiler");
- public static readonly GUIContent nameFilter = new GUIContent("Name Filter : ", "Only show markers containing the strings");
- public static readonly GUIContent nameExclude = new GUIContent("Exclude Names : ", "Excludes markers containing the strings");
- public static readonly GUIContent threadFilter = new GUIContent("Thread : ", "Select threads to focus on");
- public static readonly GUIContent threadFilterSelect = new GUIContent("Select", "Select threads to focus on");
- public static readonly GUIContent unitFilter = new GUIContent("Units : ", "Units to show in UI");
- public static readonly GUIContent timingFilter = new GUIContent("Analysis Type : ", TimingOptions.Tooltip);
- public static readonly GUIContent markerColumns = new GUIContent("Marker Columns : ");
- public static readonly GUIContent graphPairing = new GUIContent("Pair Graph Selection", "Selections on one graph will affect the other");
- public static readonly GUIContent frameSummary = new GUIContent("Frame Summary", "");
- public static readonly GUIContent frameCount = new GUIContent("Frame Count", "Frame Count");
- public static readonly GUIContent frameStart = new GUIContent("Start", "Frame Start");
- public static readonly GUIContent frameEnd = new GUIContent("End", "Frame End");
- public static readonly GUIContent threadSummary = new GUIContent("Thread Summary", "");
- public static readonly GUIContent threadGraphScale = new GUIContent("Graph Scale : ", "");
- public static readonly GUIContent[] threadRanges =
- {
- new GUIContent("Median", "Median frame time"),
- new GUIContent("Upper quartile", "Upper quartile of frame time"),
- new GUIContent("Max", "Max frame time")
- };
- public static readonly GUIContent markerSummary = new GUIContent("Marker Summary", "");
- public static readonly GUIContent filters = new GUIContent("Filters", "");
- public static readonly GUIContent profileTable = new GUIContent("Marker Details for currently selected range", "");
- public static readonly GUIContent comparisonTable = new GUIContent("Marker Comparison for currently selected range", "");
- public static readonly GUIContent depthTitle = new GUIContent("Depth Slice : ", "Marker callstack depth to analyze");
- public static readonly GUIContent leftDepthTitle = new GUIContent("Left : ", "Marker callstack depth to analyze");
- public static readonly GUIContent rightDepthTitle = new GUIContent("Right : ", "Marker callstack depth to analyze");
- public static readonly string autoDepthTitleText = "Auto Depth (Diff: {0:+##;-##;None})";
- public static readonly GUIContent autoDepthTitle = new GUIContent("Auto Depth", "Match up the depth levels based on the most common difference between markers present in both data sets. If the selected depth is at a depth not present in the other data set, after applying this difference, it will use the deepest level.");
- public static readonly GUIContent parentMarker = new GUIContent("Parent Marker : ", "Marker to start analysis from. Parent of the hierarchy to analyze.");
- public static readonly GUIContent selectParentMarker = new GUIContent("None", "Select using right click context menu on marker names in marker table");
- public static readonly GUIContent topMarkerRatio = new GUIContent("Ratio : ", "Normalize\tNormalized to time of the individual set\nLongest\tRatio based on longest time of the two");
- public static readonly GUIContent firstFrame = new GUIContent("First frame", "");
- public static readonly GUIContent[] topTenDisplayOptions =
- {
- new GUIContent("Normalized", "Ratio normalized to time of the individual data set"),
- new GUIContent("Longest", "Ratio based on longest time of the two data sets")
- };
- public static readonly GUIContent[] nameFilterOperation =
- {
- new GUIContent("All", "Marker name contains all strings"),
- new GUIContent("Any", "Marker name contains any of the strings")
- };
- public static readonly GUIContent menuItemSelectFramesInAll = new GUIContent("Select Frames that contain this marker (within whole data set)", "");
- public static readonly GUIContent menuItemSelectFramesInCurrent = new GUIContent("Select Frames that contain this marker (within current selection)", "");
- public static readonly GUIContent menuItemSelectFramesAll = new GUIContent("Clear Selection", "");
- public static readonly GUIContent frameCosts = new GUIContent(" by frame costs", "Contains accumulated marker cost within the frame");
- public static readonly GUIContent dataMissing = new GUIContent("Pull or load a data set for analysis", "Pull data from Unity Profiler or load a previously saved analysis data set");
- public static readonly GUIContent comparisonDataMissing = new GUIContent("Pull or load a data set for comparison", "Pull data from Unity Profiler or load previously saved analysis data sets");
- public static readonly string topMarkersTooltip = "Top markers for the median frame.\nThe length of this frame is the median of those in the data set.\nIt is likely to be the most representative frame.";
- public static readonly string medianFrameTooltip = "The length of this frame is the median of those in the data set.\nIt is likely to be the most representative frame.";
- public static readonly string helpText =
- @"This tool can analyze Unity Profiler data, to find representative frames and perform comparisons of data sets.
- To gather data to analyze:
- * Open the Unity Profiler. Either via the Unity menu under 'Windows', 'Analysis' or via the 'Open Profile Window' in the tool bar.
- * Capture some profiling data in the Unity Profiler by selecting a target application and click the 'Record' button.
- * Stop the capture by clicking again on the 'Record' button.
- To analyze the data:
- * Pull the Unity Profiler data into this tool by clicking the 'Pull Data' button in the single or compare views.
- * The analysis will be automatically triggered (in the compare view two data sets are required before analysis is performed).
- * Select a marker to see more detailed information about its time utilization over the frame time range.
- * Save off a data file from here to keep for future use. (Recommend saving the profile .data file in the same folder).
- To compare two data sets:
- * Click the compare tab. The data in the single tab will be used by default. You can also load previously saved analysis data.
- * Drag select a region in the frame time graph (above) to choose 1 or more frames for each of the two data sets.
- * The comparison will be automatically triggered as the selection is made.";
- }
- const float k_ProgressBarHeight = 2f;
- ProgressBarDisplay m_ProgressBar;
- ProfileAnalyzer m_ProfileAnalyzer;
- ProfilerWindowInterface m_ProfilerWindowInterface;
- string m_LastProfilerSelectedMarker;
- string m_LastMarkerSuccesfullySyncedWithProfilerWindow = null;
- [NonSerialized] bool m_SelectionEventFromProfilerWindowInProgress = false;
- int m_TopNumber;
- string[] m_TopStrings;
- int[] m_TopValues;
- [SerializeField] DepthSliceUI m_DepthSliceUI;
- [SerializeField]
- TimingOptions.TimingOption m_TimingOption = TimingOptions.TimingOption.Time;
- [SerializeField]
- string m_ParentMarker = null;
- List<string> m_ThreadUINames = new List<string>();
- List<string> m_ThreadNames = new List<string>();
- Dictionary<string, string> m_ThreadNameToUIName;
- [SerializeField]
- ThreadSelection m_ThreadSelection = new ThreadSelection();
- ThreadSelection m_ThreadSelectionNew;
- string m_ThreadSelectionSummary;
- [SerializeField]
- DisplayUnits m_DisplayUnits = new DisplayUnits(Units.Milliseconds);
- string[] m_UnitNames;
- [SerializeField]
- string m_NameFilter = "";
- [SerializeField]
- string m_NameExclude = "";
- [SerializeField]
- MarkerColumnFilter m_SingleModeFilter = new MarkerColumnFilter(MarkerColumnFilter.Mode.TimeAndCount);
- [SerializeField]
- MarkerColumnFilter m_CompareModeFilter = new MarkerColumnFilter(MarkerColumnFilter.Mode.TimeAndCount);
- [SerializeField]
- TopTenDisplay m_TopTenDisplay = TopTenDisplay.Normalized;
- [SerializeField]
- NameFilterOperation m_NameFilterOperation = NameFilterOperation.All;
- [SerializeField]
- NameFilterOperation m_NameExcludeOperation = NameFilterOperation.Any;
- int m_ProfilerFirstFrameIndex = 0;
- int m_ProfilerLastFrameIndex = 0;
- const int k_ProfileDataDefaultDisplayOffset = 1;
- ActiveTab m_NextActiveTab = ActiveTab.Summary;
- ActiveTab m_ActiveTab = ActiveTab.Summary;
- bool m_OtherTabDirty = false;
- bool m_OtherTableDirty = false;
- [SerializeField]
- bool m_ShowFilters = true;
- [SerializeField]
- bool m_ShowTopNMarkers = true;
- [SerializeField]
- bool m_ShowFrameSummary = true;
- [SerializeField]
- bool m_ShowThreadSummary = false;
- [SerializeField]
- bool m_ShowMarkerSummary = true;
- [SerializeField]
- bool m_ShowMarkerTable = true;
- #if UNITY_PRE_2019_1
- bool m_NeedPre2019Enable;
- #endif
- internal static class UIColor
- {
- static internal Color Color256(int r, int g, int b, int a)
- {
- return new Color((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f);
- }
- public static readonly Color white = new UnityEngine.Color(1.0f, 1.0f, 1.0f);
- public static readonly Color barBackground = new Color(0.5f, 0.5f, 0.5f);
- public static readonly Color barBackgroundSelected = new Color(0.6f, 0.6f, 0.6f);
- public static readonly Color boxAndWhiskerBoxColor = Color256(112, 112, 112, 255);
- public static readonly Color boxAndWhiskerLineColorLeft = Color256(206, 219, 238, 255);
- public static readonly Color boxAndWhiskerBoxColorLeft = Color256(59, 104, 144, 255);
- public static readonly Color boxAndWhiskerLineColorRight = Color256(247, 212, 201, 255);
- public static readonly Color boxAndWhiskerBoxColorRight = Color256(161, 83, 30, 255);
- public static readonly Color bar = new Color(0.95f, 0.95f, 0.95f);
- public static readonly Color barSelected = new Color(0.5f, 1.0f, 0.5f);
- public static readonly Color standardLine = new Color(1.0f, 1.0f, 1.0f);
- public static readonly Color gridLines = new Color(0.4f, 0.4f, 0.4f);
- public static readonly Color left = Color256(111, 163, 216, 255);
- public static readonly Color leftSelected = Color256(06, 219, 238, 255);
- public static readonly Color right = Color256(238, 134, 84, 255);
- public static readonly Color rightSelected = Color256(247, 212, 201, 255);
- public static readonly Color both = Color256(175, 150, 150, 255);
- public static readonly Color textTopMarkers = Color256(0, 0, 0, 255);
- public static readonly Color marker = new Color(0.0f, 0.5f, 0.5f);
- public static readonly Color markerSelected = new Color(0.0f, 0.6f, 0.6f);
- public static readonly Color thread = new Color(0.5f, 0.0f, 0.5f);
- public static readonly Color threadSelected = new Color(0.6f, 0.0f, 0.6f);
- }
- [SerializeField]
- ProfileDataView m_ProfileSingleView;
- [SerializeField]
- ProfileDataView m_ProfileLeftView;
- [SerializeField]
- ProfileDataView m_ProfileRightView;
- [SerializeField] ThreadMarkerInfo m_SelectedMarker = new ThreadMarkerInfo();
- [Serializable]
- struct ThreadMarkerInfo
- {
- [SerializeField]
- public int id;
- [SerializeField]
- public string threadName;
- [SerializeField]
- public string threadGroupName;
- [SerializeField]
- public string name;
- }
- FrameTimeGraphGlobalSettings m_FrameTimeGraphGlobalSettings;
- FrameTimeGraph m_FrameTimeGraph;
- FrameTimeGraph m_LeftFrameTimeGraph;
- FrameTimeGraph m_RightFrameTimeGraph;
- bool m_FrameTimeGraphsPaired = true;
- TopMarkers m_TopMarkers;
- TopMarkers m_TopMarkersLeft;
- TopMarkers m_TopMarkersRight;
- List<MarkerPairing> m_PairingsNew;
- int m_TotalCombinedMarkerCountNew;
- [SerializeField]
- List<MarkerPairing> m_Pairings = new List<MarkerPairing>();
- int m_TotalCombinedMarkerCount = 0;
- [SerializeField]
- int m_SelectedPairing = 0;
- [SerializeField]
- TreeViewState m_ProfileTreeViewState;
- [SerializeField]
- MultiColumnHeaderState m_ProfileMulticolumnHeaderState;
- ProfileTable m_ProfileTable;
- [SerializeField]
- TreeViewState m_ComparisonTreeViewState;
- [SerializeField]
- MultiColumnHeaderState m_ComparisonMulticolumnHeaderState;
- ComparisonTable m_ComparisonTable;
- internal static class LayoutSize
- {
- public static readonly int WidthColumn0 = 100;
- public static readonly int WidthColumn1 = 52; // +2 to prevent some
- public static readonly int WidthColumn2 = 52;
- public static readonly int WidthColumn3 = 52;
- public static readonly int WidthRHS = 290; // Column widths + label padding between (276) + scrollbar width
- public static readonly int FilterOptionsLeftLabelWidth = 100;
- public static readonly int FilterOptionsEnumWidth = 50;
- public static readonly int FilterOptionsLockedEnumWidth = 120;
- public static readonly int FilterOptionsRightLabelWidth = 110;
- public static readonly int FilterOptionsRightEnumWidth = 150;
- public static readonly int HistogramWidth = 153;
- public static readonly int MinWindowWidth = 800 + WidthRHS;
- public static readonly int MinWindowHeight = 480;
- public static readonly int WindowWidth = MinWindowWidth;
- public static readonly int WindowHeight = 840;
- public static readonly int ScrollBarPadding = 6; // this is legacy and we might be able to kill it but it will slightly change the layout of the window.
- }
- Columns m_Columns = new Columns(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- [SerializeField]
- ThreadRange m_ThreadRange = ThreadRange.UpperQuartile;
- internal Draw2D m_2D;
- bool m_Async = true;
- Thread m_BackgroundThread;
- ThreadActivity m_ThreadActivity;
- ProfileData m_ProfilerData;
- string m_Path;
- int m_ThreadPhase;
- int m_ThreadPhases;
- int m_ThreadProgress;
- bool m_RequestRepaint;
- bool m_RequestAnalysis;
- bool m_RequestCompare;
- bool m_FullAnalysisRequired;
- bool m_FullCompareRequired;
- [SerializeField]
- int m_TopNBars = 10;
- bool m_EnableAnalysisProfiling = false;
- int m_AnalyzeInUpdatePhase = 0;
- string m_LastAnalysisTime = "";
- string m_LastCompareTime = "";
- float m_LastAnalysisTimeMilliseconds;
- float m_LastCompareTimeMilliseconds;
- bool m_NewDataLoaded = false;
- bool m_NewComparisonDataLoaded = false;
- Vector2 m_HelpScroll = new Vector2(0, 0);
- Vector2 m_ThreadScroll = new Vector2(0, 0);
- Vector2 m_MarkerSummaryScroll = new Vector2(0, 0);
- Rect m_ThreadsAreaRect = new Rect();
- Rect m_ComparisonThreadsAreaRect = new Rect();
- Vector2 m_LastScreenSize = new Vector2(0, 0);
- bool m_ScreenSizeChanged;
- double m_ScreenSizeChangedTimeStarted;
- double m_ScreenSizeChangedTimeFinished;
- ActiveTab m_ScreenSizeChangedTab;
- GUIStyle m_StyleMiddleRight;
- GUIStyle m_StyleUpperLeft;
- bool m_StylesSetup = false;
- static Regex quotedStringWithoutQuotes = new Regex("\"([^\"]*)\"");
- static Regex quotedString = new Regex("(\"[^\"]*\")");
- static Regex stringWithoutWhiteSpace = new Regex("([^ \t]+)");
- /*
- static Regex lastSpace = new Regex("(.+)[ ]([^ ]*)");
- */
- #if UNITY_2018_1_OR_NEWER
- [MenuItem("Window/Analysis/Profile Analyzer")]
- #else
- [MenuItem("Window/Profile Analyzer")]
- #endif
- static void Init()
- {
- var window = GetWindow<ProfileAnalyzerWindow>("Profile Analyzer");
- window.minSize = new Vector2(LayoutSize.MinWindowWidth, LayoutSize.MinWindowHeight);
- window.position.size.Set(LayoutSize.WindowWidth, LayoutSize.WindowHeight);
- window.Show();
- window.m_LastScreenSize = window.position.size;
- }
- /// <summary>
- /// Open profile analyzer window
- /// </summary>
- public static void OpenProfileAnalyzer()
- {
- Init();
- }
- void Awake()
- {
- m_ScreenSizeChanged = false;
- m_ScreenSizeChangedTimeStarted = 0.0;
- m_ScreenSizeChangedTimeFinished = 0.0;
- m_ScreenSizeChangedTab = ActiveTab.Summary;
- m_ProfileSingleView = new ProfileDataView();
- m_ProfileLeftView = new ProfileDataView();
- m_ProfileRightView = new ProfileDataView();
- m_RequestRepaint = false;
- m_RequestAnalysis = false;
- m_RequestCompare = false;
- m_FrameTimeGraphGlobalSettings = new FrameTimeGraphGlobalSettings();
- }
- static int s_TmpCount = 0;
- static string s_TmpDir = "";
- ActiveView m_ActiveLoadingView;
- static string s_ApplicationDataPath;
- internal static string TmpDir
- {
- get
- {
- if (string.IsNullOrEmpty(s_ApplicationDataPath))
- s_ApplicationDataPath = Application.dataPath;
- if (string.IsNullOrEmpty(s_TmpDir))
- s_TmpDir = string.Format("{0}{1}ProfileAnalyzer{1}", Directory.GetParent(s_ApplicationDataPath).FullName, Path.DirectorySeparatorChar);
- return s_TmpDir;
- }
- }
- internal static string TmpPath
- {
- get
- {
- if (!Directory.Exists(TmpDir))
- Directory.CreateDirectory(TmpDir);
- while (File.Exists(string.Format("{0}tmp{1}.pdata", TmpDir, s_TmpCount)))
- {
- s_TmpCount++;
- }
- return string.Format("{0}tmp{1}.pdata", TmpDir, s_TmpCount);
- }
- }
- void OnEnable()
- {
- //do this here to safeguard against Application.dataPAth being accessed off the main thread
- s_ApplicationDataPath = Application.dataPath;
- // Update styles so we get the theme changes
- m_StylesSetup = false;
- ProfileAnalyzerAnalytics.EnableAnalytics();
- m_ProgressBar = new ProgressBarDisplay();
- if (m_DepthSliceUI == null)
- m_DepthSliceUI = new DepthSliceUI(b => UpdateActiveTab(b));
- else
- m_DepthSliceUI.OnEnable(b => UpdateActiveTab(b));
- m_ProfilerWindowInterface = new ProfilerWindowInterface(m_ProgressBar);
- if (!m_ProfilerWindowInterface.IsReady())
- {
- m_ProfilerWindowInterface.GetProfilerWindowHandle();
- }
- if (!string.IsNullOrEmpty(m_SelectedMarker.name))
- {
- var oldSelectedMarkerName = m_SelectedMarker;
- m_SelectedMarker.name = null;
- // wait a frame for the ProfilerWindow to get Enabled before re-setting the selection
- EditorApplication.delayCall += () => SelectMarkerByName(oldSelectedMarkerName.name, oldSelectedMarkerName.threadGroupName, oldSelectedMarkerName.threadName);
- }
- m_ProfilerWindowInterface.selectedMarkerChanged -= OnProfilerWindowCpuModuleSelectionChanged;
- m_ProfilerWindowInterface.selectedMarkerChanged += OnProfilerWindowCpuModuleSelectionChanged;
- m_ProfilerWindowInterface.selectedFrameChanged -= OnProfilerWindowSelectedFrameChanged;
- m_ProfilerWindowInterface.selectedFrameChanged += OnProfilerWindowSelectedFrameChanged;
- m_ProfileAnalyzer = new ProfileAnalyzer();
- if (m_ThreadSelection == null || m_ThreadSelection.empty)
- {
- ThreadIdentifier mainThreadSelection = new ThreadIdentifier("Main Thread", 1);
- m_ThreadSelection.Set(mainThreadSelection.threadNameWithIndex);
- }
- if (m_ThreadSelectionNew != null && m_ThreadSelectionNew.empty)
- m_ThreadSelectionNew = null;
- m_2D = new Draw2D("Unlit/ProfileAnalyzerShader");
- FrameTimeGraph.SetGlobalSettings(m_FrameTimeGraphGlobalSettings);
- m_FrameTimeGraph = new FrameTimeGraph(0, m_2D, m_DisplayUnits.Units, UIColor.barBackground, UIColor.barBackgroundSelected, UIColor.bar, UIColor.barSelected, UIColor.marker, UIColor.markerSelected, UIColor.thread, UIColor.threadSelected, UIColor.gridLines);
- m_FrameTimeGraph.SetRangeCallback(SetRange);
- m_FrameTimeGraph.SetActiveCallback(GraphActive);
- m_LeftFrameTimeGraph = new FrameTimeGraph(1, m_2D, m_DisplayUnits.Units, UIColor.barBackground, UIColor.barBackgroundSelected, UIColor.left, UIColor.leftSelected, UIColor.marker, UIColor.markerSelected, UIColor.thread, UIColor.threadSelected, UIColor.gridLines);
- m_LeftFrameTimeGraph.SetRangeCallback(SetLeftRange);
- m_LeftFrameTimeGraph.SetActiveCallback(GraphActive);
- m_RightFrameTimeGraph = new FrameTimeGraph(2, m_2D, m_DisplayUnits.Units, UIColor.barBackground, UIColor.barBackgroundSelected, UIColor.right, UIColor.rightSelected, UIColor.marker, UIColor.markerSelected, UIColor.thread, UIColor.threadSelected, UIColor.gridLines);
- m_RightFrameTimeGraph.SetRangeCallback(SetRightRange);
- m_RightFrameTimeGraph.SetActiveCallback(GraphActive);
- m_LeftFrameTimeGraph.PairWith(m_FrameTimeGraphsPaired ? m_RightFrameTimeGraph : null);
- m_TopMarkers = new TopMarkers(this, m_2D, UIColor.barBackground, UIColor.textTopMarkers);
- m_TopMarkersLeft = new TopMarkers(this, m_2D, UIColor.barBackground, UIColor.textTopMarkers);
- m_TopMarkersRight = new TopMarkers(this, m_2D, UIColor.barBackground, UIColor.textTopMarkers);
- m_ThreadActivity = ThreadActivity.None;
- m_ThreadProgress = 0;
- m_ThreadPhase = 0;
- List<int> values = new List<int>();
- List<String> strings = new List<string>();
- for (int i = 1; i <= 10; i++)
- {
- values.Add(i);
- strings.Add(i.ToString());
- }
- m_TopValues = values.ToArray();
- m_TopStrings = strings.ToArray();
- m_TopNumber = 3;
- List<string> unitNames = new List<string>(DisplayUnits.UnitNames);
- unitNames.RemoveAt(unitNames.Count - 1);
- m_UnitNames = unitNames.ToArray();
- // Regrenerate analysis if just re initialised with the existing profile data reloaded from serialisation (e.g. on enter play mode)
- // As we don't serialise the analysis itself.
- // UpdateActiveTab(true);
- UpdateThreadNames();
- if (m_ProfileSingleView.analysis != null)
- {
- CreateProfileTable();
- m_RequestRepaint = true;
- }
- if (m_ProfileLeftView.analysis != null && m_ProfileRightView.analysis != null)
- {
- CreateComparisonTable();
- m_RequestRepaint = true;
- }
- // Mouse movement calls OnGui
- wantsMouseMove = true;
- }
- void OnDisable()
- {
- if (ProfileAnalyzerExportWindow.IsOpen())
- ProfileAnalyzerExportWindow.CloseAll();
- m_ProfilerWindowInterface.selectedMarkerChanged -= OnProfilerWindowCpuModuleSelectionChanged;
- m_ProfilerWindowInterface.selectedFrameChanged -= OnProfilerWindowSelectedFrameChanged;
- m_ProfilerWindowInterface.OnDisable();
- m_ProfilerWindowInterface = null;
- }
- void OnDestroy()
- {
- if (m_BackgroundThread != null)
- m_BackgroundThread.Abort();
- Pre2019ReEnableRecording();
- if (m_ProfileSingleView != null && m_ProfileSingleView.data != null)
- m_ProfileSingleView.data.DeleteTmpFiles();
- if (m_ProfileLeftView != null && m_ProfileLeftView.data != null)
- m_ProfileLeftView.data.DeleteTmpFiles();
- if (m_ProfileRightView != null && m_ProfileRightView.data != null)
- m_ProfileRightView.data.DeleteTmpFiles();
- if (Directory.Exists(TmpDir) && Directory.GetFiles(TmpDir).Length == 0)
- Directory.Delete(TmpDir, true);
- }
- bool DisplayCount()
- {
- switch (m_SingleModeFilter.mode)
- {
- case MarkerColumnFilter.Mode.CountTotals:
- case MarkerColumnFilter.Mode.CountPerFrame:
- return true;
- default:
- return false;
- }
- }
- void OnGUI()
- {
- if (Event.current.type != EventType.MouseMove)
- {
- m_2D.OnGUI();
- Draw();
- }
- ProcessInput();
- }
- bool TmpInUse(ProfileDataView dv, string path)
- {
- if (dv != m_ProfileSingleView && m_ProfileSingleView.data != null && m_ProfileSingleView.data.FilePath == path)
- return true;
- if (dv != m_ProfileLeftView && m_ProfileLeftView.data != null && m_ProfileLeftView.data.FilePath == path)
- return true;
- if (dv != m_ProfileRightView && m_ProfileRightView.data != null && m_ProfileRightView.data.FilePath == path)
- return true;
- return false;
- }
- void SetView(ProfileDataView dst, ProfileData data, string path, FrameTimeGraph graph)
- {
- if (!data.IsSame(dst.data))
- {
- if (dst == m_ProfileSingleView)
- m_NewDataLoaded = true;
- else
- m_NewComparisonDataLoaded = true;
- }
- if (dst.data != null && (m_NewDataLoaded || m_NewComparisonDataLoaded) && !TmpInUse(dst, dst.data.FilePath))
- dst.data.DeleteTmpFiles();
- dst.data = data;
- dst.path = path;
- dst.SelectFullRange();
- graph.Reset();
- graph.SetData(GetFrameTimeData(dst.data));
- // One of the views changed so make sure the export window knows if its open
- ProfileAnalyzerExportWindow exportWindow = ProfileAnalyzerExportWindow.FindOpenWindow();
- if (exportWindow != null)
- {
- exportWindow.SetData(m_ProfileSingleView, m_ProfileLeftView, m_ProfileRightView);
- }
- }
- void SetView(ProfileDataView dst, ProfileDataView src, FrameTimeGraph graph)
- {
- SetView(dst, src.data, src.path, graph);
- }
- void UpdateThreadNames()
- {
- // Update threads list
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- GetThreadNames(m_ProfileSingleView.data, out m_ThreadUINames, out m_ThreadNames, out m_ThreadNameToUIName);
- break;
- case ActiveTab.Compare:
- GetThreadNames(m_ProfileLeftView.data, m_ProfileRightView.data, out m_ThreadUINames, out m_ThreadNames, out m_ThreadNameToUIName);
- break;
- }
- UpdateThreadGroupSelection(m_ThreadNames, m_ThreadSelection);
- m_ThreadSelectionSummary = CalculateSelectedThreadsSummary();
- }
- void ProcessTabSwitch()
- {
- if (m_NextActiveTab != m_ActiveTab)
- {
- m_ActiveTab = m_NextActiveTab;
- // Copy data if none present for this tab
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- if (!m_ProfileSingleView.IsDataValid())
- {
- if (m_ProfileLeftView.IsDataValid())
- {
- SetView(m_ProfileSingleView, m_ProfileLeftView, m_FrameTimeGraph);
- m_RequestAnalysis = true;
- m_FullAnalysisRequired = true;
- }
- else if (m_ProfileRightView.IsDataValid())
- {
- SetView(m_ProfileSingleView, m_ProfileRightView, m_FrameTimeGraph);
- m_RequestAnalysis = true;
- m_FullAnalysisRequired = true;
- }
- }
- break;
- case ActiveTab.Compare:
- if ((!m_ProfileLeftView.IsDataValid() || !m_ProfileRightView.IsDataValid()) && m_ProfileSingleView.IsDataValid())
- {
- if (!m_ProfileLeftView.IsDataValid())
- {
- SetView(m_ProfileLeftView, m_ProfileSingleView, m_LeftFrameTimeGraph);
- }
- if (!m_ProfileRightView.IsDataValid())
- {
- SetView(m_ProfileRightView, m_ProfileSingleView, m_RightFrameTimeGraph);
- }
- // Remove pairing of both left/right point at the same data
- if (m_ProfileLeftView.path == m_ProfileRightView.path)
- {
- SetFrameTimeGraphPairing(false);
- }
- m_RequestCompare = true;
- m_FullCompareRequired = true;
- }
- break;
- }
- UpdateThreadNames();
- if (!m_OtherTableDirty)
- SelectMarker(m_SelectedMarker.name);
- if (m_OtherTabDirty)
- {
- UpdateActiveTab(true, false); // Make sure any depth/thread updates are applied when switching tabs, but don't dirty the other tab
- m_OtherTabDirty = false;
- }
- if (m_OtherTableDirty)
- {
- UpdateMarkerTable(false); // Make sure any marker selection updates are applied when switching tabs, but don't dirty the other tab
- m_OtherTableDirty = false;
- }
- if (!m_RequestAnalysis && !m_RequestCompare)
- m_DepthSliceUI.UpdateDepthFilters(m_ActiveTab == ActiveTab.Summary, m_ProfileSingleView, m_ProfileLeftView, m_ProfileRightView);
- }
- }
- bool IsDocked()
- {
- #if UNITY_2020_1_OR_NEWER
- return docked;
- #else
- BindingFlags fullBinding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
- MethodInfo isDockedMethod = typeof(EditorWindow).GetProperty("docked", fullBinding).GetGetMethod(true);
- bool isDocked = (bool)isDockedMethod.Invoke(this, null);
- return isDocked;
- #endif // UNITY_2020_1_OR_NEWER
- }
- void CheckScreenSizeChanges()
- {
- // We get a 5 pixel change in y height during initialization.
- // We could wait before considering size changes but using a delta is also useful
- float sizeDeltaForChange = 10;
- Vector2 sizeDiff = position.size - m_LastScreenSize;
- if (Math.Abs(sizeDiff.x) > sizeDeltaForChange || Math.Abs(sizeDiff.y) > sizeDeltaForChange)
- {
- if (m_LastScreenSize.x != 0) // At initialization time the screen size has not yet been recorded. Don't consider this a screen size change
- {
- m_LastScreenSize = position.size;
- if (!m_ScreenSizeChanged)
- {
- // Record when we started the change
- m_ScreenSizeChanged = true;
- m_ScreenSizeChangedTimeStarted = EditorApplication.timeSinceStartup;
- }
- // Record the last time of a change
- m_ScreenSizeChangedTimeFinished = EditorApplication.timeSinceStartup;
- // Record which tab we were on when it was changed
- m_ScreenSizeChangedTab = m_ActiveTab;
- }
- }
- if (m_ScreenSizeChanged)
- {
- double secondsSinceChanged = (EditorApplication.timeSinceStartup - m_ScreenSizeChangedTimeFinished);
- double secondsToDelay = 3f;
- if (secondsSinceChanged > secondsToDelay)
- {
- // Send analytic
- var uiResizeView = m_ScreenSizeChangedTab == ActiveTab.Summary ? ProfileAnalyzerAnalytics.UIResizeView.Single : ProfileAnalyzerAnalytics.UIResizeView.Comparison;
- float durationInSeconds = (float)(m_ScreenSizeChangedTimeFinished - m_ScreenSizeChangedTimeStarted);
- ProfileAnalyzerAnalytics.SendUIResizeEvent(uiResizeView, durationInSeconds, position.size.x, position.size.y, IsDocked());
- m_ScreenSizeChanged = false;
- }
- }
- }
- internal void RequestRepaint()
- {
- m_RequestRepaint = true;
- }
- void ProcessInput()
- {
- FrameTimeGraph.State inputStatus = FrameTimeGraph.State.None;
- if (m_ActiveTab == ActiveTab.Summary)
- {
- inputStatus = m_FrameTimeGraph.ProcessInput();
- }
- else if (m_ActiveTab == ActiveTab.Compare)
- {
- if (m_ProfileLeftView.IsDataValid() && inputStatus == FrameTimeGraph.State.None)
- inputStatus = m_LeftFrameTimeGraph.ProcessInput();
- if (m_ProfileRightView.IsDataValid() && inputStatus == FrameTimeGraph.State.None)
- inputStatus = m_RightFrameTimeGraph.ProcessInput();
- }
- switch (inputStatus)
- {
- case FrameTimeGraph.State.Dragging:
- m_RequestRepaint = true;
- break;
- case FrameTimeGraph.State.DragComplete:
- m_RequestCompare = true;
- break;
- }
- if (Event.current.isKey && Event.current.type == EventType.KeyDown)
- {
- switch (Event.current.keyCode)
- {
- case KeyCode.Alpha1:
- if (m_ActiveTab == ActiveTab.Summary)
- {
- m_FrameTimeGraph.MakeGraphActive(true);
- GUI.FocusControl("FrameTimeGraph");
- }
- else if (m_ActiveTab == ActiveTab.Compare)
- {
- m_LeftFrameTimeGraph.MakeGraphActive(true);
- GUI.FocusControl("LeftFrameTimeGraph");
- }
- m_RequestRepaint = true;
- break;
- case KeyCode.Alpha2:
- if (m_ActiveTab == ActiveTab.Compare)
- {
- m_RightFrameTimeGraph.MakeGraphActive(true);
- GUI.FocusControl("RightFrameTimeGraph");
- }
- m_RequestRepaint = true;
- break;
- }
- }
- }
- //Check if the ProfileDataView is in sync with the loaded frame data inside the profiler window
- //We are required to do this check in order to either enable or disable the ability to
- //jump into the matching frame data(loaded in the profiler window) for a specific profile analyzer capture
- void VerifyFrameDataInSyncWithProfilerWindow(ProfileDataView dataView)
- {
- var firstFrameIdx = m_ProfilerFirstFrameIndex - 1;
- var incompleteFrameCount = 0;
- if (dataView != null && dataView.data != null)
- incompleteFrameCount = (dataView.data.FirstFrameIncomplete ? 1 : 0) + (dataView.data.LastFrameIncomplete ? 1 : 0);
- var loadedFrameCount = m_ProfilerLastFrameIndex - m_ProfilerFirstFrameIndex + (firstFrameIdx != -1 ? 1 : 0)
- - incompleteFrameCount;
- if (loadedFrameCount == 0
- || !dataView.IsDataValid() //check if the data is valid and potentially reload the file, .data shouldn't be accessed before this point
- || dataView.data.GetFrameCount() != loadedFrameCount
- || m_ProfilerWindowInterface.GetThreadCountForFrame(firstFrameIdx) != dataView.data.GetFrame(0).threads.Count)
- {
- dataView.inSyncWithProfilerData = false;
- }
- else
- {
- var pDataFrame = dataView.data.GetFrame(0); //get the first frame we don't care about the offset as we only need to compare frames
- var loadedFrame = m_ProfilerWindowInterface.GetProfileFrameForThread(firstFrameIdx, 0);
- //compare frame start time and duration
- //todo improve this
- if (pDataFrame.msStartTime != loadedFrame.msStartTime
- || pDataFrame.msFrame != loadedFrame.msFrame)
- {
- dataView.inSyncWithProfilerData = false;
- }
- else
- {
- dataView.inSyncWithProfilerData = true;
- }
- }
- }
- //Returns true if we were able to sync with the window, but not necessarily if the data is in sync
- bool SyncWithProfilerWindow()
- {
- if (m_ProfilerWindowInterface.IsReady())
- {
- // Check if a new profile has been recorded (or loaded) by checking the frame index range.
- int first;
- int last;
- m_ProfilerWindowInterface.GetFrameRangeFromProfiler(out first, out last);
- if (first != m_ProfilerFirstFrameIndex || last != m_ProfilerLastFrameIndex)
- {
- // Store the updated range and alter the pull range
- m_ProfilerFirstFrameIndex = first;
- m_ProfilerLastFrameIndex = last;
- }
- VerifyFrameDataInSyncWithProfilerWindow(m_ProfileSingleView);
- VerifyFrameDataInSyncWithProfilerWindow(m_ProfileLeftView);
- VerifyFrameDataInSyncWithProfilerWindow(m_ProfileRightView);
- return true;
- }
- m_ProfilerWindowInterface.GetProfilerWindowHandle();
- return false;
- }
- void OnProfilerWindowCpuModuleSelectionChanged(string selectedMarker, string threadGroupName, string threadName)
- {
- // selectedMarker can be "" if in play mode and no active timeline shown (on versions pre 2021.1
- if (!string.IsNullOrEmpty(selectedMarker) && selectedMarker != m_LastProfilerSelectedMarker)
- {
- m_LastProfilerSelectedMarker = selectedMarker;
- m_SelectionEventFromProfilerWindowInProgress = true;
- SelectMarker(selectedMarker, threadGroupName, threadName);
- m_SelectionEventFromProfilerWindowInProgress = false;
- Repaint();
- }
- }
- void OnProfilerWindowSelectedFrameChanged(int newlySelectedFrame)
- {
- // selectedMarker can be "" if in play mode and no active timeline shown (on versions pre 2021.1
- if (!string.IsNullOrEmpty(m_LastProfilerSelectedMarker))
- {
- m_SelectionEventFromProfilerWindowInProgress = true;
- UpdateSelectedMarkerName(m_LastProfilerSelectedMarker);
- m_SelectionEventFromProfilerWindowInProgress = false;
- Repaint();
- }
- }
- void Update()
- {
- CheckScreenSizeChanges();
- // Check if profiler is open
- if (SyncWithProfilerWindow())
- {
- // Check if the selected marker in the profiler has changed
- m_ProfilerWindowInterface.PollProfilerWindowMarkerName();
- m_ProfilerWindowInterface.PollSelectedFrameChanges();
- }
- // Deferred to here so drawing isn't messed up by changing tab half way through a function rendering the old tab
- ProcessTabSwitch();
- // Force repaint for the progress bar
- if (IsAnalysisRunning())
- {
- int loadingProgress;
- int analysisProgress;
- if (IsLoading())
- {
- loadingProgress = (int)(ProfileData.GetLoadingProgress() * 100);
- analysisProgress = 0;
- }
- else
- {
- loadingProgress = 100;
- analysisProgress = m_ProfileAnalyzer.GetProgress();
- if (m_ThreadPhases > 1)
- {
- // Use thread phases to evaluate the progress as analysis process might contain multiple ProfileAnalyzer passes.
- analysisProgress = (100 * m_ThreadPhase) / m_ThreadPhases;
- }
- }
- int progress = (loadingProgress + analysisProgress) / 2;
- if (m_ThreadProgress != progress)
- {
- m_ThreadProgress = progress;
- m_RequestRepaint = true;
- }
- }
- if (m_ThreadSelectionNew != null)
- {
- m_ThreadSelection = new ThreadSelection(m_ThreadSelectionNew);
- m_ThreadSelectionNew = null;
- m_ThreadSelectionSummary = CalculateSelectedThreadsSummary();
- }
- switch (m_ThreadActivity)
- {
- case ThreadActivity.AnalyzeDone:
- // Create table when analysis complete
- Pre2019ReEnableRecording();
- UpdateAnalysisFromAsyncProcessing(m_ProfileSingleView, m_FullAnalysisRequired);
- m_FullAnalysisRequired = false;
- UpdateThreadNames();
- if (m_ProfileSingleView.analysis != null)
- {
- CreateProfileTable();
- m_RequestRepaint = true;
- }
- m_ThreadActivity = ThreadActivity.None;
- if (m_NewDataLoaded)
- {
- if (m_ProfileSingleView.IsDataValid())
- {
- // Don't bother sending an analytic if the data set is empty (should never occur anyway but consistent with comparison flow)
- ProfileAnalyzerAnalytics.SendUIUsageModeEvent(ProfileAnalyzerAnalytics.UIUsageMode.Single, m_LastAnalysisTimeMilliseconds / 1000f);
- }
- m_NewDataLoaded = false;
- }
- SelectMarker(m_SelectedMarker.name);
- break;
- case ThreadActivity.CompareDone:
- Pre2019ReEnableRecording();
- UpdateAnalysisFromAsyncProcessing(m_ProfileLeftView, m_FullCompareRequired);
- UpdateAnalysisFromAsyncProcessing(m_ProfileRightView, m_FullCompareRequired);
- m_FullCompareRequired = false;
- m_Pairings = m_PairingsNew;
- m_TotalCombinedMarkerCount = m_TotalCombinedMarkerCountNew;
- UpdateThreadNames();
- if (m_ProfileLeftView.analysis != null && m_ProfileRightView.analysis != null)
- {
- CreateComparisonTable();
- m_RequestRepaint = true;
- }
- m_ThreadActivity = ThreadActivity.None;
- if (m_NewComparisonDataLoaded)
- {
- if (m_ProfileLeftView.IsDataValid() && m_ProfileRightView.IsDataValid())
- {
- // Don't bother sending an analytic when one (or more) of the data sets is blank (as no comparison is really made)
- ProfileAnalyzerAnalytics.SendUIUsageModeEvent(ProfileAnalyzerAnalytics.UIUsageMode.Comparison, m_LastCompareTimeMilliseconds / 1000f);
- }
- m_NewComparisonDataLoaded = false;
- }
- SelectMarker(m_SelectedMarker.name);
- break;
- case ThreadActivity.LoadDone:
- Pre2019ReEnableRecording();
- SetView(GetActiveView, m_ProfilerData, m_Path, GetActiveFrameTimeGraph);
- switch (m_ActiveTab)
- {
- case ActiveTab.Compare:
- // Remove pairing if both left/right point at the same data
- if (m_ProfileLeftView.path == m_ProfileRightView.path)
- {
- SetFrameTimeGraphPairing(false);
- }
- m_FullCompareRequired = true;
- m_RequestCompare = true;
- break;
- case ActiveTab.Summary:
- m_RequestAnalysis = true;
- m_FullAnalysisRequired = true;
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- m_ThreadActivity = ThreadActivity.None;
- break;
- }
- if (m_RequestAnalysis)
- {
- if (!IsAnalysisRunning())
- {
- Analyze();
- m_RequestAnalysis = false;
- }
- }
- if (m_RequestCompare)
- {
- if (!IsAnalysisRunning())
- {
- Compare();
- m_RequestCompare = false;
- }
- }
- if (m_RequestRepaint)
- {
- Repaint();
- m_RequestRepaint = false;
- }
- if (m_AnalyzeInUpdatePhase > 0)
- {
- switch (m_AnalyzeInUpdatePhase)
- {
- case 1:
- UnityEngine.Profiling.Profiler.enabled = true;
- m_AnalyzeInUpdatePhase++;
- return;
- case 2:
- AnalyzeSync();
- UpdateAnalysisFromAsyncProcessing(m_ProfileSingleView, m_FullAnalysisRequired);
- m_FullAnalysisRequired = false;
- m_AnalyzeInUpdatePhase++;
- return;
- case 3:
- m_AnalyzeInUpdatePhase++;
- return;
- case 4:
- UnityEngine.Profiling.Profiler.enabled = false;
- m_AnalyzeInUpdatePhase++;
- return;
- default:
- m_AnalyzeInUpdatePhase = 0;
- break;
- }
- }
- }
- void Pre2019ReEnableRecording()
- {
- #if UNITY_PRE_2019_1
- if (m_NeedPre2019Enable)
- {
- m_NeedPre2019Enable = false;
- ProfilerCommon.enabled = true;
- }
- #endif
- }
- void Pre2019DisableRecording()
- {
- #if UNITY_PRE_2019_1
- if (ProfilerCommon.enabled && ProfilerDriver.deepProfiling && (EditorApplication.isPlaying || ProfilerDriver.profileEditor))
- {
- ProfilerCommon.enabled = false;
- m_NeedPre2019Enable = true;
- }
- #endif
- }
- ProfileDataView GetActiveView
- {
- get
- {
- switch (m_ActiveLoadingView)
- {
- case ActiveView.Single:
- return m_ProfileSingleView;
- case ActiveView.Left:
- return m_ProfileLeftView;
- case ActiveView.Right:
- return m_ProfileRightView;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
- }
- FrameTimeGraph GetActiveFrameTimeGraph
- {
- get
- {
- switch (m_ActiveLoadingView)
- {
- case ActiveView.Single:
- return m_FrameTimeGraph;
- case ActiveView.Left:
- return m_LeftFrameTimeGraph;
- case ActiveView.Right:
- return m_RightFrameTimeGraph;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
- }
- void UpdateAnalysisFromAsyncProcessing(ProfileDataView view, bool full)
- {
- view.analysis = view.analysisNew;
- if (full)
- {
- if (view.selectedIndices != null && view.IsDataValid() && view.selectedIndices.Count == view.data.GetFrameCount())
- view.analysisFull = view.analysis;
- else
- view.analysisFull = view.analysisFullNew;
- }
- }
- List<FrameTimeGraph.Data> GetFrameTimeData(ProfileData profileData)
- {
- List<FrameTimeGraph.Data> data = new List<FrameTimeGraph.Data>();
- int frames = profileData.GetFrameCount();
- for (int frameOffset = 0; frameOffset < frames; frameOffset++)
- {
- float ms = profileData.GetFrame(frameOffset).msFrame;
- FrameTimeGraph.Data dataPoint = new FrameTimeGraph.Data(ms, frameOffset);
- data.Add(dataPoint);
- }
- return data;
- }
- void Load()
- {
- m_Path = EditorUtility.OpenFilePanel("Load profile analyzer data file", "", "pdata");
- if (m_Path.Length != 0)
- {
- m_ActiveLoadingView = ActiveView.Single;
- Pre2019DisableRecording();
- BeginAsyncAction(ThreadActivity.Load);
- }
- GUIUtility.ExitGUI();
- }
- void UpdateMatchingProfileData(ProfileData data, ref string path, ProfileAnalysis analysis, string newPath)
- {
- // Update left/right data if we are effectively overwriting it.
- if (m_ProfileLeftView.path == newPath)
- {
- SetView(m_ProfileLeftView, data, newPath, m_LeftFrameTimeGraph);
- m_RequestCompare = true;
- m_FullCompareRequired = true;
- }
- if (m_ProfileRightView.path == newPath)
- {
- SetView(m_ProfileRightView, data, newPath, m_RightFrameTimeGraph);
- m_RequestCompare = true;
- m_FullCompareRequired = true;
- }
- // Update single view if needed
- if (m_ProfileSingleView.path == newPath)
- {
- SetView(m_ProfileSingleView, data, newPath, m_FrameTimeGraph);
- m_ProfileSingleView.analysis = analysis;
- }
- path = newPath;
- }
- void Save(ProfileDataView dataView, bool updateDataViewWithSelectedPath = false)
- {
- string newPath = EditorUtility.SaveFilePanel("Save profile analyzer data file", "", "capture.pdata", "pdata");
- if (newPath.Length != 0)
- {
- if (updateDataViewWithSelectedPath)
- {
- dataView.path = newPath;
- }
- if (ProfileData.Save(newPath, dataView.data))
- {
- UpdateMatchingProfileData(dataView.data, ref dataView.path, dataView.analysis, newPath);
- }
- }
- GUIUtility.ExitGUI();
- }
- int GetTotalCombinedMarkerCount(ProfileData left, ProfileData right)
- {
- if (left == null)
- return 0;
- if (right == null)
- return 0;
- List<string> leftMarkers = left.GetMarkerNames();
- if (leftMarkers == null)
- return 0;
- List<string> rightMarkers = right.GetMarkerNames();
- if (rightMarkers == null)
- return 0;
- HashSet<string> markerPairs = new HashSet<string>();
- for (int index = 0; index < leftMarkers.Count; index++)
- {
- string markerName = leftMarkers[index];
- markerPairs.Add(markerName);
- }
- for (int index = 0; index < rightMarkers.Count; index++)
- {
- string markerName = rightMarkers[index];
- if (!markerPairs.Contains(markerName))
- {
- markerPairs.Add(markerName);
- }
- }
- return markerPairs.Count;
- }
- List<MarkerPairing> GeneratePairings(ProfileAnalysis leftAnalysis, ProfileAnalysis rightAnalysis)
- {
- if (leftAnalysis == null)
- return null;
- if (rightAnalysis == null)
- return null;
- List<MarkerData> leftMarkers = leftAnalysis.GetMarkers();
- if (leftMarkers == null)
- return null;
- List<MarkerData> rightMarkers = rightAnalysis.GetMarkers();
- if (rightMarkers == null)
- return null;
- Dictionary<string, MarkerPairing> markerPairs = new Dictionary<string, MarkerPairing>();
- for (int index = 0; index < leftMarkers.Count; index++)
- {
- MarkerData marker = leftMarkers[index];
- MarkerPairing pair = new MarkerPairing
- {
- name = marker.name,
- leftIndex = index,
- rightIndex = -1
- };
- markerPairs[marker.name] = pair;
- }
- for (int index = 0; index < rightMarkers.Count; index++)
- {
- MarkerData marker = rightMarkers[index];
- if (markerPairs.ContainsKey(marker.name))
- {
- MarkerPairing pair = markerPairs[marker.name];
- pair.rightIndex = index;
- markerPairs[marker.name] = pair;
- }
- else
- {
- MarkerPairing pair = new MarkerPairing
- {
- name = marker.name,
- leftIndex = -1,
- rightIndex = index
- };
- markerPairs[marker.name] = pair;
- }
- }
- List<MarkerPairing> pairings = new List<MarkerPairing>();
- foreach (MarkerPairing pair in markerPairs.Values)
- pairings.Add(pair);
- return pairings;
- }
- void SetThreadPhaseCount(ThreadActivity activity)
- {
- // Will be refined by the analysis functions
- if (activity == ThreadActivity.Compare)
- {
- m_ThreadPhases = 8;
- }
- else
- {
- m_ThreadPhases = 2;
- }
- }
- void BeginAsyncAction(ThreadActivity activity)
- {
- if (IsAnalysisRunning())
- return;
- m_ThreadActivity = activity;
- m_ThreadProgress = 0;
- m_ThreadPhase = 0;
- SetThreadPhaseCount(activity);
- m_BackgroundThread = new Thread(BackgroundThread);
- m_BackgroundThread.Start();
- }
- void CreateComparisonTable()
- {
- UpdateThreadNames();
- // Set default sorting state
- int sortedColumn = (int)ComparisonTable.MyColumns.AbsDiff;
- bool sortAscending = false;
- // Query last sorting state
- if (m_ComparisonMulticolumnHeaderState != null)
- {
- if (m_ComparisonMulticolumnHeaderState.sortedColumnIndex >= 0)
- {
- sortedColumn = m_ComparisonMulticolumnHeaderState.sortedColumnIndex;
- if (sortedColumn >= 0 && sortedColumn < m_ComparisonMulticolumnHeaderState.columns.Length)
- sortAscending = m_ComparisonMulticolumnHeaderState.columns[sortedColumn].sortedAscending;
- }
- }
- if (m_ComparisonTreeViewState == null)
- m_ComparisonTreeViewState = new TreeViewState();
- m_ComparisonMulticolumnHeaderState = ComparisonTable.CreateDefaultMultiColumnHeaderState(m_CompareModeFilter);
- var multiColumnHeader = new MultiColumnHeader(m_ComparisonMulticolumnHeaderState);
- multiColumnHeader.SetSorting(sortedColumn, sortAscending);
- multiColumnHeader.ResizeToFit();
- m_ComparisonTable = new ComparisonTable(m_ComparisonTreeViewState, multiColumnHeader, m_ProfileLeftView, m_ProfileRightView, m_Pairings, this, m_2D, UIColor.left, UIColor.right);
- if (string.IsNullOrEmpty(m_SelectedMarker.name))
- SelectPairing(0);
- else
- SelectPairingByName(m_SelectedMarker.name);
- }
- void CalculatePairingbuckets(ProfileAnalysis left, ProfileAnalysis right, List<MarkerPairing> pairings)
- {
- var leftMarkers = left.GetMarkers();
- var rightMarkers = right.GetMarkers();
- foreach (var pairing in pairings)
- {
- float min = float.MaxValue;
- float max = 0.0f;
- MarkerData leftMarker = null;
- MarkerData rightMarker = null;
- if (pairing.leftIndex >= 0)
- {
- leftMarker = leftMarkers[pairing.leftIndex];
- max = Math.Max(max, leftMarker.msMax);
- min = Math.Min(min, leftMarker.msMin);
- }
- if (pairing.rightIndex >= 0)
- {
- rightMarker = rightMarkers[pairing.rightIndex];
- max = Math.Max(max, rightMarker.msMax);
- min = Math.Min(min, rightMarker.msMin);
- }
- int countMin = int.MaxValue;
- int countMax = 0;
- if (leftMarker != null)
- {
- countMax = Math.Max(countMax, leftMarker.countMax);
- countMin = Math.Min(countMin, leftMarker.countMin);
- }
- if (rightMarker != null)
- {
- countMax = Math.Max(countMax, rightMarker.countMax);
- countMin = Math.Min(countMin, rightMarker.countMin);
- }
- if (leftMarker != null)
- {
- leftMarker.ComputeBuckets(min, max);
- leftMarker.ComputeCountBuckets(countMin, countMax);
- }
- if (rightMarker != null)
- {
- rightMarker.ComputeBuckets(min, max);
- rightMarker.ComputeCountBuckets(countMin, countMax);
- }
- }
- }
- bool CompareSync()
- {
- if (!m_ProfileLeftView.IsDataValid())
- return false;
- if (!m_ProfileRightView.IsDataValid())
- return false;
- List<string> threadUINamesNew;
- List<string> threadNamesNew;
- Dictionary<string, string> threadNameToUINameNew;
- GetThreadNames(m_ProfileLeftView.data, m_ProfileRightView.data, out threadUINamesNew, out threadNamesNew, out threadNameToUINameNew);
- List<string> threadSelection = GetLimitedThreadSelection(threadNamesNew, m_ThreadSelection);
- System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
- stopwatch.Start();
- int updateDepthPhase = m_NewComparisonDataLoaded ? 2 : 0;
- int fullLeftPhase = (m_FullCompareRequired && m_ProfileLeftView.selectedIndices.Count != m_ProfileLeftView.data.GetFrameCount()) ? 1 : 0;
- int fullRightPhase = (m_FullCompareRequired && m_ProfileLeftView.selectedIndices.Count != m_ProfileLeftView.data.GetFrameCount()) ? 1 : 0;
- m_ThreadPhases = 2 /*scan left and right*/ + updateDepthPhase + 2 /*fullLeftPhase and fullRightPhase*/ + 2 /*analyze left and right*/;
- bool selfTimes = IsSelfTime();
- // First scan just the frames
- m_ThreadPhase = 0;
- var leftAnalysisNew = m_ProfileAnalyzer.Analyze(m_ProfileLeftView.data, m_ProfileLeftView.selectedIndices, null, m_DepthSliceUI.depthFilter1, selfTimes, m_ParentMarker);
- m_ThreadPhase++;
- var rightAnalysisNew = m_ProfileAnalyzer.Analyze(m_ProfileRightView.data, m_ProfileRightView.selectedIndices, null, m_DepthSliceUI.depthFilter2, selfTimes, m_ParentMarker);
- m_ThreadPhase++;
- if (leftAnalysisNew == null || rightAnalysisNew == null)
- {
- stopwatch.Stop();
- return false;
- }
- // Calculate the max frame time of the two scans
- float timeScaleMax = Math.Max(leftAnalysisNew.GetFrameSummary().msMax, rightAnalysisNew.GetFrameSummary().msMax);
- // Need to recalculate the depth difference when thread filters change
- // For now do it always if the depth is auto and not 'all'
- if (updateDepthPhase != 0)
- {
- var leftAnalysis = m_ProfileAnalyzer.Analyze(m_ProfileLeftView.data, m_ProfileLeftView.selectedIndices, threadSelection, ProfileAnalyzer.kDepthAll, selfTimes, m_ParentMarker, timeScaleMax);
- m_ThreadPhase++;
- var rightAnalysis = m_ProfileAnalyzer.Analyze(m_ProfileRightView.data, m_ProfileRightView.selectedIndices, threadSelection, ProfileAnalyzer.kDepthAll, selfTimes, m_ParentMarker, timeScaleMax);
- m_ThreadPhase++;
- var pairings = GeneratePairings(leftAnalysis, rightAnalysis);
- if (m_DepthSliceUI.UpdateDepthForCompareSync(leftAnalysis, rightAnalysis, pairings, m_ProfileLeftView, m_ProfileRightView))
- {
- // New depth diff calculated to we need to do the full analysis
- if (fullLeftPhase == 0)
- fullLeftPhase = 1;
- if (fullRightPhase == 0)
- fullRightPhase = 1;
- }
- }
- // Now process the markers and setup buckets using the overall max frame time
- List<int> selection = new List<int>();
- if (fullLeftPhase != 0)
- {
- selection.Clear();
- for (int frameOffset = 0; frameOffset < m_ProfileLeftView.data.GetFrameCount(); frameOffset++)
- {
- selection.Add(m_ProfileLeftView.data.OffsetToDisplayFrame(frameOffset));
- }
- // We don't pass timeScaleMax as that is only for the selected region.
- // Pass 0 to auto select full range
- m_ProfileLeftView.analysisFullNew = m_ProfileAnalyzer.Analyze(m_ProfileLeftView.data, selection, threadSelection, m_DepthSliceUI.depthFilter1, selfTimes, m_ParentMarker, 0);
- }
- m_ThreadPhase++;
- if (fullRightPhase != 0)
- {
- selection.Clear();
- for (int frameOffset = 0; frameOffset < m_ProfileRightView.data.GetFrameCount(); frameOffset++)
- {
- selection.Add(m_ProfileRightView.data.OffsetToDisplayFrame(frameOffset));
- }
- // We don't pass timeScaleMax as that is only for the selected region.
- // Pass 0 to auto select full range
- m_ProfileRightView.analysisFullNew = m_ProfileAnalyzer.Analyze(m_ProfileRightView.data, selection, threadSelection, m_DepthSliceUI.depthFilter2, selfTimes, m_ParentMarker, 0);
- }
- m_ThreadPhase++;
- m_ProfileLeftView.analysisNew = m_ProfileAnalyzer.Analyze(m_ProfileLeftView.data, m_ProfileLeftView.selectedIndices, threadSelection, m_DepthSliceUI.depthFilter1, selfTimes, m_ParentMarker, timeScaleMax);
- m_ThreadPhase++;
- m_ProfileRightView.analysisNew = m_ProfileAnalyzer.Analyze(m_ProfileRightView.data, m_ProfileRightView.selectedIndices, threadSelection, m_DepthSliceUI.depthFilter2, selfTimes, m_ParentMarker, timeScaleMax);
- m_ThreadPhase++;
- m_TotalCombinedMarkerCountNew = GetTotalCombinedMarkerCount(m_ProfileLeftView.data, m_ProfileRightView.data);
- m_PairingsNew = GeneratePairings(m_ProfileLeftView.analysisNew, m_ProfileRightView.analysisNew);
- CalculatePairingbuckets(m_ProfileLeftView.analysisNew, m_ProfileRightView.analysisNew, m_PairingsNew);
- stopwatch.Stop();
- m_LastCompareTimeMilliseconds = stopwatch.ElapsedMilliseconds;
- TimeSpan ts = stopwatch.Elapsed;
- if (ts.Minutes > 0)
- m_LastCompareTime = string.Format("Last compare time {0} mins {1} secs {2} ms ", ts.Minutes, ts.Seconds, ts.Milliseconds);
- else if (ts.Seconds > 0)
- m_LastCompareTime = string.Format("Last compare time {0} secs {1} ms ", ts.Seconds, ts.Milliseconds);
- else
- m_LastCompareTime = string.Format("Last compare time {0} ms ", ts.Milliseconds);
- return true;
- }
- void Compare()
- {
- if (m_Async)
- {
- //m_comparisonTable = null;
- //m_ProfileLeftView.analysis = null;
- //m_ProfileRightView.analysis = null;
- Pre2019DisableRecording();
- BeginAsyncAction(ThreadActivity.Compare);
- }
- else
- {
- CompareSync();
- UpdateAnalysisFromAsyncProcessing(m_ProfileLeftView, m_FullCompareRequired);
- UpdateAnalysisFromAsyncProcessing(m_ProfileRightView, m_FullCompareRequired);
- m_FullCompareRequired = false;
- }
- }
- List<MarkerPairing> GetPairings()
- {
- return m_Pairings;
- }
- int GetUnsavedIndex(string path)
- {
- if (path == null)
- return 0;
- Regex unsavedRegExp = new Regex(@"^Unsaved[\s*]([\d]*)", RegexOptions.IgnoreCase);
- Match match = unsavedRegExp.Match(path);
- if (match.Length <= 0)
- return 0;
- return Int32.Parse(match.Groups[1].Value);
- }
- void PullFromProfiler(int firstFrame, int lastFrame, ProfileDataView view, FrameTimeGraph frameTimeGraph)
- {
- m_ProgressBar.InitProgressBar("Pulling Frames from Profiler", "Please wait...", lastFrame - firstFrame);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- ProfileData newProfileData = m_ProfilerWindowInterface.PullFromProfiler(firstFrame, lastFrame);
- ProfileAnalyzerAnalytics.SendUIButtonEvent(ProfileAnalyzerAnalytics.UIButton.Pull, analytic);
- frameTimeGraph.Reset();
- frameTimeGraph.SetData(GetFrameTimeData(newProfileData));
- // Check if this is new data (rather than repulling the same data)
- if (!newProfileData.IsSame(view.data))
- {
- if (view == m_ProfileSingleView)
- m_NewDataLoaded = true;
- else
- m_NewComparisonDataLoaded = true;
- }
- // Update the path to use the same saved file name if this is the same data as another view
- if (newProfileData.IsSame(m_ProfileLeftView.data))
- {
- view.path = m_ProfileLeftView.path;
- }
- else if (newProfileData.IsSame(m_ProfileRightView.data))
- {
- view.path = m_ProfileRightView.path;
- }
- else if (newProfileData.IsSame(m_ProfileSingleView.data))
- {
- view.path = m_ProfileSingleView.path;
- }
- else
- {
- int lastIndex = 0;
- lastIndex = Math.Max(lastIndex, GetUnsavedIndex(m_ProfileSingleView.path));
- lastIndex = Math.Max(lastIndex, GetUnsavedIndex(m_ProfileLeftView.path));
- lastIndex = Math.Max(lastIndex, GetUnsavedIndex(m_ProfileRightView.path));
- view.path = string.Format("Unsaved {0}", lastIndex + 1);
- }
- if (view.data != null && !TmpInUse(view, view.data.FilePath))
- view.data.DeleteTmpFiles();
- view.data = newProfileData;
- view.SelectFullRange();
- // Remove pairing if both left/right point at the same data
- if (m_ProfileLeftView.path == m_ProfileRightView.path)
- {
- SetFrameTimeGraphPairing(false);
- }
- m_ProgressBar.ClearProgressBar();
- }
- void BackgroundThread()
- {
- try
- {
- switch (m_ThreadActivity)
- {
- case ThreadActivity.Analyze:
- AnalyzeSync();
- m_ThreadActivity = ThreadActivity.AnalyzeDone;
- break;
- case ThreadActivity.Compare:
- CompareSync();
- m_ThreadActivity = ThreadActivity.CompareDone;
- break;
- case ThreadActivity.AnalyzeDone:
- break;
- case ThreadActivity.CompareDone:
- break;
- case ThreadActivity.Load:
- m_ThreadActivity = ProfileData.Load(m_Path, out m_ProfilerData) ? ThreadActivity.LoadDone : ThreadActivity.None;
- break;
- case ThreadActivity.LoadDone:
- break;
- default:
- // m_threadActivity = ThreadActivity.None;
- break;
- }
- }
- catch (ThreadAbortException)
- {
- var activity = (m_ThreadActivity == ThreadActivity.Load) ? "Load" : "Analysis";
- Debug.LogFormat("{0} failed due to a domain reload. Please try again.", activity);
- }
- }
- void SelectFirstMarkerInTable()
- {
- // SelectMarkerByIndex(0) would only select the first one found, not the first in the sorted list
- if (m_ProfileTable == null)
- return;
- var rows = m_ProfileTable.GetRows();
- if (rows == null || rows.Count < 1)
- return;
- SelectMarkerByName(rows[0].displayName);
- }
- void CreateProfileTable()
- {
- if (m_ProfileTreeViewState == null)
- m_ProfileTreeViewState = new TreeViewState();
- // Set default sorting state
- int sortedColumn = (int)ProfileTable.MyColumns.Median;
- bool sortAscending = false;
- // Query last sorting state
- if (m_ProfileMulticolumnHeaderState != null)
- {
- if (m_ProfileMulticolumnHeaderState.sortedColumnIndex >= 0)
- {
- sortedColumn = m_ProfileMulticolumnHeaderState.sortedColumnIndex;
- if (sortedColumn >= 0 && sortedColumn < m_ProfileMulticolumnHeaderState.columns.Length)
- sortAscending = m_ProfileMulticolumnHeaderState.columns[sortedColumn].sortedAscending;
- }
- }
- m_ProfileMulticolumnHeaderState = ProfileTable.CreateDefaultMultiColumnHeaderState(m_SingleModeFilter);
- var multiColumnHeader = new MultiColumnHeader(m_ProfileMulticolumnHeaderState);
- multiColumnHeader.SetSorting(sortedColumn, sortAscending);
- multiColumnHeader.ResizeToFit();
- m_ProfileTable = new ProfileTable(m_ProfileTreeViewState, multiColumnHeader, m_ProfileSingleView, this, m_2D, UIColor.bar);
- if (string.IsNullOrEmpty(m_SelectedMarker.name))
- SelectFirstMarkerInTable();
- else
- SelectMarkerByName(m_SelectedMarker.name);
- UpdateThreadNames();
- }
- void AnalyzeSync()
- {
- if (!m_ProfileSingleView.IsDataValid())
- return;
- System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
- stopwatch.Start();
- List<string> threadUINamesNew;
- List<string> threadNamesNew;
- Dictionary<string, string> threadNameToUINameNew;
- GetThreadNames(m_ProfileSingleView.data, out threadUINamesNew, out threadNamesNew, out threadNameToUINameNew);
- List<string> threadSelection = GetLimitedThreadSelection(threadNamesNew, m_ThreadSelection);
- int fullPhase = (m_FullAnalysisRequired && (m_ProfileSingleView.selectedIndices.Count != m_ProfileSingleView.data.GetFrameCount())) ? 1 : 0;
- m_ThreadPhases = 1 + fullPhase;
- bool selfTimes = IsSelfTime();
- m_ThreadPhase = 0;
- if (fullPhase == 1)
- {
- List<int> selection = new List<int>();
- for (int frameOffset = 0; frameOffset < m_ProfileSingleView.data.GetFrameCount(); frameOffset++)
- {
- selection.Add(m_ProfileSingleView.data.OffsetToDisplayFrame(frameOffset));
- }
- m_ProfileSingleView.analysisFullNew = m_ProfileAnalyzer.Analyze(m_ProfileSingleView.data, selection, threadSelection, m_DepthSliceUI.depthFilter, selfTimes, m_ParentMarker);
- m_ThreadPhase++;
- }
- m_ProfileSingleView.analysisNew = m_ProfileAnalyzer.Analyze(m_ProfileSingleView.data, m_ProfileSingleView.selectedIndices, threadSelection, m_DepthSliceUI.depthFilter, selfTimes, m_ParentMarker);
- m_ThreadPhase++;
- stopwatch.Stop();
- m_LastAnalysisTimeMilliseconds = stopwatch.ElapsedMilliseconds;
- TimeSpan ts = stopwatch.Elapsed;
- if (ts.Minutes > 0)
- m_LastAnalysisTime = string.Format("Last analysis time {0} mins {1} secs {2} ms ", ts.Minutes, ts.Seconds, ts.Milliseconds);
- else if (ts.Seconds > 0)
- m_LastAnalysisTime = string.Format("Last analysis time {0} secs {1} ms ", ts.Seconds, ts.Milliseconds);
- else
- m_LastAnalysisTime = string.Format("Last analysis time {0} ms ", ts.Milliseconds);
- }
- void Analyze()
- {
- if (m_EnableAnalysisProfiling)
- {
- m_AnalyzeInUpdatePhase = 1;
- return;
- }
- if (m_Async)
- {
- //m_profileTable = null;
- //m_ProfileSingleView.analysis = null;
- Pre2019DisableRecording();
- BeginAsyncAction(ThreadActivity.Analyze);
- }
- else
- {
- AnalyzeSync();
- UpdateAnalysisFromAsyncProcessing(m_ProfileSingleView, m_FullAnalysisRequired);
- m_FullAnalysisRequired = false;
- }
- }
- void GetThreadNames(ProfileData profleData, out List<string> threadUINames, out List<string> threadFilters, out Dictionary<string, string> threadNameToUIName)
- {
- GetThreadNames(profleData, null, out threadUINames, out threadFilters, out threadNameToUIName);
- }
- public string GetUIThreadName(string threadNameWithIndex)
- {
- string threadName = "";
- m_ThreadNameToUIName.TryGetValue(threadNameWithIndex, out threadName);
- return threadName;
- }
- string GetFriendlyThreadName(string threadNameWithIndex, bool single)
- {
- if (string.IsNullOrEmpty(threadNameWithIndex))
- return "";
- var info = threadNameWithIndex.Split(':');
- int threadGroupIndex = int.Parse(info[0]);
- var threadName = info[1].Trim();
- if (single) // Single instance of this thread name
- {
- return threadName;
- }
- else
- {
- // The original format was "Worker 0"
- // The internal formatting is 1:Worker (1+original value).
- // Hence the -1 here
- return string.Format("{0} {1}", threadName, threadGroupIndex - 1);
- }
- }
- internal int CompareUINames(string a, string b)
- {
- var aSpaceIndex = a.LastIndexOf(' ');
- var bSpaceIndex = b.LastIndexOf(' ');
- if (aSpaceIndex >= 0 && bSpaceIndex >= 0)
- {
- var aThreadName = a.Substring(0, aSpaceIndex);
- var bThreadName = b.Substring(0, bSpaceIndex);
- if (aThreadName == bThreadName)
- {
- var aThreadIndex = a.Substring(aSpaceIndex + 1);
- var bThreadIndex = b.Substring(bSpaceIndex + 1);
- if (aThreadIndex == "All" && bThreadIndex != "All")
- return -1;
- if (aThreadIndex != "All" && bThreadIndex == "All")
- return 1;
- int aGroupIndex;
- if (int.TryParse(aThreadIndex, out aGroupIndex))
- {
- int bGroupIndex;
- if (int.TryParse(bThreadIndex, out bGroupIndex))
- {
- return aGroupIndex.CompareTo(bGroupIndex);
- }
- }
- }
- }
- return a.CompareTo(b);
- }
- void GetThreadNames(ProfileData leftData, ProfileData rightData, out List<string> threadUINames, out List<string> threadFilters, out Dictionary<string, string> threadNameToUIName)
- {
- List<string> threadNames = (leftData != null) ? new List<string>(leftData.GetThreadNames()) : new List<string>();
- if (rightData != null)
- {
- foreach (var threadNameWithIndex in rightData.GetThreadNames())
- {
- if (!threadNames.Contains(threadNameWithIndex))
- {
- // TODO: Insert after last thread with same name (or at end)
- threadNames.Add(threadNameWithIndex);
- }
- }
- }
- Dictionary<string, string> threadNamesDict = new Dictionary<string, string>();
- for (int index = 0; index < threadNames.Count; index++)
- {
- var threadNameWithIndex = threadNames[index];
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.index == 1)
- {
- if (threadNames.Contains(string.Format("2:{0}", threadIdentifier.name)))
- {
- var threadGroupIdentifier = new ThreadIdentifier(threadIdentifier);
- threadGroupIdentifier.SetAll();
- // First thread name of a group with the same name
- // Add an 'all' selection
- threadNamesDict[string.Format("{0} : All", threadIdentifier.name)] = threadGroupIdentifier.threadNameWithIndex;
- // And add the first item too
- threadNamesDict[GetFriendlyThreadName(threadNameWithIndex, false)] = threadNameWithIndex;
- }
- else
- {
- // Single instance of this thread name
- threadNamesDict[GetFriendlyThreadName(threadNameWithIndex, true)] = threadNameWithIndex;
- }
- }
- else
- {
- threadNamesDict[GetFriendlyThreadName(threadNameWithIndex, false)] = threadNameWithIndex;
- }
- }
- List<string> uiNames = new List<string>();
- foreach (string uiName in threadNamesDict.Keys)
- uiNames.Add(uiName);
- uiNames.Sort(CompareUINames);
- var allThreadIdentifier = new ThreadIdentifier();
- allThreadIdentifier.SetName("All");
- allThreadIdentifier.SetAll();
- threadUINames = new List<string>();
- threadFilters = new List<string>();
- threadNameToUIName = new Dictionary<string, string>();
- threadUINames.Add(allThreadIdentifier.name);
- threadFilters.Add(allThreadIdentifier.threadNameWithIndex);
- threadNameToUIName[allThreadIdentifier.name] = allThreadIdentifier.threadNameWithIndex;
- foreach (string uiName in uiNames)
- {
- // Strip off the group name
- // Note we don't do this in GetFriendlyThreadName else we would collapse the same named threads (in different groups) in the dict
- string groupName;
- string threadName = ProfileData.GetThreadNameWithoutGroup(uiName, out groupName);
- string threadFilter = threadNamesDict[uiName];
- threadUINames.Add(threadName);
- threadFilters.Add(threadFilter);
- threadNameToUIName[threadFilter] = threadName;
- }
- }
- void UpdateThreadGroupSelection(List<string> threadNames, ThreadSelection threadSelection)
- {
- // Make sure all members of active groups are present
- foreach (string threadGroupNameWithIndex in threadSelection.groups)
- {
- var threadGroupIdentifier = new ThreadIdentifier(threadGroupNameWithIndex);
- if (threadGroupIdentifier.name == "All" && threadGroupIdentifier.index == ThreadIdentifier.kAll)
- {
- foreach (string threadNameWithIndex in threadNames)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.index != ThreadIdentifier.kAll)
- {
- if (!threadSelection.selection.Contains(threadNameWithIndex))
- threadSelection.selection.Add(threadNameWithIndex);
- }
- }
- }
- else
- {
- foreach (string threadNameWithIndex in threadNames)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.name == threadGroupIdentifier.name &&
- threadIdentifier.index != ThreadIdentifier.kAll)
- {
- if (!threadSelection.selection.Contains(threadNameWithIndex))
- threadSelection.selection.Add(threadNameWithIndex);
- }
- }
- }
- }
- }
- List<string> GetLimitedThreadSelection(List<string> threadNames, ThreadSelection threadSelection)
- {
- List<string> limitedThreadSelection = new List<string>();
- if (threadSelection.selection == null)
- return limitedThreadSelection;
- foreach (string threadNameWithIndex in threadSelection.selection)
- {
- if (threadNames.Contains(threadNameWithIndex))
- limitedThreadSelection.Add(threadNameWithIndex);
- }
- // Make sure all members of active groups are present
- foreach (string threadGroupNameWithIndex in threadSelection.groups)
- {
- var threadGroupIdentifier = new ThreadIdentifier(threadGroupNameWithIndex);
- if (threadGroupIdentifier.name == "All" && threadGroupIdentifier.index == ThreadIdentifier.kAll)
- {
- foreach (string threadNameWithIndex in threadNames)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.index != ThreadIdentifier.kAll)
- {
- if (!limitedThreadSelection.Contains(threadNameWithIndex))
- limitedThreadSelection.Add(threadNameWithIndex);
- }
- }
- }
- else
- {
- foreach (string threadNameWithIndex in threadNames)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.name == threadGroupIdentifier.name &&
- threadIdentifier.index != ThreadIdentifier.kAll)
- {
- if (!limitedThreadSelection.Contains(threadNameWithIndex))
- limitedThreadSelection.Add(threadNameWithIndex);
- }
- }
- }
- }
- return limitedThreadSelection;
- }
- int ClampToRange(int value, int min, int max)
- {
- if (value < min)
- value = min;
- if (value > max)
- value = max;
- return value;
- }
- void GraphActive(bool active)
- {
- RequestRepaint();
- }
- void SetRange(List<int> selectedOffsets, int clickCount, FrameTimeGraph.State inputStatus)
- {
- if (inputStatus == FrameTimeGraph.State.Dragging)
- return;
- if (clickCount == 2)
- {
- if (selectedOffsets.Count > 0 && m_ProfileSingleView.inSyncWithProfilerData)
- JumpToFrame(m_ProfileSingleView.data.OffsetToDisplayFrame(selectedOffsets[0]), m_ProfileSingleView.data, false);
- }
- else
- {
- m_ProfileSingleView.selectedIndices.Clear();
- foreach (int offset in selectedOffsets)
- {
- m_ProfileSingleView.selectedIndices.Add(m_ProfileSingleView.data.OffsetToDisplayFrame(offset));
- }
- // Keep indices sorted
- m_ProfileSingleView.selectedIndices.Sort();
- m_RequestAnalysis = true;
- }
- }
- internal void ClearSelection()
- {
- if (m_ActiveTab == ActiveTab.Summary)
- {
- m_ProfileSingleView.ClearSelection();
- m_RequestAnalysis = true;
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- m_ProfileLeftView.ClearSelection();
- m_ProfileRightView.ClearSelection();
- m_RequestCompare = true;
- }
- }
- internal void SelectAllFrames()
- {
- if (m_ActiveTab == ActiveTab.Summary)
- {
- m_ProfileSingleView.SelectFullRange();
- m_RequestAnalysis = true;
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- m_ProfileLeftView.SelectFullRange();
- m_ProfileRightView.SelectFullRange();
- m_RequestCompare = true;
- }
- }
- internal void SelectFramesContainingMarker(string markerName, bool inSelection)
- {
- if (m_ActiveTab == ActiveTab.Summary)
- {
- if (m_ProfileSingleView.SelectAllFramesContainingMarker(markerName, inSelection))
- {
- m_RequestAnalysis = true;
- }
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- if (m_ProfileLeftView.SelectAllFramesContainingMarker(markerName, inSelection))
- {
- m_RequestCompare = true;
- }
- if (m_ProfileRightView.SelectAllFramesContainingMarker(markerName, inSelection))
- {
- m_RequestCompare = true;
- }
- }
- }
- static List<string> GetNameFilters(string nameFilter)
- {
- List<string> nameFilters = new List<string>();
- if (string.IsNullOrEmpty(nameFilter))
- return nameFilters;
- // Get all quoted strings, without the quotes
- MatchCollection matches = quotedStringWithoutQuotes.Matches(nameFilter);
- foreach (Match match in matches)
- {
- var theData = match.Groups[1].Value;
- nameFilters.Add(theData);
- }
- // Get a new string with the quoted strings removed
- string remaining = quotedString.Replace(nameFilter, "");
- // Get all the remaining strings (that are space separated)
- matches = stringWithoutWhiteSpace.Matches(remaining);
- foreach (Match match in matches)
- {
- string theData = match.Groups[1].Value;
- nameFilters.Add(theData);
- }
- return nameFilters;
- }
- internal List<string> GetNameFilters()
- {
- return GetNameFilters(m_NameFilter);
- }
- internal List<string> GetNameExcludes()
- {
- return GetNameFilters(m_NameExclude);
- }
- internal bool NameInFilterList(string name, List<string> nameFilters)
- {
- switch (m_NameFilterOperation)
- {
- default:
- //case NameFilterOperation.All:
- return NameInAllFilterList(name, nameFilters);
- case NameFilterOperation.Any:
- return NameInAnyFilterList(name, nameFilters);
- }
- }
- internal bool NameInExcludeList(string name, List<string> nameFilters)
- {
- switch (m_NameExcludeOperation)
- {
- default:
- //case NameFilterOperation.All:
- return NameInAllFilterList(name, nameFilters);
- case NameFilterOperation.Any:
- return NameInAnyFilterList(name, nameFilters);
- }
- }
- internal bool NameInAllFilterList(string name, List<string> nameFilters)
- {
- foreach (string subString in nameFilters)
- {
- // As soon as name doesn't match one in the list then return false
- if (name.IndexOf(subString, StringComparison.OrdinalIgnoreCase) < 0)
- return false;
- }
- // Name is matching all the filters in the list
- return true;
- }
- bool NameInAnyFilterList(string name, List<string> nameFilters)
- {
- foreach (string subString in nameFilters)
- {
- // As soon as names matches one in the list then return true
- if (name.IndexOf(subString, StringComparison.OrdinalIgnoreCase) >= 0)
- return true;
- }
- return false;
- }
- static string FilterWithQuotes(string markerName)
- {
- return markerName.Contains(" ") ? string.Format("\"{0}\"", markerName) : markerName;
- }
- static void AddFilter(ref string filter, string quotedMarkerName)
- {
- if (string.IsNullOrEmpty(filter))
- filter = quotedMarkerName;
- else
- filter = string.Format("{0} {1}", filter, quotedMarkerName);
- }
- static bool AddFilter(List<string> nameFilters, ref string filter, string markerName)
- {
- bool justAdded = false;
- string quotedMarkerName = FilterWithQuotes(markerName);
- if (!nameFilters.Contains(quotedMarkerName))
- {
- AddFilter(ref filter, quotedMarkerName);
- justAdded = true;
- }
- return justAdded;
- }
- internal void AddToIncludeFilter(string markerName)
- {
- if (AddFilter(GetNameFilters(), ref m_NameFilter, markerName))
- UpdateMarkerTable();
- // Remove from exclude list if in the include list
- RemoveFromExcludeFilter(markerName);
- }
- internal void AddToExcludeFilter(string markerName)
- {
- if (AddFilter(GetNameExcludes(), ref m_NameExclude, markerName))
- UpdateMarkerTable();
- // Remove from include list if in the include list
- RemoveFromIncludeFilter(markerName);
- }
- internal void RemoveFromFilter(string markerName, List<string> nameFilters, ref string newFilters)
- {
- if (nameFilters.Count == 0)
- return;
- string nameFilterString = "";
- bool updated = false;
- foreach (string filter in nameFilters)
- {
- if (string.Compare(filter, markerName, StringComparison.CurrentCultureIgnoreCase) != 0)
- AddFilter(ref nameFilterString, FilterWithQuotes(filter));
- else
- updated = true;
- }
- if (updated)
- {
- newFilters = nameFilterString;
- UpdateMarkerTable();
- }
- }
- internal void RemoveFromIncludeFilter(string markerName)
- {
- RemoveFromFilter(markerName, GetNameFilters(), ref m_NameFilter);
- }
- internal void RemoveFromExcludeFilter(string markerName)
- {
- RemoveFromFilter(markerName, GetNameExcludes(), ref m_NameExclude);
- }
- internal void SetAsParentMarkerFilter(string markerName)
- {
- if (markerName != m_ParentMarker)
- {
- m_ParentMarker = markerName;
- UpdateActiveTab(true);
- }
- }
- float GetFilenameWidth(string path)
- {
- if (path == null)
- return 0f;
- string filename = System.IO.Path.GetFileName(path);
- GUIContent content = new GUIContent(filename, path);
- Vector2 size = GUI.skin.label.CalcSize(content);
- return size.x;
- }
- void ShowFilename(string path)
- {
- if (path != null)
- {
- string filename = System.IO.Path.GetFileNameWithoutExtension(path);
- GUIContent content = new GUIContent(filename, path);
- Vector2 size = GUI.skin.label.CalcSize(content);
- float width = Math.Min(size.x, 200f);
- EditorGUILayout.LabelField(content, GUILayout.MaxWidth(width));
- }
- }
- void DrawLoadSave()
- {
- EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300), GUILayout.ExpandWidth(false));
- GUIStyle buttonStyle = GUI.skin.button;
- bool lastEnabled = GUI.enabled;
- bool isAnalysisRunning = IsAnalysisRunning();
- GUI.enabled = !isAnalysisRunning;
- if (GUILayout.Button("Load", buttonStyle, GUILayout.ExpandWidth(false), GUILayout.Width(50)))
- Load();
- GUI.enabled = !isAnalysisRunning && (m_ProfileSingleView.IsDataValid());
- if (GUILayout.Button("Save", buttonStyle, GUILayout.ExpandWidth(false), GUILayout.Width(50)))
- Save(m_ProfileSingleView);
- GUI.enabled = lastEnabled;
- ShowFilename(m_ProfileSingleView.path);
- EditorGUILayout.EndHorizontal();
- }
- void ShowSelectedMarker()
- {
- bool valid = true;
- if (m_ActiveTab == ActiveTab.Summary)
- {
- if (IsAnalysisValid())
- {
- valid = false;
- List<MarkerData> markers = m_ProfileSingleView.analysis.GetMarkers();
- if (markers != null)
- {
- int markerAt = m_SelectedMarker.id;
- if (markerAt >= 0 && markerAt < markers.Count)
- {
- valid = true;
- }
- }
- }
- }
- else if (m_ActiveTab == ActiveTab.Compare)
- {
- if (IsAnalysisValid())
- {
- valid = false;
- List<MarkerData> leftMarkers = m_ProfileLeftView.analysis.GetMarkers();
- List<MarkerData> rightMarkers = m_ProfileRightView.analysis.GetMarkers();
- int pairingAt = m_SelectedPairing;
- if (leftMarkers != null && rightMarkers != null && m_Pairings != null)
- {
- if (pairingAt >= 0 && pairingAt < m_Pairings.Count)
- {
- valid = true;
- }
- }
- }
- }
- if (valid)
- {
- DrawSelectedText(m_SelectedMarker.name);
- }
- else
- {
- var markerInThread = m_SelectedMarker.id == -1 && !string.IsNullOrEmpty(m_SelectedMarker.threadName);
- var threadText = markerInThread ?
- string.Format(" (Selected in: {0}{1}{2})",
- m_SelectedMarker.threadGroupName,
- string.IsNullOrEmpty(m_SelectedMarker.threadGroupName) ? "" : ".",
- m_SelectedMarker.threadName) :
- null;
- string text = string.Format("{0}{1} not in selection", m_SelectedMarker.name, threadText);
- GUIContent content = new GUIContent(text, text);
- Vector2 size = GUI.skin.label.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(size.x), GUILayout.Height(size.y));
- if (Event.current.type == EventType.Repaint)
- {
- GUI.Label(rect, content);
- }
- }
- }
- internal bool AllSelected()
- {
- if (m_ActiveTab == ActiveTab.Summary)
- {
- if (m_ProfileSingleView.AllSelected())
- return true;
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- if (m_ProfileLeftView.AllSelected() && m_ProfileRightView.AllSelected())
- return true;
- }
- return false;
- }
- internal bool HasSelection()
- {
- if (m_ActiveTab == ActiveTab.Summary)
- {
- if (m_ProfileSingleView.HasSelection())
- return true;
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- if (m_ProfileLeftView.HasSelection())
- return true;
- if (m_ProfileRightView.HasSelection())
- return true;
- }
- return false;
- }
- internal int GetRemappedUIFrameIndex(int frameIndex, ProfileDataView context)
- {
- if (context.inSyncWithProfilerData)
- return RemapFrameIndex(frameIndex, context.data.FrameIndexOffset);
- else
- return k_ProfileDataDefaultDisplayOffset + context.data.DisplayFrameToOffset(frameIndex);
- }
- int GetRemappedUIFirstFrameOffset(ProfileDataView context)
- {
- if (context.inSyncWithProfilerData)
- return RemapFrameIndex(context.data.OffsetToDisplayFrame(0), context.data.FrameIndexOffset);
- else
- return context.data.OffsetToDisplayFrame(0);
- }
- int GetRemappedUIFirstFrameDisplayOffset(ProfileDataView context)
- {
- if (context.inSyncWithProfilerData)
- return RemapFrameIndex(context.data.OffsetToDisplayFrame(0), context.data.FrameIndexOffset);
- else
- return k_ProfileDataDefaultDisplayOffset;
- }
- static readonly ProfilerMarkerAbstracted m_DrawFrameTimeGraphProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawFrameTimeGraph");
- void DrawFrameTimeGraph(float height)
- {
- using (m_DrawFrameTimeGraphProfilerMarker.Auto())
- {
- GUI.SetNextControlName("FrameTimeGraph");
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Height(height));
- if (m_ProfileSingleView.IsDataValid())
- {
- if (!m_FrameTimeGraph.HasData())
- m_FrameTimeGraph.SetData(GetFrameTimeData(m_ProfileSingleView.data));
- if (!m_ProfileSingleView.HasValidSelection())
- m_ProfileSingleView.SelectFullRange();
- List<int> selectedOffsets = new List<int>();
- foreach (int index in m_ProfileSingleView.selectedIndices)
- {
- selectedOffsets.Add(m_ProfileSingleView.data.DisplayFrameToOffset(index));
- }
- float yRange = m_FrameTimeGraph.GetDataRange();
- int offsetToDisplayMapping = GetRemappedUIFirstFrameDisplayOffset(m_ProfileSingleView);
- int offsetToIndexMapping = GetRemappedUIFirstFrameOffset(m_ProfileSingleView);
- bool enabled = !IsAnalysisRunning();
- m_FrameTimeGraph.SetEnabled(enabled);
- m_FrameTimeGraph.Draw(rect, m_ProfileSingleView.analysis, selectedOffsets, yRange, offsetToDisplayMapping, offsetToIndexMapping,
- m_SelectedMarker.name, 0, m_ProfileSingleView.analysisFull);
- EditorGUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
- ShowSelectedMarker();
- EditorGUILayout.EndHorizontal();
- }
- else
- {
- GUI.Label(rect, Styles.dataMissing, m_StyleUpperLeft);
- }
- }
- }
- void DrawParentFilter()
- {
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField(Styles.parentMarker, GUILayout.Width(100));
- if (!string.IsNullOrEmpty(m_ParentMarker))
- {
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- GUI.enabled = enabled;
- if (GUILayout.Button("Clear", EditorStyles.miniButton, GUILayout.MaxWidth(LayoutSize.FilterOptionsEnumWidth)))
- {
- SetAsParentMarkerFilter("");
- }
- GUI.enabled = lastEnabled;
- DrawSelectedText(m_ParentMarker);
- }
- else
- {
- EditorGUILayout.LabelField(Styles.selectParentMarker);
- }
- EditorGUILayout.EndHorizontal();
- }
- internal void SetThreadSelection(ThreadSelection threadSelection)
- {
- m_ThreadSelectionNew = new ThreadSelection(threadSelection);
- UpdateActiveTab(true);
- }
- string CalculateSelectedThreadsSummary()
- {
- if (m_ThreadSelection.selection == null || m_ThreadSelection.selection.Count == 0)
- return "None";
- // Count all threads in a group
- var threadDict = new Dictionary<string, int>();
- var threadSelectionDict = new Dictionary<string, int>();
- foreach (var threadNameWithIndex in m_ThreadNames)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadIdentifier.index == ThreadIdentifier.kAll)
- continue;
- int count;
- if (threadDict.TryGetValue(threadIdentifier.name, out count))
- threadDict[threadIdentifier.name] = count + 1;
- else
- threadDict[threadIdentifier.name] = 1;
- threadSelectionDict[threadIdentifier.name] = 0;
- }
- // Count all the threads we have 'selected' in a group
- foreach (var threadNameWithIndex in m_ThreadSelection.selection)
- {
- var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
- if (threadDict.ContainsKey(threadIdentifier.name) &&
- threadSelectionDict.ContainsKey(threadIdentifier.name) &&
- threadIdentifier.index <= threadDict[threadIdentifier.name])
- {
- // Selected thread valid and in the thread list
- // and also within the range of valid threads for this data set
- threadSelectionDict[threadIdentifier.name]++;
- }
- }
- // Count all thread groups where we have 'selected all the threads'
- int threadsSelected = 0;
- foreach (var threadName in threadDict.Keys)
- {
- if (threadSelectionDict[threadName] != threadDict[threadName])
- continue;
- threadsSelected++;
- }
- // If we've just added all the thread names we have everything selected
- // Note we don't compare against the m_ThreadNames directly as this contains the 'all' versions
- if (threadsSelected == threadDict.Keys.Count)
- return "All";
- // Add all the individual threads were we haven't already added the group
- List<string> threads = new List<string>();
- foreach (var threadName in threadSelectionDict.Keys)
- {
- int selectionCount = threadSelectionDict[threadName];
- if (selectionCount <= 0)
- continue;
- int threadCount = threadDict[threadName];
- if (threadCount == 1)
- threads.Add(threadName);
- else if (selectionCount != threadCount)
- threads.Add(string.Format("{0} ({1} of {2})", threadName, selectionCount, threadCount));
- else
- threads.Add(string.Format("{0} (All)", threadName));
- }
- // Maintain alphabetical order
- threads.Sort(CompareUINames);
- if (threads.Count == 0)
- return "None";
- string threadsSelectedText = string.Join(", ", threads.ToArray());
- return threadsSelectedText;
- }
- string GetSelectedThreadsSummary()
- {
- return m_ThreadSelectionSummary;
- }
- void DrawThreadFilter(ProfileData profileData)
- {
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField(Styles.threadFilter, GUILayout.Width(LayoutSize.FilterOptionsLeftLabelWidth));
- if (profileData != null)
- {
- if (m_ThreadNames.Count > 0)
- {
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning() && !ThreadSelectionWindow.IsOpen();
- GUI.enabled = enabled;
- if (GUILayout.Button(Styles.threadFilterSelect, GUILayout.Width(LayoutSize.FilterOptionsEnumWidth)))
- {
- Vector2 windowPosition = new Vector2(Event.current.mousePosition.x + LayoutSize.FilterOptionsEnumWidth, Event.current.mousePosition.y + GUI.skin.label.lineHeight);
- Vector2 screenPosition = GUIUtility.GUIToScreenPoint(windowPosition);
- ThreadSelectionWindow.Open(screenPosition.x, screenPosition.y, this, m_ThreadSelection, m_ThreadNames, m_ThreadUINames);
- EditorGUIUtility.ExitGUI();
- }
- GUI.enabled = lastEnabled;
- ShowSelectedThreads();
- GUILayout.FlexibleSpace();
- }
- }
- EditorGUILayout.EndHorizontal();
- }
- void DrawSelectedText(string text)
- {
- if (text == null)
- return;
- #if UNITY_2019_1_OR_NEWER
- GUIStyle treeViewSelectionStyle = "TV Selection";
- GUIStyle backgroundStyle = new GUIStyle(treeViewSelectionStyle);
- GUIStyle treeViewLineStyle = "TV Line";
- GUIStyle textStyle = new GUIStyle(treeViewLineStyle);
- #else
- GUIStyle textStyle = GUI.skin.label;
- #endif
- GUIContent content = new GUIContent(text, text);
- Vector2 size = textStyle.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(size.x), GUILayout.Height(size.y));
- if (Event.current.type == EventType.Repaint)
- {
- #if UNITY_2019_1_OR_NEWER
- backgroundStyle.Draw(rect, false, false, true, true);
- #endif
- GUI.Label(rect, content, textStyle);
- }
- }
- void ShowSelectedThreads()
- {
- string threadsSelected = GetSelectedThreadsSummary();
- DrawSelectedText(threadsSelected);
- }
- void DrawUnitFilter()
- {
- EditorGUILayout.BeginHorizontal(GUILayout.Width(LayoutSize.FilterOptionsRightLabelWidth + LayoutSize.FilterOptionsRightEnumWidth));
- EditorGUILayout.LabelField(Styles.unitFilter, m_StyleMiddleRight, GUILayout.Width(LayoutSize.FilterOptionsRightEnumWidth));
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- GUI.enabled = enabled;
- //Units units = (Units)EditorGUILayout.EnumPopup(m_DisplayUnits.Units, GUILayout.Width(LayoutSize.FilterOptionsRightEnumWidth));
- Units units = (Units)EditorGUILayout.Popup((int)m_DisplayUnits.Units, m_UnitNames, GUILayout.Width(LayoutSize.FilterOptionsRightEnumWidth));
- GUI.enabled = lastEnabled;
- if (units != m_DisplayUnits.Units)
- {
- SetUnits(units);
- m_FrameTimeGraph.SetUnits(m_DisplayUnits.Units);
- m_LeftFrameTimeGraph.SetUnits(m_DisplayUnits.Units);
- m_RightFrameTimeGraph.SetUnits(m_DisplayUnits.Units);
- UpdateMarkerTable();
- }
- EditorGUILayout.EndHorizontal();
- }
- bool IsSelfTime()
- {
- return (m_TimingOption == TimingOptions.TimingOption.Self) ? true : false;
- }
- void DrawTimingFilter()
- {
- EditorGUILayout.BeginHorizontal(GUILayout.Width(LayoutSize.FilterOptionsRightLabelWidth + LayoutSize.FilterOptionsRightEnumWidth));
- EditorGUILayout.LabelField(Styles.timingFilter, m_StyleMiddleRight, GUILayout.Width(LayoutSize.FilterOptionsRightLabelWidth));
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- GUI.enabled = enabled;
- var timingOption = (TimingOptions.TimingOption)EditorGUILayout.Popup((int)m_TimingOption, TimingOptions.TimingOptionNames, GUILayout.Width(LayoutSize.FilterOptionsRightEnumWidth));
- GUI.enabled = lastEnabled;
- if (timingOption != m_TimingOption)
- {
- m_TimingOption = timingOption;
- UpdateActiveTab(true, true);
- }
- EditorGUILayout.EndHorizontal();
- }
- internal string GetDisplayUnits()
- {
- return m_DisplayUnits.Postfix();
- }
- internal string ToDisplayUnits(float ms, bool showUnits = false, int limitToDigits = 5, bool showFullValueWhenBelowZero = false)
- {
- return m_DisplayUnits.ToString(ms, showUnits, limitToDigits, showFullValueWhenBelowZero);
- }
- internal string ToDisplayUnits(double ms, bool showUnits = false, int limitToDigits = 5, bool showFullValueWhenBelowZero = false)
- {
- return m_DisplayUnits.ToString((float)ms, showUnits, limitToDigits, showFullValueWhenBelowZero);
- }
- internal string ToTooltipDisplayUnits(float ms, bool showUnits = false, int frameIndex = -1)
- {
- return m_DisplayUnits.ToTooltipString(ms, showUnits, frameIndex);
- }
- internal GUIContent ToDisplayUnitsWithTooltips(float ms, bool showUnits = false, int frameIndex = -1)
- {
- return m_DisplayUnits.ToGUIContentWithTooltips(ms, showUnits, 5, frameIndex);
- }
- void SetUnits(Units units)
- {
- m_DisplayUnits = new DisplayUnits(units);
- }
- void UpdateActiveTab(bool fullAnalysisRequired = false, bool markOtherDirty = true)
- {
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- m_RequestAnalysis = true;
- m_FullAnalysisRequired = fullAnalysisRequired;
- break;
- case ActiveTab.Compare:
- m_RequestCompare = true;
- m_FullCompareRequired = fullAnalysisRequired;
- break;
- }
- if (markOtherDirty)
- m_OtherTabDirty = true;
- }
- void UpdateMarkerTable(bool markOtherDirty = true)
- {
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- if (m_ProfileTable != null)
- m_ProfileTable.Reload();
- break;
- case ActiveTab.Compare:
- if (m_ComparisonTable != null)
- m_ComparisonTable.Reload();
- break;
- }
- if (markOtherDirty)
- m_OtherTableDirty = true;
- }
- void DrawNameFilter()
- {
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.LabelField(Styles.nameFilter, GUILayout.Width(LayoutSize.FilterOptionsLeftLabelWidth));
- NameFilterOperation lastNameFilterOperation = m_NameFilterOperation;
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- GUI.enabled = enabled;
- m_NameFilterOperation = (NameFilterOperation)EditorGUILayout.Popup((int)m_NameFilterOperation, Styles.nameFilterOperation, GUILayout.MaxWidth(LayoutSize.FilterOptionsEnumWidth));
- GUI.enabled = lastEnabled;
- if (m_NameFilterOperation != lastNameFilterOperation)
- {
- UpdateMarkerTable();
- }
- string lastFilter = m_NameFilter;
- GUI.enabled = enabled;
- GUI.SetNextControlName("NameFilter");
- m_NameFilter = EditorGUILayout.TextField(m_NameFilter, GUILayout.MinWidth(200 - LayoutSize.FilterOptionsEnumWidth));
- GUI.enabled = lastEnabled;
- if (m_NameFilter != lastFilter)
- {
- UpdateMarkerTable();
- }
- EditorGUILayout.LabelField(Styles.nameExclude, GUILayout.Width(LayoutSize.FilterOptionsLeftLabelWidth));
- NameFilterOperation lastNameExcludeOperation = m_NameExcludeOperation;
- GUI.enabled = enabled;
- m_NameExcludeOperation = (NameFilterOperation)EditorGUILayout.Popup((int)m_NameExcludeOperation, Styles.nameFilterOperation, GUILayout.MaxWidth(LayoutSize.FilterOptionsEnumWidth));
- GUI.enabled = lastEnabled;
- if (m_NameExcludeOperation != lastNameExcludeOperation)
- {
- UpdateMarkerTable();
- }
- string lastExclude = m_NameExclude;
- GUI.enabled = enabled;
- GUI.SetNextControlName("ExcludeFilter");
- m_NameExclude = EditorGUILayout.TextField(m_NameExclude, GUILayout.MinWidth(200 - LayoutSize.FilterOptionsEnumWidth));
- GUI.enabled = lastEnabled;
- if (m_NameExclude != lastExclude)
- {
- UpdateMarkerTable();
- }
- EditorGUILayout.EndHorizontal();
- }
- internal void SetMode(MarkerColumnFilter.Mode newMode)
- {
- m_SingleModeFilter.mode = newMode;
- m_CompareModeFilter.mode = newMode;
- if (m_ProfileTable != null)
- m_ProfileTable.SetMode(m_SingleModeFilter);
- if (m_ComparisonTable != null)
- m_ComparisonTable.SetMode(m_CompareModeFilter);
- }
- internal void SetSingleModeColumns(int[] visibleColumns)
- {
- // If selecting the columns manually then override the currently stored selection with the current
- m_ProfileMulticolumnHeaderState.visibleColumns = visibleColumns;
- m_SingleModeFilter.mode = MarkerColumnFilter.Mode.Custom;
- m_SingleModeFilter.visibleColumns = visibleColumns;
- }
- internal void SetComparisonModeColumns(int[] visibleColumns)
- {
- // If selecting the columns manually then override the currently stored selection with the current
- m_ComparisonMulticolumnHeaderState.visibleColumns = visibleColumns;
- m_CompareModeFilter.mode = MarkerColumnFilter.Mode.Custom;
- m_CompareModeFilter.visibleColumns = visibleColumns;
- }
- void DrawMarkerColumnFilter()
- {
- EditorGUILayout.BeginHorizontal(GUILayout.Width(LayoutSize.FilterOptionsRightLabelWidth + LayoutSize.FilterOptionsRightEnumWidth));
- EditorGUILayout.LabelField(Styles.markerColumns, m_StyleMiddleRight, GUILayout.Width(LayoutSize.FilterOptionsRightLabelWidth));
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- GUI.enabled = enabled;
- var filterMode = m_ActiveTab == ActiveTab.Summary ? m_SingleModeFilter : m_CompareModeFilter;
- var oldMode = filterMode.mode;
- filterMode.mode = (MarkerColumnFilter.Mode)EditorGUILayout.IntPopup((int)filterMode.mode, MarkerColumnFilter.ModeNames, MarkerColumnFilter.ModeValues, GUILayout.Width(LayoutSize.FilterOptionsRightEnumWidth));
- if (filterMode.mode != oldMode)
- {
- if (m_ActiveTab == ActiveTab.Summary && m_ProfileTable != null)
- m_ProfileTable.SetMode(filterMode);
- else if (m_ActiveTab == ActiveTab.Compare && m_ComparisonTable != null)
- m_ComparisonTable.SetMode(filterMode);
- }
- GUI.enabled = lastEnabled;
- EditorGUILayout.EndHorizontal();
- }
- enum InDataSet
- {
- Left,
- Both,
- Right
- };
- int GetCombinedThreadCount(out int matchingCount, out int uniqueLeft, out int uniqueRight)
- {
- var threads = new Dictionary<string, InDataSet>();
- foreach (var threadName in m_ProfileLeftView.data.GetThreadNames())
- {
- threads[threadName] = InDataSet.Left;
- }
- foreach (var threadName in m_ProfileRightView.data.GetThreadNames())
- {
- if (threads.ContainsKey(threadName))
- threads[threadName] = InDataSet.Both;
- else
- threads[threadName] = InDataSet.Right;
- }
- matchingCount = 0;
- uniqueLeft = 0;
- uniqueRight = 0;
- int total = 0;
- foreach (var thread in threads)
- {
- switch (thread.Value)
- {
- case InDataSet.Left:
- uniqueLeft++;
- break;
- case InDataSet.Both:
- matchingCount++;
- break;
- case InDataSet.Right:
- uniqueRight++;
- break;
- }
- total++;
- }
- return total;
- }
- void DrawMarkerCount()
- {
- if (!IsAnalysisValid())
- return;
- if (m_ActiveTab == ActiveTab.Summary)
- {
- int markersCount = m_ProfileSingleView.analysis.GetFrameSummary().totalMarkers;
- int filteredMarkersCount = (m_ProfileTable != null) ? m_ProfileTable.GetRows().Count : 0;
- var content = new GUIContent(
- String.Format("{0} of {1} markers", filteredMarkersCount, markersCount),
- "Number of markers in the filtered set, compared to the total in the data set");
- Vector2 size = GUI.skin.label.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Width(size.x), GUILayout.Height(size.y));
- EditorGUI.LabelField(rect, content);
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- int markersCount = m_TotalCombinedMarkerCount;
- int filteredMarkersCount = (m_ComparisonTable != null) ? m_ComparisonTable.GetRows().Count : 0;
- var content = new GUIContent(
- String.Format("{0} of {1} markers", filteredMarkersCount, markersCount),
- "Number of markers in the filtered set, compared to total unique markers in the combined data sets");
- Vector2 size = GUI.skin.label.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Width(size.x), GUILayout.Height(size.y));
- EditorGUI.LabelField(rect, content);
- }
- }
- string GetThreadCountToolTipUnion(int allThreadsCount, int matchingCount)
- {
- return String.Format(
- "Total\n{0} Union : Combined over both data sets\n{1} Intersection : Matching in both data sets",
- allThreadsCount,
- matchingCount
- );
- }
- string GetThreadCountToolTipDifference(int allThreadsCount, int matchingCount, int uniqueLeft, int uniqueRight)
- {
- return String.Format(
- "Difference\n{0}\n{1} Unique to left\n{2} Unique to right",
- allThreadsCount - matchingCount,
- uniqueLeft,
- uniqueRight);
- }
- string GetThreadCountToolTip(int allThreadsCount, int matchingCount, int uniqueLeft, int uniqueRight)
- {
- return String.Format(
- "{0}\n\n{1}",
- GetThreadCountToolTipUnion(allThreadsCount, matchingCount),
- GetThreadCountToolTipDifference(allThreadsCount, matchingCount, uniqueLeft, uniqueRight)
- );
- }
- void DrawThreadCount()
- {
- if (!IsAnalysisValid())
- return;
- if (m_ActiveTab == ActiveTab.Summary)
- {
- int allThreadsCount = m_ProfileSingleView.data.GetThreadNames().Count;
- List<string> threadSelection = GetLimitedThreadSelection(m_ThreadNames, m_ThreadSelection);
- int selectedThreads = threadSelection.Count;
- var content = new GUIContent(
- String.Format("{0} of {1} threads", selectedThreads, allThreadsCount),
- "Number of threads in the filtered set, compared to the total in the data set");
- Vector2 size = GUI.skin.label.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Width(size.x), GUILayout.Height(size.y));
- EditorGUI.LabelField(rect, content);
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- int matchingCount, uniqueLeft, uniqueRight;
- int allThreadsCount = GetCombinedThreadCount(out matchingCount, out uniqueLeft, out uniqueRight);
- List<string> threadSelection = GetLimitedThreadSelection(m_ThreadNames, m_ThreadSelection);
- int selectedThreads = threadSelection.Count;
- string partialTooltip = GetThreadCountToolTip(allThreadsCount, matchingCount, uniqueLeft, uniqueRight);
- var content = new GUIContent(
- String.Format("{0} of {1} threads", selectedThreads, allThreadsCount),
- String.Format("Number of threads in the filtered set, compared to total unique threads in the combined data sets\n\n{0}", partialTooltip)
- );
- Vector2 size = GUI.skin.label.CalcSize(content);
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Width(size.x), GUILayout.Height(size.y));
- EditorGUI.LabelField(rect, content);
- }
- }
- static readonly ProfilerMarkerAbstracted m_DrawAnalysisOptionsProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawAnalysisOptions");
- void DrawAnalysisOptions()
- {
- using (m_DrawAnalysisOptionsProfilerMarker.Auto())
- {
- EditorGUILayout.BeginVertical(GUI.skin.box);
- bool lastShowFilters = m_ShowFilters;
- m_ShowFilters = BoldFoldout(m_ShowFilters, Styles.filters);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowFilters)
- {
- DrawNameFilter();
- EditorGUILayout.BeginHorizontal();
- DrawThreadFilter(m_ProfileSingleView.data);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- m_DepthSliceUI.DrawDepthFilter(IsAnalysisRunning(), m_ActiveTab == ActiveTab.Summary,
- m_ProfileSingleView, m_ProfileLeftView, m_ProfileRightView);
- DrawTimingFilter();
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- DrawParentFilter();
- DrawUnitFilter();
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- bool lastEnabled = GUI.enabled;
- GUI.enabled = !IsAnalysisRunning();
- if (GUILayout.Button(new GUIContent("Analyze", m_LastAnalysisTime), GUILayout.Width(100)))
- m_RequestAnalysis = true;
- GUI.enabled = lastEnabled;
- DrawMarkerCount();
- EditorGUILayout.LabelField(",", GUILayout.Width(10), GUILayout.ExpandWidth(false));
- DrawThreadCount();
- GUILayout.FlexibleSpace();
- DrawMarkerColumnFilter();
- EditorGUILayout.EndHorizontal();
- }
- if (m_ShowFilters != lastShowFilters)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Filters,
- analytic.GetDurationInSeconds(), m_ShowFilters);
- }
- EditorGUILayout.EndVertical();
- }
- }
- internal bool IsAnalysisRunning()
- {
- return m_ThreadActivity != ThreadActivity.None;
- }
- internal bool IsLoading()
- {
- return m_ThreadActivity == ThreadActivity.Load;
- }
- float GetProgress()
- {
- // We return the value from the update loop so the data doesn't change over the time onGui is called for layout and repaint
- // m_ThreadProgress ranges from 0 to 100.
- return m_ThreadProgress * 0.01f;
- }
- bool IsAnalysisValid(bool checkFrameCount = false)
- {
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- if (!m_ProfileSingleView.IsDataValid())
- return false;
- if (m_ProfileSingleView.analysis == null)
- return false;
- if (checkFrameCount)
- {
- if (m_ProfileSingleView.analysis.GetFrameSummary().frames.Count <= 0)
- return false;
- }
- break;
- case ActiveTab.Compare:
- if (!m_ProfileLeftView.IsDataValid())
- return false;
- if (!m_ProfileRightView.IsDataValid())
- return false;
- if (m_ProfileLeftView.analysis == null)
- return false;
- if (m_ProfileRightView.analysis == null)
- return false;
- if (checkFrameCount)
- {
- if (m_ProfileLeftView.analysis.GetFrameSummary().frames.Count <= 0)
- return false;
- if (m_ProfileRightView.analysis.GetFrameSummary().frames.Count <= 0)
- return false;
- }
- break;
- }
- //if (IsAnalysisRunning())
- // return false;
- return true;
- }
- void DrawProgress(Rect rect)
- {
- if (IsAnalysisRunning())
- {
- EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(140));
- float x = 0;
- float y = 0;
- float width = rect.width;
- float height = k_ProgressBarHeight;
- if (m_2D.DrawStart(width, height, Draw2D.Origin.TopLeft))
- {
- float barLength = width * GetProgress();
- m_2D.DrawFilledBox(x, y, barLength, height, UIColor.white);
- m_2D.DrawEnd();
- }
- EditorGUILayout.EndHorizontal();
- }
- else
- {
- EditorGUILayout.BeginVertical();
- GUILayout.Space(k_ProgressBarHeight);
- EditorGUILayout.EndVertical();
- }
- }
- void DrawPullButton(Color color, ProfileDataView view, FrameTimeGraph frameTimeGraph)
- {
- bool lastEnabled = GUI.enabled;
- GUI.enabled = !IsAnalysisRunning();
- GUIContent content;
- if (!IsProfilerWindowOpen())
- {
- content = Styles.pullOpen;
- GUI.enabled = false;
- }
- else if (m_ProfilerFirstFrameIndex == 0 && m_ProfilerLastFrameIndex == 0)
- {
- content = Styles.pullRange;
- GUI.enabled = false;
- }
- /*
- // Commented out so we can capture even if recording
- else if (m_ProfilerWindowInterface.IsRecording())
- {
- content = Styles.pullRecording;
- GUI.enabled = false;
- }
- */
- else
- {
- content = Styles.pull;
- }
- Color oldColor = GUI.backgroundColor;
- GUI.backgroundColor = color;
- bool pull = GUILayout.Button(content, GUILayout.Width(100));
- GUI.backgroundColor = oldColor;
- if (pull)
- {
- PullFromProfiler(m_ProfilerFirstFrameIndex, m_ProfilerLastFrameIndex, view, frameTimeGraph);
- UpdateActiveTab(true, false);
- }
- GUI.enabled = lastEnabled;
- }
- static readonly ProfilerMarkerAbstracted m_DrawFilesLoadedProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawFilesLoaded");
- void DrawFilesLoaded()
- {
- using (m_DrawFilesLoadedProfilerMarker.Auto())
- {
- var boxStyle = GUI.skin.box;
- var rect = EditorGUILayout.BeginVertical(boxStyle);
- if (m_ActiveTab == ActiveTab.Summary)
- {
- EditorGUILayout.BeginHorizontal(GUILayout.Height(100 + GUI.skin.label.lineHeight +
- (2 * (GUI.skin.label.margin.vertical +
- GUI.skin.label.padding.vertical))));
- float filenameWidth = GetFilenameWidth(m_ProfileSingleView.path);
- filenameWidth = Math.Min(filenameWidth, 200);
- EditorGUILayout.BeginVertical(GUILayout.MaxWidth(100 + filenameWidth),
- GUILayout.ExpandWidth(false));
- DrawPullButton(GUI.backgroundColor, m_ProfileSingleView, m_FrameTimeGraph);
- DrawLoadSave();
- EditorGUILayout.EndVertical();
- EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
- DrawFrameTimeGraph(100);
- EditorGUILayout.EndVertical();
- EditorGUILayout.EndHorizontal();
- }
- if (m_ActiveTab == ActiveTab.Compare)
- {
- DrawComparisonLoadSave();
- }
- rect.width -= boxStyle.margin.right;
- DrawProgress(rect);
- EditorGUILayout.EndVertical();
- }
- }
- void ShowHelp()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box);
- m_HelpScroll = EditorGUILayout.BeginScrollView(m_HelpScroll, GUILayout.ExpandHeight(true));
- #if UNITY_2019_3_OR_NEWER
- GUILayout.TextArea(Styles.helpText);
- #else
- GUIStyle helpStyle = new GUIStyle(EditorStyles.textField);
- helpStyle.wordWrap = true;
- EditorGUILayout.LabelField(Styles.helpText, helpStyle);
- #endif
- EditorGUILayout.EndScrollView();
- EditorGUILayout.EndVertical();
- }
- static readonly ProfilerMarkerAbstracted m_DrawAnalysisProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawAnalysis");
- static readonly ProfilerMarkerAbstracted m_TopNMarkersProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.TopNMarkers");
- static readonly ProfilerMarkerAbstracted m_DrawMarkerTableProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawMarkerTable");
- void DrawAnalysis()
- {
- using (m_DrawAnalysisProfilerMarker.Auto())
- {
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.BeginVertical();
- DrawFilesLoaded();
- if (m_ProfileSingleView.IsDataValid() && m_ProfileSingleView.data.GetFrameCount() > 0)
- {
- DrawAnalysisOptions();
- if (IsAnalysisValid())
- {
- EditorGUILayout.BeginVertical(GUI.skin.box);
- string title = string.Format("Top {0} markers on median frame", m_TopNBars);
- GUIContent markersTitle = new GUIContent(title, Styles.topMarkersTooltip);
- bool lastShowTopMarkers = m_ShowTopNMarkers;
- m_ShowTopNMarkers = BoldFoldout(m_ShowTopNMarkers, markersTitle);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowTopNMarkers)
- {
- using (m_TopNMarkersProfilerMarker.Auto())
- {
- m_TopMarkers.SetData(m_ProfileSingleView, m_DepthSliceUI.depthFilter, GetNameFilters(),
- GetNameExcludes(), m_TimingOption, m_ThreadSelection.selection.Count);
- EditorGUILayout.BeginVertical(GUILayout.Height(20));
- EditorGUILayout.BeginHorizontal();
- FrameSummary frameSummary = m_ProfileSingleView.analysis.GetFrameSummary();
- if (frameSummary.count > 0)
- DrawFrameIndexButton(frameSummary.medianFrameIndex, m_ProfileSingleView);
- else
- GUILayout.Label("", GUILayout.MinWidth(50));
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true),
- GUILayout.ExpandHeight(true));
- float range = m_TopMarkers.GetTopMarkerTimeRange();
- m_TopMarkers.Draw(rect, UIColor.bar, m_TopNBars, range, UIColor.barBackground,
- Color.black, Color.white, true, true);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.EndVertical();
- EditorGUILayout.BeginVertical(GUILayout.Height(20));
- GUILayout.Label(m_DepthSliceUI.GetUIInfo(false));
- EditorGUILayout.EndVertical();
- }
- }
- if (m_ShowTopNMarkers != lastShowTopMarkers)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.TopTen,
- analytic.GetDurationInSeconds(), m_ShowTopNMarkers);
- }
- EditorGUILayout.EndVertical();
- if (m_ProfileTable != null)
- {
- m_ShowMarkerTable = BoldFoldout(m_ShowMarkerTable, Styles.profileTable);
- if (m_ShowMarkerTable)
- {
- using (m_DrawMarkerTableProfilerMarker.Auto())
- {
- Rect r = EditorGUILayout.GetControlRect(GUILayout.ExpandHeight(true));
- float scrollBarWidth = GUI.skin.verticalScrollbar.fixedWidth +
- GUI.skin.verticalScrollbar.border.horizontal +
- GUI.skin.verticalScrollbar.margin.horizontal +
- GUI.skin.verticalScrollbar.padding.horizontal;
- scrollBarWidth += LayoutSize.ScrollBarPadding;
- //offset vertically to get correct clipping behaviour
- Rect clipRect = new Rect(r.x, m_ProfileTable.state.scrollPos.y,
- r.width - scrollBarWidth,
- r.height -
- (m_ProfileTable.multiColumnHeader.height + GUI.skin.box.padding.top) -
- (m_ProfileTable.ShowingHorizontalScroll
- ? (scrollBarWidth - LayoutSize.ScrollBarPadding)
- : 0));
- m_2D.SetClipRect(clipRect);
- m_ProfileTable.OnGUI(r);
- m_2D.ClearClipRect();
- }
- }
- }
- }
- }
- else
- {
- ShowHelp();
- }
- EditorGUILayout.EndVertical();
- EditorGUILayout.BeginVertical(GUILayout.Width(LayoutSize.WidthRHS));
- GUILayout.Space(4);
- DrawFrameSummary();
- DrawThreadSummary();
- DrawSelected();
- EditorGUILayout.EndVertical();
- EditorGUILayout.EndHorizontal();
- }
- }
- void SetRange(List<int> selectedOffsets, int clickCount, FrameTimeGraph.State inputStatus, ProfileDataView mainData, List<int> selectedIndices)
- {
- if (inputStatus == FrameTimeGraph.State.Dragging)
- return;
- var data = mainData.data;
- if (clickCount == 2)
- {
- if (mainData.inSyncWithProfilerData)
- {
- int index = data.OffsetToDisplayFrame(selectedOffsets[0]);
- JumpToFrame(index, mainData.data, false);
- }
- }
- else
- {
- selectedIndices.Clear();
- foreach (int offset in selectedOffsets)
- {
- selectedIndices.Add(data.OffsetToDisplayFrame(offset));
- }
- // Keep indices sorted
- selectedIndices.Sort();
- m_RequestCompare = true;
- }
- }
- void SetLeftRange(List<int> selectedOffsets, int clickCount, FrameTimeGraph.State inputStatus)
- {
- SetRange(selectedOffsets, clickCount, inputStatus, m_ProfileLeftView, m_ProfileLeftView.selectedIndices);
- }
- void SetRightRange(List<int> selectedOffsets, int clickCount, FrameTimeGraph.State inputStatus)
- {
- SetRange(selectedOffsets, clickCount, inputStatus, m_ProfileRightView, m_ProfileRightView.selectedIndices);
- }
- void DrawComparisonLoadSaveButton(Color color, ProfileDataView view, FrameTimeGraph frameTimeGraph, ActiveView activeView)
- {
- bool lastEnabled = GUI.enabled;
- bool isAnalysisRunning = IsAnalysisRunning();
- EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300), GUILayout.ExpandWidth(false));
- GUIStyle buttonStyle = GUI.skin.button;
- Color oldColor = GUI.backgroundColor;
- GUI.backgroundColor = color;
- GUI.enabled = !isAnalysisRunning;
- bool load = GUILayout.Button("Load", buttonStyle, GUILayout.ExpandWidth(false), GUILayout.Width(50));
- GUI.enabled = lastEnabled;
- GUI.backgroundColor = oldColor;
- if (load)
- {
- m_Path = EditorUtility.OpenFilePanel("Load profile analyzer data file", "", "pdata");
- if (m_Path.Length != 0)
- {
- m_ActiveLoadingView = activeView;
- Pre2019DisableRecording();
- BeginAsyncAction(ThreadActivity.Load);
- }
- GUIUtility.ExitGUI();
- }
- GUI.backgroundColor = color;
- GUI.enabled = !isAnalysisRunning && view.IsDataValid();
- bool save = GUILayout.Button("Save", buttonStyle, GUILayout.ExpandWidth(false), GUILayout.Width(50));
- GUI.enabled = lastEnabled;
- GUI.backgroundColor = oldColor;
- if (save)
- {
- Save(view, true);
- }
- ShowFilename(view.path);
- EditorGUILayout.EndHorizontal();
- }
- float GetComparisonYRange()
- {
- float yRangeLeft = m_ProfileLeftView.IsDataValid() ? m_LeftFrameTimeGraph.GetDataRange() : 0f;
- float yRangeRight = m_ProfileRightView.IsDataValid() ? m_RightFrameTimeGraph.GetDataRange() : 0f;
- float yRange = Math.Max(yRangeLeft, yRangeRight);
- return yRange;
- }
- void SetFrameTimeGraphPairing(bool paired)
- {
- if (paired != m_FrameTimeGraphsPaired)
- {
- m_FrameTimeGraphsPaired = paired;
- m_LeftFrameTimeGraph.PairWith(m_FrameTimeGraphsPaired ? m_RightFrameTimeGraph : null);
- }
- }
- void DrawComparisonLoadSave()
- {
- int leftFrames = m_ProfileLeftView.IsDataValid() ? m_ProfileLeftView.data.GetFrameCount() : 0;
- int rightFrames = m_ProfileRightView.IsDataValid() ? m_ProfileRightView.data.GetFrameCount() : 0;
- int maxFrames = Math.Max(leftFrames, rightFrames);
- float yRange = GetComparisonYRange();
- EditorGUILayout.BeginHorizontal(GUILayout.Height(100 + GUI.skin.label.lineHeight + (2 * (GUI.skin.label.margin.vertical + GUI.skin.label.padding.vertical))));
- float leftFilenameWidth = GetFilenameWidth(m_ProfileLeftView.path);
- float rightFilenameWidth = GetFilenameWidth(m_ProfileRightView.path);
- float filenameWidth = Math.Max(leftFilenameWidth, rightFilenameWidth);
- filenameWidth = Math.Min(filenameWidth, 200);
- EditorGUILayout.BeginVertical(GUILayout.MaxWidth(100 + filenameWidth), GUILayout.ExpandWidth(false));
- DrawPullButton(UIColor.left, m_ProfileLeftView, m_LeftFrameTimeGraph);
- DrawComparisonLoadSaveButton(UIColor.left, m_ProfileLeftView, m_LeftFrameTimeGraph, ActiveView.Left);
- DrawPullButton(UIColor.right, m_ProfileRightView, m_RightFrameTimeGraph);
- DrawComparisonLoadSaveButton(UIColor.right, m_ProfileRightView, m_RightFrameTimeGraph, ActiveView.Right);
- EditorGUILayout.EndVertical();
- bool lastEnabled = GUI.enabled;
- bool enabled = !IsAnalysisRunning();
- EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
- GUI.SetNextControlName("LeftFrameTimeGraph");
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.Height(50));
- if (m_ProfileLeftView.IsDataValid())
- {
- if (!m_LeftFrameTimeGraph.HasData())
- m_LeftFrameTimeGraph.SetData(GetFrameTimeData(m_ProfileLeftView.data));
- if (!m_ProfileLeftView.HasValidSelection())
- m_ProfileLeftView.SelectFullRange();
- List<int> selectedOffsets = new List<int>();
- foreach (int index in m_ProfileLeftView.selectedIndices)
- {
- selectedOffsets.Add(m_ProfileLeftView.data.DisplayFrameToOffset(index));
- }
- int offsetToDisplayMapping = GetRemappedUIFirstFrameDisplayOffset(m_ProfileLeftView);
- int offsetToIndexMapping = GetRemappedUIFirstFrameOffset(m_ProfileLeftView);
- m_LeftFrameTimeGraph.SetEnabled(enabled);
- m_LeftFrameTimeGraph.Draw(rect, m_ProfileLeftView.analysis, selectedOffsets, yRange, offsetToDisplayMapping, offsetToIndexMapping, m_SelectedMarker.name, maxFrames, m_ProfileLeftView.analysisFull);
- }
- else
- {
- GUI.Label(rect, Styles.comparisonDataMissing, m_StyleUpperLeft);
- }
- GUI.SetNextControlName("RightFrameTimeGraph");
- rect = EditorGUILayout.GetControlRect(GUILayout.Height(50));
- if (m_ProfileRightView.IsDataValid())
- {
- if (!m_RightFrameTimeGraph.HasData())
- m_RightFrameTimeGraph.SetData(GetFrameTimeData(m_ProfileRightView.data));
- if (!m_ProfileRightView.HasValidSelection())
- m_ProfileRightView.SelectFullRange();
- List<int> selectedOffsets = new List<int>();
- foreach (int index in m_ProfileRightView.selectedIndices)
- {
- selectedOffsets.Add(m_ProfileRightView.data.DisplayFrameToOffset(index));
- }
- int offsetToDisplayMapping = GetRemappedUIFirstFrameDisplayOffset(m_ProfileRightView);
- int offsetToIndexMapping = GetRemappedUIFirstFrameOffset(m_ProfileRightView);
- m_RightFrameTimeGraph.SetEnabled(enabled);
- m_RightFrameTimeGraph.Draw(rect, m_ProfileRightView.analysis, selectedOffsets, yRange, offsetToDisplayMapping, offsetToIndexMapping, m_SelectedMarker.name, maxFrames, m_ProfileRightView.analysisFull);
- }
- else
- {
- GUI.Label(rect, Styles.comparisonDataMissing, m_StyleUpperLeft);
- }
- EditorGUILayout.BeginHorizontal();
- if (m_ProfileLeftView.IsDataValid() && m_ProfileRightView.IsDataValid() && m_ProfileLeftView.data.GetFrameCount() > 0 && m_ProfileRightView.data.GetFrameCount() > 0)
- {
- GUIStyle lockButtonStyle = "IN LockButton";
- GUIStyle style = new GUIStyle(lockButtonStyle);
- style.padding.left = 20;
- //bool paired = GUILayout.Toggle(m_frameTimeGraphsPaired, Styles.graphPairing, style);
- GUI.enabled = enabled;
- bool paired = EditorGUILayout.ToggleLeft(Styles.graphPairing, m_FrameTimeGraphsPaired, style, GUILayout.MaxWidth(200));
- GUI.enabled = lastEnabled;
- SetFrameTimeGraphPairing(paired);
- GUILayout.FlexibleSpace();
- ShowSelectedMarker();
- }
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.EndVertical();
- EditorGUILayout.EndHorizontal();
- }
- void DrawComparisonHistogram(float height, float minValue, float maxValue, int bucketCount, int[] leftBuckets, int[] rightBuckets, int leftCount, int rightCount, bool leftValid, bool rightValid, DisplayUnits displayUnits)
- {
- Histogram histogram = new Histogram(m_2D, displayUnits.Units);
- float width = LayoutSize.HistogramWidth;
- float min = minValue;
- float max = maxValue;
- float spacing = 2;
- float range = max - min;
- // bucketCount = (range == 0f) ? 1 : bucketCount;
- float x = (spacing / 2);
- float y = 0;
- float w = ((width + spacing) / bucketCount) - spacing;
- float h = height;
- histogram.DrawStart(width);
- if (m_2D.DrawStart(width, height, Draw2D.Origin.BottomLeft))
- {
- float bucketWidth = (range / bucketCount);
- Rect rect = GUILayoutUtility.GetLastRect();
- histogram.DrawBackground(width, height, bucketCount, min, max, spacing);
- if (!IsAnalysisRunning())
- {
- for (int bucketAt = 0; bucketAt < bucketCount; bucketAt++)
- {
- float leftBarCount = leftValid ? leftBuckets[bucketAt] : 0;
- float rightBarCount = rightValid ? rightBuckets[bucketAt] : 0;
- float leftBarHeight = leftValid ? ((h * leftBarCount) / leftCount) : 0;
- float rightBarHeight = rightValid ? ((h * rightBarCount) / rightCount) : 0;
- if (leftBarCount > 0) // Make sure we always slow a small bar if non zero
- leftBarHeight = Mathf.Max(1.0f, leftBarHeight);
- if (rightBarCount > 0) // Make sure we always slow a small bar if non zero
- rightBarHeight = Mathf.Max(1.0f, rightBarHeight);
- if ((int)rightBarHeight == (int)leftBarHeight)
- {
- m_2D.DrawFilledBox(x, y, w, leftBarHeight, UIColor.both);
- }
- else if (rightBarHeight > leftBarHeight)
- {
- m_2D.DrawFilledBox(x, y, w, rightBarHeight, UIColor.right);
- m_2D.DrawFilledBox(x, y, w, leftBarHeight, UIColor.both);
- }
- else
- {
- m_2D.DrawFilledBox(x, y, w, leftBarHeight, UIColor.left);
- m_2D.DrawFilledBox(x, y, w, rightBarHeight, UIColor.both);
- }
- float bucketStart = min + (bucketAt * bucketWidth);
- float bucketEnd = bucketStart + bucketWidth;
- string tooltip = string.Format(
- "{0}-{1}\nLeft: {2} {3}\nRight: {4} {5}\n\nBar width: {6}",
- displayUnits.ToTooltipString(bucketStart, false),
- displayUnits.ToTooltipString(bucketEnd, true),
- leftBarCount, leftBarCount == 1 ? "frame" : "frames",
- rightBarCount, rightBarCount == 1 ? "frame" : "frames",
- displayUnits.ToTooltipString(bucketWidth, true));
- GUI.Label(new Rect(rect.x + x, rect.y + y, w, h),
- new GUIContent("", tooltip)
- );
- x += w;
- x += spacing;
- }
- }
- m_2D.DrawEnd();
- }
- histogram.DrawEnd(width, min, max, spacing);
- }
- void DrawComparisonFrameSummary()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- bool lastShowFrameSummary = m_ShowFrameSummary;
- m_ShowFrameSummary = BoldFoldout(m_ShowFrameSummary, Styles.frameSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowFrameSummary)
- {
- EditorGUILayout.BeginVertical(); // To match indenting on the marker summary where a scroll area is present
- if (IsAnalysisValid())
- {
- var leftFrameSummary = m_ProfileLeftView.analysis.GetFrameSummary();
- var rightFrameSummary = m_ProfileRightView.analysis.GetFrameSummary();
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- m_Columns.Draw4("", "Left", "Right", "Diff");
- int diff = rightFrameSummary.count - leftFrameSummary.count;
- m_Columns.Draw4(Styles.frameCount, GetFrameCountText(m_ProfileLeftView), GetFrameCountText(m_ProfileRightView), new GUIContent(diff.ToString(), ""));
- m_Columns.Draw3(Styles.frameStart, GetFirstFrameText(m_ProfileLeftView), GetFirstFrameText(m_ProfileRightView));
- m_Columns.Draw3(Styles.frameEnd, GetLastFrameText(m_ProfileLeftView), GetLastFrameText(m_ProfileRightView));
- m_Columns.Draw(0, "");
- string units = GetDisplayUnits();
- m_Columns.Draw4("", units, units, units);
- Draw4DiffMs(Styles.max, leftFrameSummary.msMax, leftFrameSummary.maxFrameIndex, rightFrameSummary.msMax, rightFrameSummary.maxFrameIndex);
- Draw4DiffMs(Styles.upperQuartile, leftFrameSummary.msUpperQuartile, rightFrameSummary.msUpperQuartile);
- Draw4DiffMs(Styles.median, leftFrameSummary.msMedian, leftFrameSummary.medianFrameIndex, rightFrameSummary.msMedian, rightFrameSummary.medianFrameIndex);
- Draw4DiffMs(Styles.mean, leftFrameSummary.msMean, rightFrameSummary.msMean);
- Draw4DiffMs(Styles.lowerQuartile, leftFrameSummary.msLowerQuartile, rightFrameSummary.msLowerQuartile);
- Draw4DiffMs(Styles.min, leftFrameSummary.msMin, leftFrameSummary.minFrameIndex, rightFrameSummary.msMin, rightFrameSummary.minFrameIndex);
- GUIStyle style = GUI.skin.label;
- GUILayout.Space(style.lineHeight);
- EditorGUILayout.BeginHorizontal();
- int leftBucketCount = leftFrameSummary.buckets.Length;
- int rightBucketCount = rightFrameSummary.buckets.Length;
- float msFrameMax = Math.Max(leftFrameSummary.msMax, rightFrameSummary.msMax);
- float yRange = msFrameMax;
- if (leftBucketCount != rightBucketCount)
- {
- Debug.Log("Error left frame summary bucket count doesn't equal right summary");
- }
- else
- {
- DrawComparisonHistogram(40, 0, yRange, leftBucketCount, leftFrameSummary.buckets, rightFrameSummary.buckets, leftFrameSummary.count, rightFrameSummary.count, true, true, m_DisplayUnits);
- }
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, m_DisplayUnits.Units);
- float plotWidth = 40 + GUI.skin.box.padding.horizontal;
- float plotHeight = 40;
- plotWidth /= 2.0f;
- boxAndWhiskerPlot.Draw(plotWidth, plotHeight, leftFrameSummary.msMin, leftFrameSummary.msLowerQuartile,
- leftFrameSummary.msMedian, leftFrameSummary.msUpperQuartile, leftFrameSummary.msMax, 0, yRange,
- UIColor.boxAndWhiskerLineColorLeft, UIColor.boxAndWhiskerBoxColorLeft);
- boxAndWhiskerPlot.Draw(plotWidth, plotHeight, rightFrameSummary.msMin, rightFrameSummary.msLowerQuartile,
- rightFrameSummary.msMedian, rightFrameSummary.msUpperQuartile, rightFrameSummary.msMax, 0, yRange,
- UIColor.boxAndWhiskerLineColorRight, UIColor.boxAndWhiskerBoxColorRight);
- boxAndWhiskerPlot.DrawText(m_Columns.GetColumnWidth(3), plotHeight, 0, yRange,
- "Min frame time for selected frames in the 2 data sets",
- "Max frame time for selected frames in the 2 data sets");
- EditorGUILayout.EndHorizontal();
- }
- else
- {
- EditorGUILayout.LabelField("No analysis data selected");
- }
- EditorGUILayout.EndVertical();
- }
- if (m_ShowFrameSummary != lastShowFrameSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Frames, analytic.GetDurationInSeconds(), m_ShowFrameSummary);
- }
- EditorGUILayout.EndVertical();
- }
- void ShowThreadRange()
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, Styles.threadGraphScale);
- m_ThreadRange = (ThreadRange)EditorGUILayout.Popup((int)m_ThreadRange, Styles.threadRanges, GUILayout.Width(160));
- EditorGUILayout.EndHorizontal();
- }
- float GetThreadTimeRange(ProfileAnalysis profileAnalysis)
- {
- if (profileAnalysis == null)
- return 0.0f;
- var frameSummary = profileAnalysis.GetFrameSummary();
- float range = frameSummary.msMax;
- switch (m_ThreadRange)
- {
- case ThreadRange.Median:
- range = frameSummary.msMedian;
- break;
- case ThreadRange.UpperQuartile:
- range = frameSummary.msUpperQuartile;
- break;
- case ThreadRange.Max:
- range = frameSummary.msMax;
- break;
- }
- return range;
- }
- int GetThreadSelectionCount(out int leftSelectionCount, out int rightSelectionCount)
- {
- List<string> threadSelection = GetLimitedThreadSelection(m_ThreadNames, m_ThreadSelection);
- leftSelectionCount = 0;
- foreach (var threadName in m_ProfileLeftView.data.GetThreadNames())
- {
- if (threadSelection.Contains(threadName))
- {
- leftSelectionCount++;
- }
- }
- rightSelectionCount = 0;
- foreach (var threadName in m_ProfileRightView.data.GetThreadNames())
- {
- if (threadSelection.Contains(threadName))
- {
- rightSelectionCount++;
- }
- }
- return threadSelection.Count;
- }
- void DrawComparisonThreadSummary()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- bool lastShowThreadSummary = m_ShowThreadSummary;
- m_ShowThreadSummary = BoldFoldout(m_ShowThreadSummary, Styles.threadSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowThreadSummary)
- {
- EditorGUILayout.BeginVertical(); // To match indenting on the marker summary where a scroll area is present
- if (IsAnalysisValid())
- {
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw4("", "Left", "Right", "Total");
- EditorGUILayout.EndHorizontal();
- int matchingCount, uniqueLeft, uniqueRight;
- int allThreadsCount = GetCombinedThreadCount(out matchingCount, out uniqueLeft, out uniqueRight);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, "Total Count : ");
- m_Columns.Draw(1, new GUIContent(m_ProfileLeftView.data.GetThreadCount().ToString(), "Total threads in left data set"));
- m_Columns.Draw(2, new GUIContent(m_ProfileRightView.data.GetThreadCount().ToString(), "Total threads in right data set"));
- string tooltip = GetThreadCountToolTipUnion(allThreadsCount, matchingCount);
- m_Columns.Draw(3, new GUIContent(allThreadsCount.ToString(), tooltip));
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, "Unique Count : ");
- m_Columns.Draw(1, new GUIContent(uniqueLeft.ToString(), "Unique to left data set"));
- m_Columns.Draw(2, new GUIContent(uniqueRight.ToString(), "Unique to right data set"));
- tooltip = GetThreadCountToolTipDifference(allThreadsCount, matchingCount, uniqueLeft, uniqueRight);
- m_Columns.Draw(3, new GUIContent((allThreadsCount - matchingCount).ToString(), tooltip));
- EditorGUILayout.EndHorizontal();
- int leftSelectionCount, rightSelectionCount;
- int selectedThreads = GetThreadSelectionCount(out leftSelectionCount, out rightSelectionCount);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, "Selected : ");
- m_Columns.Draw(1, new GUIContent(leftSelectionCount.ToString(), "Left selected"));
- m_Columns.Draw(2, new GUIContent(rightSelectionCount.ToString(), "Right selected"));
- m_Columns.Draw(3, new GUIContent(selectedThreads.ToString(), "Total selected"));
- EditorGUILayout.EndHorizontal();
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2 + LayoutSize.WidthColumn3, 0);
- ShowThreadRange();
- float width = 100;
- float height = GUI.skin.label.lineHeight;
- float xAxisMin = 0.0f;
- float xAxisMax = GetThreadTimeRange(m_ProfileLeftView.analysis);
- m_Columns.Draw3(Styles.emptyString, Styles.median, Styles.thread);
- m_ThreadScroll = EditorGUILayout.BeginScrollView(m_ThreadScroll, GUIStyle.none, GUI.skin.verticalScrollbar);
- Rect clipRect = new Rect(m_ThreadScroll.x, m_ThreadScroll.y, m_ComparisonThreadsAreaRect.width, m_ComparisonThreadsAreaRect.height);
- m_2D.SetClipRect(clipRect);
- for (int i = 0; i < m_ThreadUINames.Count; i++)
- {
- string threadNameWithIndex = m_ThreadNames[i];
- bool include = ProfileAnalyzer.MatchThreadFilter(threadNameWithIndex, m_ThreadSelection.selection);
- if (!include)
- continue;
- ThreadData threadLeft = m_ProfileLeftView.analysis.GetThreadByName(threadNameWithIndex);
- ThreadData threadRight = m_ProfileRightView.analysis.GetThreadByName(threadNameWithIndex);
- ThreadData thread = threadLeft != null ? threadLeft : threadRight;
- if (thread == null)
- continue;
- bool singleThread = thread.threadsInGroup > 1 ? false : true;
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, m_DisplayUnits.Units);
- EditorGUILayout.BeginHorizontal();
- if (threadLeft != null)
- boxAndWhiskerPlot.DrawHorizontal(width, height, threadLeft.msMin, threadLeft.msLowerQuartile, threadLeft.msMedian, threadLeft.msUpperQuartile, threadLeft.msMax, xAxisMin, xAxisMax, UIColor.boxAndWhiskerLineColorLeft, UIColor.boxAndWhiskerBoxColorLeft, GUI.skin.label);
- else
- EditorGUILayout.LabelField(Styles.noThread, GUILayout.Width(width));
- m_Columns.Draw(1, (threadLeft != null) ? ToDisplayUnitsWithTooltips(threadLeft.msMedian) : Styles.noThread);
- m_Columns.Draw(2, GetThreadNameWithGroupTooltip(thread.threadNameWithIndex, singleThread));
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- if (threadRight != null)
- boxAndWhiskerPlot.DrawHorizontal(width, height, threadRight.msMin, threadRight.msLowerQuartile, threadRight.msMedian, threadRight.msUpperQuartile, threadRight.msMax, xAxisMin, xAxisMax, UIColor.boxAndWhiskerLineColorRight, UIColor.boxAndWhiskerBoxColorRight, GUI.skin.label);
- else
- EditorGUILayout.LabelField(Styles.noThread, GUILayout.Width(width));
- m_Columns.Draw(1, (threadRight != null) ? ToDisplayUnitsWithTooltips(threadRight.msMedian) : Styles.noThread);
- m_Columns.Draw(2, "");
- EditorGUILayout.EndHorizontal();
- }
- m_2D.ClearClipRect();
- EditorGUILayout.EndScrollView();
- if (Event.current.type == EventType.Repaint)
- {
- // This value is not valid at layout phase
- m_ComparisonThreadsAreaRect = GUILayoutUtility.GetLastRect();
- }
- }
- else
- {
- EditorGUILayout.LabelField("No analysis data selected");
- }
- EditorGUILayout.EndVertical();
- }
- if (m_ShowThreadSummary != lastShowThreadSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Threads, analytic.GetDurationInSeconds(), m_ShowThreadSummary);
- }
- EditorGUILayout.EndVertical();
- }
- static readonly ProfilerMarkerAbstracted m_DrawCompareOptionsProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawCompareOptions");
- void DrawCompareOptions()
- {
- using (m_DrawCompareOptionsProfilerMarker.Auto())
- {
- EditorGUILayout.BeginVertical(GUI.skin.box);
- bool lastShowFilters = m_ShowFilters;
- m_ShowFilters = BoldFoldout(m_ShowFilters, Styles.filters);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowFilters)
- {
- DrawNameFilter();
- EditorGUILayout.BeginHorizontal();
- DrawThreadFilter(m_ProfileLeftView.data);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- m_DepthSliceUI.DrawDepthFilter(IsAnalysisRunning(), m_ActiveTab == ActiveTab.Summary,
- m_ProfileSingleView, m_ProfileLeftView, m_ProfileRightView);
- DrawTimingFilter();
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- DrawParentFilter();
- DrawUnitFilter();
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- if (m_ProfileLeftView.IsDataValid() && m_ProfileRightView.IsDataValid())
- {
- bool lastEnabled = GUI.enabled;
- GUI.enabled = !IsAnalysisRunning();
- if (GUILayout.Button(new GUIContent("Compare", m_LastCompareTime), GUILayout.Width(100)))
- m_RequestCompare = true;
- GUI.enabled = lastEnabled;
- }
- DrawMarkerCount();
- EditorGUILayout.LabelField(",", GUILayout.Width(10), GUILayout.ExpandWidth(false));
- DrawThreadCount();
- GUILayout.FlexibleSpace();
- DrawMarkerColumnFilter();
- EditorGUILayout.EndHorizontal();
- }
- if (m_ShowFilters != lastShowFilters)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Filters,
- analytic.GetDurationInSeconds(), m_ShowFilters);
- }
- EditorGUILayout.EndVertical();
- }
- }
- static readonly ProfilerMarkerAbstracted m_DrawComparisonProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawComparison");
- static readonly ProfilerMarkerAbstracted m_DrawComparisonTableProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawComparisonTable");
- void DrawComparison()
- {
- using (m_DrawComparisonProfilerMarker.Auto())
- {
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.BeginVertical();
- DrawFilesLoaded();
- if (m_ProfileLeftView.IsDataValid() && m_ProfileRightView.IsDataValid() &&
- m_ProfileLeftView.data.GetFrameCount() > 0 && m_ProfileRightView.data.GetFrameCount() > 0)
- {
- DrawCompareOptions();
- if (m_ComparisonTable != null)
- {
- EditorGUILayout.BeginVertical(GUI.skin.box);
- string title = string.Format("Top {0} markers on median frames", m_TopNBars);
- GUIContent markersTitle = new GUIContent(title, Styles.topMarkersTooltip);
- bool lastShowTopMarkers = m_ShowTopNMarkers;
- m_ShowTopNMarkers = BoldFoldout(m_ShowTopNMarkers, markersTitle);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowTopNMarkers)
- {
- using (m_TopNMarkersProfilerMarker.Auto())
- {
- EditorGUILayout.BeginVertical(GUILayout.Height(40));
- Rect rect = EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true),
- GUILayout.ExpandHeight(true));
- rect.height = rect.height / 2;
- var nameFilters = GetNameFilters();
- var nameExcludes = GetNameExcludes();
- m_TopMarkersLeft.SetData(m_ProfileLeftView, m_DepthSliceUI.depthFilter1, nameFilters,
- nameExcludes, m_TimingOption, m_ThreadSelection.selection.Count);
- m_TopMarkersRight.SetData(m_ProfileRightView, m_DepthSliceUI.depthFilter2, nameFilters,
- nameExcludes, m_TimingOption, m_ThreadSelection.selection.Count);
- float leftRange = m_TopMarkersLeft.GetTopMarkerTimeRange();
- float rightRange = m_TopMarkersRight.GetTopMarkerTimeRange();
- if (m_TopTenDisplay == TopTenDisplay.LongestTime)
- {
- float max = Math.Max(leftRange, rightRange);
- leftRange = max;
- rightRange = max;
- }
- int leftMedian = 0;
- int rightMedian = 0;
- if (m_ProfileLeftView.analysis != null)
- {
- FrameSummary frameSummary = m_ProfileLeftView.analysis.GetFrameSummary();
- if (frameSummary.count > 0)
- leftMedian = frameSummary.medianFrameIndex;
- }
- if (m_ProfileRightView.analysis != null)
- {
- FrameSummary frameSummary = m_ProfileRightView.analysis.GetFrameSummary();
- if (frameSummary.count > 0)
- rightMedian = frameSummary.medianFrameIndex;
- }
- int maxMedian = Math.Max(leftMedian, rightMedian);
- Rect frameIndexRect = new Rect(rect);
- Vector2 size =
- GUI.skin.button.CalcSize(new GUIContent(string.Format("{0}", maxMedian)));
- frameIndexRect.width =
- Math.Max(size.x, 50); // DrawFrameIndexButton should always be at least 50 wide
- if (leftMedian != 0f)
- DrawFrameIndexButton(frameIndexRect, leftMedian, m_ProfileLeftView);
- else
- GUI.Label(frameIndexRect, "");
- float padding = 2;
- rect.x += frameIndexRect.width + padding;
- rect.width -= frameIndexRect.width;
- m_TopMarkersLeft.Draw(rect, UIColor.left, m_TopNBars, leftRange, UIColor.barBackground,
- Color.black, Color.white, true, true);
- rect.y += rect.height;
- frameIndexRect.y += rect.height;
- if (rightMedian != 0f)
- DrawFrameIndexButton(frameIndexRect, rightMedian, m_ProfileRightView);
- else
- GUI.Label(frameIndexRect, "");
- m_TopMarkersRight.Draw(rect, UIColor.right, m_TopNBars, rightRange,
- UIColor.barBackground,
- Color.black, Color.white, true, true);
- EditorGUILayout.EndVertical();
- EditorGUILayout.BeginHorizontal();
- GUILayout.Label(m_DepthSliceUI.GetUIInfo(true), GUILayout.ExpandWidth(true));
- GUILayout.Label(Styles.topMarkerRatio, GUILayout.ExpandWidth(false));
- m_TopTenDisplay = (TopTenDisplay)EditorGUILayout.Popup((int)m_TopTenDisplay, Styles.topTenDisplayOptions, GUILayout.MaxWidth(100));
- EditorGUILayout.EndHorizontal();
- }
- }
- if (m_ShowTopNMarkers != lastShowTopMarkers)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(
- ProfileAnalyzerAnalytics.UIVisibility.Markers, analytic.GetDurationInSeconds(),
- m_ShowTopNMarkers);
- }
- EditorGUILayout.EndVertical();
- if (m_ComparisonTable != null)
- {
- m_ShowMarkerTable = BoldFoldout(m_ShowMarkerTable, Styles.comparisonTable);
- if (m_ShowMarkerTable)
- {
- using (m_DrawComparisonTableProfilerMarker.Auto())
- {
- Rect r = EditorGUILayout.GetControlRect(GUILayout.ExpandHeight(true));
- float scrollBarWidth = GUI.skin.verticalScrollbar.fixedWidth +
- GUI.skin.verticalScrollbar.border.horizontal +
- GUI.skin.verticalScrollbar.margin.horizontal +
- GUI.skin.verticalScrollbar.padding.horizontal;
- scrollBarWidth += LayoutSize.ScrollBarPadding;
- //offset vertically to get correct clipping behaviour
- Rect clipRect = new Rect(r.x, m_ComparisonTable.state.scrollPos.y,
- r.width - scrollBarWidth,
- r.height - (m_ComparisonTable.multiColumnHeader.height + GUI.skin.box.padding.top) -
- (m_ComparisonTable.ShowingHorizontalScroll
- ? (scrollBarWidth - LayoutSize.ScrollBarPadding)
- : 0));
- m_2D.SetClipRect(clipRect);
- m_ComparisonTable.OnGUI(r);
- m_2D.ClearClipRect();
- }
- }
- }
- }
- }
- else
- {
- ShowHelp();
- }
- EditorGUILayout.EndVertical();
- EditorGUILayout.BeginVertical(GUILayout.Width(LayoutSize.WidthRHS));
- GUILayout.Space(4);
- DrawComparisonFrameSummary();
- DrawComparisonThreadSummary();
- DrawComparisonSelected();
- EditorGUILayout.EndVertical();
- EditorGUILayout.EndHorizontal();
- }
- }
- bool BoldFoldout(bool toggle, GUIContent content)
- {
- GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout);
- foldoutStyle.fontStyle = FontStyle.Bold;
- return EditorGUILayout.Foldout(toggle, content, true, foldoutStyle);
- }
- void DrawComparisonSelectedStats(MarkerData leftMarker, MarkerData rightMarker)
- {
- GUIStyle style = GUI.skin.label;
- string units = GetDisplayUnits();
- m_Columns.Draw4("", units, units, units);
- Draw4DiffMs(Styles.max, MarkerData.GetMsMax(leftMarker), MarkerData.GetMaxFrameIndex(leftMarker), MarkerData.GetMsMax(rightMarker), MarkerData.GetMaxFrameIndex(rightMarker));
- Draw4DiffMs(Styles.upperQuartile, MarkerData.GetMsUpperQuartile(leftMarker), MarkerData.GetMsUpperQuartile(rightMarker));
- Draw4DiffMs(Styles.median, MarkerData.GetMsMedian(leftMarker), MarkerData.GetMedianFrameIndex(leftMarker), MarkerData.GetMsMedian(rightMarker), MarkerData.GetMedianFrameIndex(rightMarker));
- Draw4DiffMs(Styles.mean, MarkerData.GetMsMean(leftMarker), MarkerData.GetMsMean(rightMarker));
- Draw4DiffMs(Styles.lowerQuartile, MarkerData.GetMsLowerQuartile(leftMarker), MarkerData.GetMsLowerQuartile(rightMarker));
- Draw4DiffMs(Styles.min, MarkerData.GetMsMin(leftMarker), MarkerData.GetMinFrameIndex(leftMarker), MarkerData.GetMsMin(rightMarker), MarkerData.GetMinFrameIndex(rightMarker));
- GUILayout.Space(style.lineHeight);
- Draw4DiffMs(Styles.individualMax, MarkerData.GetMsMaxIndividual(leftMarker), MarkerData.GetMsMaxIndividual(rightMarker));
- Draw4DiffMs(Styles.individualMin, MarkerData.GetMsMinIndividual(leftMarker), MarkerData.GetMsMinIndividual(rightMarker));
- }
- void DrawComparisonSelected()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- GUIStyle style = GUI.skin.label;
- bool lastMarkerSummary = m_ShowMarkerSummary;
- m_ShowMarkerSummary = BoldFoldout(m_ShowMarkerSummary, Styles.markerSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowMarkerSummary)
- {
- EditorGUILayout.BeginVertical(); // To match indenting on the marker summary where a scroll area is present
- if (IsAnalysisValid())
- {
- List<MarkerData> leftMarkers = m_ProfileLeftView.analysis.GetMarkers();
- List<MarkerData> rightMarkers = m_ProfileRightView.analysis.GetMarkers();
- int pairingAt = m_SelectedPairing;
- if (leftMarkers != null && rightMarkers != null && m_Pairings != null)
- {
- if (pairingAt >= 0 && pairingAt < m_Pairings.Count)
- {
- m_MarkerSummaryScroll = GUILayout.BeginScrollView(m_MarkerSummaryScroll, GUIStyle.none, GUI.skin.verticalScrollbar);
- Rect clipRect = new Rect(m_MarkerSummaryScroll.x, m_MarkerSummaryScroll.y, LayoutSize.WidthRHS, 500);
- m_2D.SetClipRect(clipRect);
- EditorGUILayout.BeginVertical();
- var pairing = m_Pairings[pairingAt];
- var leftMarker = (pairing.leftIndex >= 0 && pairing.leftIndex < leftMarkers.Count) ? leftMarkers[pairing.leftIndex] : null;
- var rightMarker = (pairing.rightIndex >= 0 && pairing.rightIndex < rightMarkers.Count) ? rightMarkers[pairing.rightIndex] : null;
- EditorGUILayout.LabelField(pairing.name,
- GUILayout.MaxWidth(LayoutSize.WidthRHS -
- (GUI.skin.box.padding.horizontal + GUI.skin.box.margin.horizontal)));
- DrawComparisonFrameRatio(leftMarker, rightMarker);
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, Styles.firstFrame);
- if (leftMarker != null)
- DrawFrameIndexButton(leftMarker.firstFrameIndex, m_ProfileLeftView);
- else
- m_Columns.Draw(1, Styles.emptyString);
- if (rightMarker != null)
- DrawFrameIndexButton(rightMarker.firstFrameIndex, m_ProfileRightView);
- else
- m_Columns.Draw(2, Styles.emptyString);
- EditorGUILayout.EndHorizontal();
- DrawTopComparison(leftMarker, rightMarker);
- GUILayout.Space(style.lineHeight);
- EditorGUILayout.BeginHorizontal();
- int leftBucketCount = leftMarker != null ? leftMarker.buckets.Length : 0;
- int rightBucketCount = rightMarker != null ? rightMarker.buckets.Length : 0;
- float leftMin = MarkerData.GetMsMin(leftMarker);
- float rightMin = MarkerData.GetMsMin(rightMarker);
- float leftMax = MarkerData.GetMsMax(leftMarker);
- float rightMax = MarkerData.GetMsMax(rightMarker);
- int[] leftBuckets = leftMarker != null ? leftMarker.buckets : new int[0];
- int[] rightBuckets = rightMarker != null ? rightMarker.buckets : new int[0];
- Units units = m_DisplayUnits.Units;
- string unitName = "marker time";
- if (DisplayCount())
- {
- units = Units.Count;
- unitName = "count";
- leftBucketCount = leftMarker != null ? leftMarker.countBuckets.Length : 0;
- rightBucketCount = rightMarker != null ? rightMarker.countBuckets.Length : 0;
- leftMin = MarkerData.GetCountMin(leftMarker);
- rightMin = MarkerData.GetCountMin(rightMarker);
- leftMax = MarkerData.GetCountMax(leftMarker);
- rightMax = MarkerData.GetCountMax(rightMarker);
- leftBuckets = leftMarker != null ? leftMarker.countBuckets : new int[0];
- rightBuckets = rightMarker != null ? rightMarker.countBuckets : new int[0];
- }
- DisplayUnits displayUnits = new DisplayUnits(units);
- float minValue;
- float maxValue;
- if (leftMarker != null && rightMarker != null)
- {
- minValue = Math.Min(leftMin, rightMin);
- maxValue = Math.Max(leftMax, rightMax);
- }
- else if (leftMarker != null)
- {
- minValue = leftMin;
- maxValue = leftMax;
- }
- else // Either valid or 0
- {
- minValue = rightMin;
- maxValue = rightMax;
- }
- if (leftBucketCount > 0 && rightBucketCount > 0 && leftBucketCount != rightBucketCount)
- {
- Debug.Log("Error - number of buckets doesn't match in the left and right marker analysis");
- }
- else
- {
- int bucketCount = Math.Max(leftBucketCount, rightBucketCount);
- int leftFrameCount = MarkerData.GetPresentOnFrameCount(leftMarker);
- int rightFrameCount = MarkerData.GetPresentOnFrameCount(rightMarker);
- DrawComparisonHistogram(100, minValue, maxValue, bucketCount, leftBuckets, rightBuckets, leftFrameCount, rightFrameCount, leftMarker != null, rightMarker != null, displayUnits);
- }
- float plotWidth = 40 + GUI.skin.box.padding.horizontal;
- float plotHeight = 100;
- plotWidth /= 2.0f;
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, units);
- DrawBoxAndWhiskerPlotForMarker(boxAndWhiskerPlot, plotWidth, plotHeight, m_ProfileLeftView.analysis, leftMarker, minValue, maxValue,
- UIColor.boxAndWhiskerLineColorLeft, UIColor.boxAndWhiskerBoxColorLeft);
- DrawBoxAndWhiskerPlotForMarker(boxAndWhiskerPlot, plotWidth, plotHeight, m_ProfileRightView.analysis, rightMarker, minValue, maxValue,
- UIColor.boxAndWhiskerLineColorRight, UIColor.boxAndWhiskerBoxColorRight);
- boxAndWhiskerPlot.DrawText(m_Columns.GetColumnWidth(3), plotHeight, minValue, maxValue,
- string.Format("Min {0} for selected frames in the 2 data sets", unitName),
- string.Format("Max {0} for selected frames in the 2 data sets", unitName));
- EditorGUILayout.EndHorizontal();
- GUILayout.Space(style.lineHeight);
- DrawComparisonSelectedStats(leftMarker, rightMarker);
- EditorGUILayout.EndVertical();
- m_2D.ClearClipRect();
- GUILayout.EndScrollView();
- }
- else
- {
- EditorGUILayout.LabelField("Marker not in selection");
- }
- }
- }
- else
- {
- EditorGUILayout.LabelField("No marker data selected");
- }
- EditorGUILayout.EndVertical();
- }
- if (m_ShowMarkerSummary != lastMarkerSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Markers, analytic.GetDurationInSeconds(), m_ShowMarkerSummary);
- }
- EditorGUILayout.EndVertical();
- }
- void SelectTab(ActiveTab newTab)
- {
- m_NextActiveTab = newTab;
- }
- static readonly ProfilerMarkerAbstracted m_DrawToolbarProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.DrawToolbar");
- void DrawToolbar()
- {
- using (m_DrawToolbarProfilerMarker.Auto())
- {
- EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
- EditorGUILayout.LabelField("Mode:", GUILayout.Width(40));
- ActiveTab newTab = (ActiveTab)GUILayout.Toolbar((int)m_ActiveTab, new string[] {"Single", "Compare"},
- EditorStyles.toolbarButton, GUILayout.ExpandWidth(false));
- if (newTab != m_ActiveTab)
- {
- SelectTab(newTab);
- }
- //GUILayout.FlexibleSpace();
- EditorGUILayout.Separator();
- bool lastEnabled = GUI.enabled;
- bool enabled = GUI.enabled;
- if (m_ProfileSingleView.IsDataValid() ||
- (m_ProfileLeftView.IsDataValid() && m_ProfileRightView.IsDataValid()))
- GUI.enabled = true;
- else
- GUI.enabled = false;
- if (GUILayout.Button(Styles.export, EditorStyles.toolbarButton, GUILayout.Width(50)))
- {
- Vector2 windowPosition = new Vector2(Event.current.mousePosition.x,
- Event.current.mousePosition.y + GUI.skin.label.lineHeight);
- Vector2 screenPosition = GUIUtility.GUIToScreenPoint(windowPosition);
- ProfileAnalyzerExportWindow.Open(screenPosition.x, screenPosition.y, m_ProfileSingleView,
- m_ProfileLeftView, m_ProfileRightView, this);
- EditorGUIUtility.ExitGUI();
- }
- GUI.enabled = lastEnabled;
- bool profilerOpen = IsProfilerWindowOpen();
- if (!profilerOpen)
- {
- if (GUILayout.Toggle(profilerOpen, "Open Profiler Window", EditorStyles.toolbarButton,
- GUILayout.ExpandWidth(false)) == true)
- {
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- m_ProfilerWindowInterface.OpenProfilerOrUseExisting();
- ProfileAnalyzerAnalytics.SendUIButtonEvent(ProfileAnalyzerAnalytics.UIButton.OpenProfiler,
- analytic);
- EditorGUIUtility.ExitGUI();
- }
- }
- else
- {
- if (GUILayout.Toggle(profilerOpen, "Close Profiler Window", EditorStyles.toolbarButton,
- GUILayout.ExpandWidth(false)) == false)
- {
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- m_ProfilerWindowInterface.CloseProfiler();
- ProfileAnalyzerAnalytics.SendUIButtonEvent(ProfileAnalyzerAnalytics.UIButton.CloseProfiler,
- analytic);
- EditorGUIUtility.ExitGUI();
- }
- }
- EditorGUILayout.Separator();
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
- }
- }
- void SetupStyles()
- {
- if (!m_StylesSetup)
- {
- m_StyleMiddleRight = new GUIStyle(GUI.skin.label);
- m_StyleMiddleRight.alignment = TextAnchor.MiddleRight;
- m_StyleUpperLeft = new GUIStyle(GUI.skin.label);
- m_StyleUpperLeft.alignment = TextAnchor.UpperLeft;
- m_StylesSetup = true;
- }
- }
- static readonly ProfilerMarkerAbstracted m_DrawProfilerMarker = new ProfilerMarkerAbstracted("ProfileAnalyzer.Draw");
- void Draw()
- {
- // Make sure we start enabled (in case something overrode it last frame)
- GUI.enabled = true;
- using (m_DrawProfilerMarker.Auto())
- {
- SetupStyles();
- EditorGUILayout.BeginVertical();
- DrawToolbar();
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- DrawAnalysis();
- break;
- case ActiveTab.Compare:
- DrawComparison();
- break;
- }
- EditorGUILayout.EndVertical();
- }
- }
- int FindSelectionByName(List<MarkerData> markers, string name)
- {
- int index = 0;
- foreach (var marker in markers)
- {
- if (marker.name == name)
- return index;
- index++;
- }
- return -1; // not found
- }
- /// <summary>
- /// Select marker to focus on
- /// </summary>
- /// <param name="name">Name of the marker</param>
- // Version 1.0 of the package exposed this API so we can't remove it until we increment the major package version.
- public void SelectMarker(string name)
- {
- SelectMarker(name, null, null);
- }
- void SelectMarker(string name, string threadGroupName = null, string threadName = null)
- {
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- SelectMarkerByName(name, threadGroupName, threadName);
- break;
- case ActiveTab.Compare:
- SelectPairingByName(name, threadGroupName, threadName);
- break;
- }
- }
- void UpdateSelectedMarkerName(string markerName)
- {
- m_SelectedMarker.name = markerName;
- // only update the Profiler Window if it wasn't updated successfully with this marker yet.
- if (m_LastMarkerSuccesfullySyncedWithProfilerWindow == markerName)
- return;
- var updatedSelectedSampleSuccesfully = false;
- if (m_ProfilerWindowInterface.IsReady() && !m_SelectionEventFromProfilerWindowInProgress && m_ThreadSelection.selection != null && m_ThreadSelection.selection.Count > 0)
- {
- updatedSelectedSampleSuccesfully = m_ProfilerWindowInterface.SetProfilerWindowMarkerName(markerName, m_ThreadSelection.selection);
- }
- if (updatedSelectedSampleSuccesfully)
- m_LastMarkerSuccesfullySyncedWithProfilerWindow = markerName;
- }
- internal void SelectMarkerByIndex(int index, string markerNameFallback = null, string threadGroupName = null, string threadName = null)
- {
- if (m_ProfileSingleView == null || m_ProfileSingleView.analysis == null)
- return;
- // Check if this marker is in the 'filtered' list
- var markers = m_ProfileSingleView.analysis.GetMarkers();
- if (markers.Count <= 0)
- return;
- bool valid = true;
- if (index >= 0 && index < markers.Count)
- {
- var marker = markers[index];
- var nameFilters = GetNameFilters();
- if (nameFilters.Count > 0)
- {
- if (!NameInFilterList(marker.name, nameFilters))
- valid = false;
- }
- var nameExcludes = GetNameExcludes();
- if (nameExcludes.Count > 0)
- {
- if (NameInExcludeList(marker.name, nameExcludes))
- valid = false;
- }
- }
- m_SelectedMarker.id = index;
- if (m_ProfileTable != null)
- {
- List<int> selection = new List<int>();
- if (index >= 0 && valid)
- selection.Add(index);
- m_ProfileTable.SetSelection(selection, TreeViewSelectionOptions.RevealAndFrame);
- }
- var markerName = GetMarkerName(index);
- if (index == -1 && !string.IsNullOrEmpty(markerNameFallback))
- {
- markerName = markerNameFallback;
- if (!string.IsNullOrEmpty(threadName))
- {
- m_SelectedMarker.threadGroupName = threadGroupName;
- m_SelectedMarker.threadName = threadName;
- }
- else
- {
- m_SelectedMarker.threadGroupName = null;
- m_SelectedMarker.threadName = null;
- }
- }
- else
- {
- m_SelectedMarker.threadGroupName = null;
- m_SelectedMarker.threadName = null;
- }
- if (markerName != null)
- UpdateSelectedMarkerName(markerName);
- }
- /// <summary>
- /// Get currently selected marker
- /// </summary>
- /// <returns>Name of currently selected marker, or null if none selected</returns>
- public string GetSelectedMarkerName()
- {
- switch (m_ActiveTab)
- {
- case ActiveTab.Summary:
- return GetMarkerName(m_SelectedMarker.id);
- case ActiveTab.Compare:
- return GetPairingName(m_SelectedPairing);
- }
- return null;
- }
- string GetMarkerName(int index)
- {
- if (m_ProfileSingleView.analysis == null)
- return null;
- var marker = m_ProfileSingleView.analysis.GetMarker(index);
- if (marker == null)
- return null;
- return marker.name;
- }
- void SelectMarkerByName(string markerName, string threadGroupName = null, string threadName = null)
- {
- int index = (m_ProfileSingleView.analysis != null) ? m_ProfileSingleView.analysis.GetMarkerIndexByName(markerName) : -1;
- SelectMarkerByIndex(index, markerName, threadGroupName, threadName);
- }
- internal void SelectPairing(int index, string threadGroupName = null, string threadName = null)
- {
- if (m_Pairings == null || m_Pairings.Count == 0)
- return;
- // Check if this marker is in the 'filtered' list
- bool valid = true;
- if (index >= 0 && index < m_Pairings.Count)
- {
- var pairing = m_Pairings[index];
- var nameFilters = GetNameFilters();
- if (nameFilters.Count > 0)
- {
- if (!NameInFilterList(pairing.name, nameFilters))
- valid = false;
- }
- var nameExcludes = GetNameExcludes();
- if (nameExcludes.Count > 0)
- {
- if (NameInExcludeList(pairing.name, nameExcludes))
- valid = false;
- }
- }
- m_SelectedPairing = index;
- if (m_ComparisonTable != null)
- {
- List<int> selection = new List<int>();
- if (index >= 0 && valid)
- selection.Add(index);
- m_ComparisonTable.SetSelection(selection, TreeViewSelectionOptions.RevealAndFrame);
- }
- var markerName = GetPairingName(index);
- if (markerName != null)
- UpdateSelectedMarkerName(markerName);
- }
- string GetPairingName(int index)
- {
- if (m_Pairings == null)
- return null;
- if (index < 0 || index >= m_Pairings.Count)
- return null;
- return m_Pairings[index].name;
- }
- void SelectPairingByName(string pairingName, string threadGroupName = null, string threadName = null)
- {
- if (m_Pairings != null && pairingName != null)
- {
- for (int index = 0; index < m_Pairings.Count; index++)
- {
- var pairing = m_Pairings[index];
- if (pairing.name == pairingName)
- {
- SelectPairing(index, threadGroupName, threadName);
- return;
- }
- }
- }
- SelectPairing(-1, threadGroupName, threadName);
- }
- GUIContent GetFrameCountText(ProfileDataView context)
- {
- var frameSummary = context.analysis.GetFrameSummary();
- string text;
- string tooltip;
- if (frameSummary.first == frameSummary.last)
- {
- text = string.Format("{0}", frameSummary.count);
- tooltip = "";
- }
- else
- {
- int rangeSize = (1 + (frameSummary.last - frameSummary.first));
- if (frameSummary.count == rangeSize)
- {
- text = string.Format("{0}", frameSummary.count);
- tooltip = string.Format("{0} frames selected\n\n{1} first selected frame\n{2} last selected frame\n\nConsecutive Sequence"
- , frameSummary.count
- , GetRemappedUIFrameIndex(frameSummary.first, context)
- , GetRemappedUIFrameIndex(frameSummary.last, context));
- }
- else
- {
- text = string.Format("{0}*", frameSummary.count);
- var ranges = RangesText(context);
- tooltip = string.Format("{0} frames selected\n\nframe ranges: {1} \n\nNot a consecutive sequence", frameSummary.count, ranges);
- }
- }
- return new GUIContent(text, tooltip);
- }
- string RangesText(ProfileDataView context)
- {
- var sortedFrames = context.analysis.GetFrameSummary().frames.OrderBy(x => x.frameIndex).ToArray();
- var ranges = "";
- int lastAdded = GetRemappedUIFrameIndex(sortedFrames[0].frameIndex, context);
- ranges += lastAdded;
- for (int n = 1; n < sortedFrames.Length; ++n)
- {
- if (sortedFrames[n].frameIndex == (sortedFrames[n - 1].frameIndex + 1)) continue;
- int nIdx = GetRemappedUIFrameIndex(sortedFrames[n].frameIndex, context);
- int pNIdx = GetRemappedUIFrameIndex(sortedFrames[n - 1].frameIndex, context);
- if (lastAdded == pNIdx)
- {
- ranges += ", " + nIdx;
- }
- else
- {
- ranges += "-" + pNIdx + ", " + nIdx;
- }
- lastAdded = nIdx;
- }
- int remappedLastFrame = GetRemappedUIFrameIndex(sortedFrames.Last().frameIndex, context);
- if (lastAdded == remappedLastFrame)
- return ranges;
- ranges += "-" + remappedLastFrame;
- return ranges;
- }
- GUIContent GetFirstFrameText(ProfileDataView context)
- {
- var frameSummary = context.analysis.GetFrameSummary();
- string text;
- string tooltip;
- if (frameSummary.count == 0)
- {
- text = "";
- tooltip = "";
- }
- else if (frameSummary.first == frameSummary.last)
- {
- int remappedFrame = GetRemappedUIFrameIndex(frameSummary.first, context);
- text = string.Format("{0}", remappedFrame);
- tooltip = string.Format("Frame {0} selected", remappedFrame);
- }
- else
- {
- int rangeSize = (1 + (frameSummary.last - frameSummary.first));
- if (frameSummary.count == rangeSize)
- {
- int remappedFirstFrame = GetRemappedUIFrameIndex(frameSummary.first, context);
- text = string.Format("{0}", remappedFirstFrame);
- tooltip = string.Format("{0} frames selected\n\n{1} first selected frame\n{2} last selected frame\n\nConsecutive Sequence"
- , frameSummary.count
- , remappedFirstFrame
- , GetRemappedUIFrameIndex(frameSummary.last, context));
- }
- else
- {
- text = string.Format("{0}*", GetRemappedUIFrameIndex(frameSummary.first, context));
- var ranges = RangesText(context);
- tooltip = string.Format("{0} frames selected\n\nframe ranges: {1} \n\nNot a consecutive sequence", frameSummary.count, ranges);
- }
- }
- return new GUIContent(text, tooltip);
- }
- GUIContent GetLastFrameText(ProfileDataView context)
- {
- var frameSummary = context.analysis.GetFrameSummary();
- string text;
- string tooltip;
- if (frameSummary.count == 0)
- {
- text = "";
- tooltip = "";
- }
- else if (frameSummary.first == frameSummary.last)
- {
- text = "";
- tooltip = string.Format("Frame {0} selected", GetRemappedUIFrameIndex(frameSummary.first, context), context);
- }
- else
- {
- int rangeSize = (1 + (frameSummary.last - frameSummary.first));
- if (frameSummary.count == rangeSize)
- {
- int remappedLastFrame = GetRemappedUIFrameIndex(frameSummary.last, context);
- text = string.Format("{0}", remappedLastFrame);
- tooltip = string.Format("{0} frames selected\n\n{1} first selected frame\n{2} last selected frame\n\nConsecutive Sequence",
- frameSummary.count,
- GetRemappedUIFrameIndex(frameSummary.first, context),
- remappedLastFrame);
- }
- else
- {
- text = string.Format("{0}*", GetRemappedUIFrameIndex(frameSummary.last, context));
- var ranges = RangesText(context);
- tooltip = string.Format("{0} frames selected\n\nframe ranges: {1} \n\nNot a consecutive sequence", frameSummary.count, ranges);;
- }
- }
- return new GUIContent(text, tooltip);
- }
- void DrawFrameSummary()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- bool lastShowFrameSummary = m_ShowFrameSummary;
- m_ShowFrameSummary = BoldFoldout(m_ShowFrameSummary, Styles.frameSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowFrameSummary)
- {
- EditorGUILayout.BeginVertical(); // To match indenting on the marker summary where a scroll area is present
- if (IsAnalysisValid())
- {
- var frameSummary = m_ProfileSingleView.analysis.GetFrameSummary();
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- m_Columns.Draw(0, "");
- m_Columns.Draw2(Styles.frameCount, GetFrameCountText(m_ProfileSingleView));
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, Styles.frameStart);
- GUIContent firstFrameTextContent = GetFirstFrameText(m_ProfileSingleView);
- m_Columns.Draw(1, firstFrameTextContent);
- if (firstFrameTextContent.text != "")
- DrawFrameIndexButton(frameSummary.first, m_ProfileSingleView);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, Styles.frameEnd);
- GUIContent lastFrameTextContent = GetLastFrameText(m_ProfileSingleView);
- m_Columns.Draw(1, lastFrameTextContent);
- if (lastFrameTextContent.text != "")
- DrawFrameIndexButton(frameSummary.last, m_ProfileSingleView);
- EditorGUILayout.EndHorizontal();
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- m_Columns.Draw(0, "");
- m_Columns.Draw3("", GetDisplayUnits(), "Frame");
- Draw3LabelMsFrame(Styles.max, frameSummary.msMax, frameSummary.maxFrameIndex, m_ProfileSingleView);
- Draw2LabelMs(Styles.upperQuartile, frameSummary.msUpperQuartile);
- Draw3LabelMsFrame(Styles.median, frameSummary.msMedian, frameSummary.medianFrameIndex, m_ProfileSingleView);
- Draw2LabelMs(Styles.mean, frameSummary.msMean);
- Draw2LabelMs(Styles.lowerQuartile, frameSummary.msLowerQuartile);
- Draw3LabelMsFrame(Styles.min, frameSummary.msMin, frameSummary.minFrameIndex, m_ProfileSingleView);
- GUIStyle style = GUI.skin.label;
- GUILayout.Space(style.lineHeight);
- EditorGUILayout.BeginHorizontal();
- Histogram histogram = new Histogram(m_2D, m_DisplayUnits.Units);
- histogram.Draw(LayoutSize.HistogramWidth, 40, frameSummary.buckets, frameSummary.count, 0, frameSummary.msMax, UIColor.bar);
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, m_DisplayUnits.Units);
- float plotWidth = 40 + GUI.skin.box.padding.horizontal;
- float plotHeight = 40;
- boxAndWhiskerPlot.Draw(plotWidth, plotHeight, frameSummary.msMin, frameSummary.msLowerQuartile, frameSummary.msMedian, frameSummary.msUpperQuartile, frameSummary.msMax, 0, frameSummary.msMax, UIColor.standardLine, UIColor.standardLine);
- boxAndWhiskerPlot.DrawText(m_Columns.GetColumnWidth(3), plotHeight, frameSummary.msMin, frameSummary.msMax,
- "Min frame time for selected frames",
- "Max frame time for selected frames");
- EditorGUILayout.EndHorizontal();
- }
- else
- {
- EditorGUILayout.LabelField("No analysis data selected");
- }
- EditorGUILayout.EndVertical();
- }
- if (m_ShowFrameSummary != lastShowFrameSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Frames, analytic.GetDurationInSeconds(), m_ShowFrameSummary);
- }
- EditorGUILayout.EndVertical();
- }
- GUIContent GetThreadNameWithGroupTooltip(string threadNameWithIndex, bool singleThread)
- {
- string friendlyThreadName = GetFriendlyThreadName(threadNameWithIndex, singleThread);
- string groupName;
- friendlyThreadName = ProfileData.GetThreadNameWithoutGroup(friendlyThreadName, out groupName);
- if (groupName == "")
- return new GUIContent(friendlyThreadName, string.Format("{0}", friendlyThreadName));
- else
- return new GUIContent(friendlyThreadName, string.Format("{0}\n{1}", friendlyThreadName, groupName));
- }
- void DrawThreadSummary()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- bool lastShowThreadSummary = m_ShowThreadSummary;
- m_ShowThreadSummary = BoldFoldout(m_ShowThreadSummary, Styles.threadSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowThreadSummary)
- {
- EditorGUILayout.BeginVertical(); // To match indenting on the marker summary where a scroll area is present
- if (IsAnalysisValid())
- {
- float xAxisMin = 0.0f;
- float xAxisMax = GetThreadTimeRange(m_ProfileSingleView.analysis);
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw4("", "", "", "");
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, "Total Count : ");
- m_Columns.Draw(1, m_ProfileSingleView.data.GetThreadCount().ToString());
- EditorGUILayout.EndHorizontal();
- List<string> threadSelection = GetLimitedThreadSelection(m_ThreadNames, m_ThreadSelection);
- int selectedThreads = threadSelection.Count;
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, "Selected : ");
- m_Columns.Draw(1, selectedThreads.ToString());
- EditorGUILayout.EndHorizontal();
- ShowThreadRange();
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2 + LayoutSize.WidthColumn3, 0);
- m_Columns.Draw3("", "Median", "Thread");
- m_ThreadScroll = EditorGUILayout.BeginScrollView(m_ThreadScroll, GUIStyle.none, GUI.skin.verticalScrollbar);
- Rect clipRect = new Rect(m_ThreadScroll.x, m_ThreadScroll.y, m_ThreadsAreaRect.width, m_ThreadsAreaRect.height);
- m_2D.SetClipRect(clipRect);
- for (int i = 0; i < m_ThreadUINames.Count; i++)
- {
- string threadNameWithIndex = m_ThreadNames[i];
- if (!threadNameWithIndex.Contains(":"))
- continue; // Ignore 'All'
- bool include = ProfileAnalyzer.MatchThreadFilter(threadNameWithIndex, m_ThreadSelection.selection);
- if (!include)
- continue;
- ThreadData thread = m_ProfileSingleView.analysis.GetThreadByName(threadNameWithIndex);
- if (thread == null) // May be the 'all' field
- continue;
- bool singleThread = thread.threadsInGroup > 1 ? false : true;
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, m_DisplayUnits.Units);
- EditorGUILayout.BeginHorizontal();
- boxAndWhiskerPlot.DrawHorizontal(100, GUI.skin.label.lineHeight, thread.msMin, thread.msLowerQuartile, thread.msMedian, thread.msUpperQuartile, thread.msMax, xAxisMin, xAxisMax, UIColor.bar, UIColor.barBackground, GUI.skin.label);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(thread.msMedian));
- m_Columns.Draw(2, GetThreadNameWithGroupTooltip(thread.threadNameWithIndex, singleThread));
- EditorGUILayout.EndHorizontal();
- }
- m_2D.ClearClipRect();
- EditorGUILayout.EndScrollView();
- if (Event.current.type == EventType.Repaint)
- {
- // This value is not valid at layout phase
- m_ThreadsAreaRect = GUILayoutUtility.GetLastRect();
- }
- }
- else
- {
- EditorGUILayout.LabelField("No analysis data selected");
- }
- EditorGUILayout.EndVertical();
- }
- if (m_ShowThreadSummary != lastShowThreadSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Threads, analytic.GetDurationInSeconds(), m_ShowThreadSummary);
- }
- EditorGUILayout.EndVertical();
- }
- void DrawHistogramForMarker(Histogram histogram, MarkerData marker)
- {
- if (DisplayCount())
- histogram.Draw(LayoutSize.HistogramWidth, 100, marker.countBuckets, marker.presentOnFrameCount, marker.countMin, marker.countMax, UIColor.bar);
- else
- histogram.Draw(LayoutSize.HistogramWidth, 100, marker.buckets, marker.presentOnFrameCount, marker.msMin, marker.msMax, UIColor.bar);
- }
- internal bool IsProfilerWindowOpen()
- {
- return m_ProfilerWindowInterface.IsReady();
- }
- /// <summary>
- /// Used to remap frame indices when the loaded range in the profiler does not match the range present in the Profile Analyzer capture.
- /// This happens when we reload data into the Profiler Window as the index range becomes 1 -> n+1
- /// </summary>
- /// <param name="frameIndex">target frame index</param>
- /// <param name="frameIndexOffset">capture frameIndex offset</param>
- /// <returns></returns>
- internal int RemapFrameIndex(int frameIndex, int frameIndexOffset)
- {
- if (m_ProfilerFirstFrameIndex == 1 && frameIndex > frameIndexOffset)
- return frameIndex - frameIndexOffset;
- else
- return frameIndex;
- }
- internal void JumpToFrame(int frameIndex, ProfileData frameContext, bool reportErrors = true)
- {
- if (!m_ProfilerWindowInterface.IsReady())
- return;
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- m_ProfilerWindowInterface.JumpToFrame(RemapFrameIndex(frameIndex, frameContext.FrameIndexOffset));
- if (!string.IsNullOrEmpty(m_SelectedMarker.name))
- m_ProfilerWindowInterface.SetProfilerWindowMarkerName(m_SelectedMarker.name, m_ThreadSelection.selection);
- ProfileAnalyzerAnalytics.SendUIButtonEvent(ProfileAnalyzerAnalytics.UIButton.JumpToFrame, analytic);
- }
- internal float DrawFrameIndexButton(int frameIndex, ProfileDataView frameContext)
- {
- float defaultWidth = 50f;
- if (frameIndex < 0)
- return defaultWidth;
- bool enabled = GUI.enabled;
- if (!IsProfilerWindowOpen() || !frameContext.inSyncWithProfilerData)
- GUI.enabled = false;
- var remappedIndex = GetRemappedUIFrameIndex(frameIndex, frameContext);
- var content = new GUIContent(string.Format("{0}", remappedIndex), string.Format("Jump to frame {0} in the Unity Profiler", remappedIndex));
- Vector2 size = GUI.skin.button.CalcSize(content);
- //float height = size.y;
- float maxWidth = Math.Max(defaultWidth, size.x);
- if (GUILayout.Button(content, GUILayout.MinWidth(defaultWidth), GUILayout.MaxWidth(maxWidth)))
- {
- JumpToFrame(frameIndex, frameContext.data);
- }
- GUI.enabled = enabled;
- return maxWidth;
- }
- internal void DrawFrameIndexButton(Rect rect, int frameIndex, ProfileDataView frameContext)
- {
- if (frameIndex < 0)
- return;
- bool enabled = GUI.enabled;
- if (!IsProfilerWindowOpen() || !frameContext.inSyncWithProfilerData)
- GUI.enabled = false;
- // Clamp to max height to match other buttons
- // And centre vertically if needed
- var remappedIndex = GetRemappedUIFrameIndex(frameIndex, frameContext);
- var content = new GUIContent(string.Format("{0}", remappedIndex), string.Format("Jump to frame {0} in the Unity Profiler", remappedIndex));
- Vector2 size = GUI.skin.button.CalcSize(content);
- float height = size.y; // was 14
- rect.y += (rect.height - height) / 2;
- rect.height = Math.Min(rect.height, height);
- if (GUI.Button(rect, content))
- {
- JumpToFrame(frameIndex, frameContext.data);
- }
- GUI.enabled = enabled;
- }
- void Draw3LabelMsFrame(GUIContent col1, float ms, int frameIndex, ProfileDataView frameContext)
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, col1);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(ms));
- DrawFrameIndexButton(frameIndex, frameContext);
- EditorGUILayout.EndHorizontal();
- }
- void Draw2LabelMs(GUIContent col1, float ms)
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, col1);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(ms));
- EditorGUILayout.EndHorizontal();
- }
- void Draw4DiffMs(GUIContent col1, float msLeft, float msRight)
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, col1);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(msLeft));
- m_Columns.Draw(2, ToDisplayUnitsWithTooltips(msRight));
- m_Columns.Draw(3, ToDisplayUnitsWithTooltips(msRight - msLeft));
- EditorGUILayout.EndHorizontal();
- }
- void Draw4DiffMs(GUIContent col1, float msLeft, int frameIndexLeft, float msRight, int frameIndexRight)
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, col1);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(msLeft, false, frameIndexLeft));
- m_Columns.Draw(2, ToDisplayUnitsWithTooltips(msRight, false, frameIndexRight));
- m_Columns.Draw(3, ToDisplayUnitsWithTooltips(msRight - msLeft));
- EditorGUILayout.EndHorizontal();
- }
- void Draw4Ms(GUIContent col1, float value2, float value3, float value4)
- {
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, col1);
- m_Columns.Draw(1, ToDisplayUnitsWithTooltips(value2));
- m_Columns.Draw(2, ToDisplayUnitsWithTooltips(value3));
- m_Columns.Draw(3, ToDisplayUnitsWithTooltips(value4));
- EditorGUILayout.EndHorizontal();
- }
- void DrawBoxAndWhiskerPlotForMarker(BoxAndWhiskerPlot boxAndWhiskerPlot, float width, float height, ProfileAnalysis analysis, MarkerData marker, float yAxisStart, float yAxisEnd, Color color, Color colorBackground)
- {
- if (marker == null)
- {
- boxAndWhiskerPlot.Draw(width, height, 0, 0, 0, 0, 0, yAxisStart, yAxisEnd, color, colorBackground);
- return;
- }
- if (DisplayCount())
- boxAndWhiskerPlot.Draw(width, height, marker.countMin, marker.countLowerQuartile, marker.countMedian, marker.countUpperQuartile, marker.countMax, yAxisStart, yAxisEnd, color, colorBackground);
- else
- boxAndWhiskerPlot.Draw(width, height, marker.msMin, marker.msLowerQuartile, marker.msMedian, marker.msUpperQuartile, marker.msMax, yAxisStart, yAxisEnd, color, colorBackground);
- }
- void DrawBoxAndWhiskerPlotHorizontalForMarker(BoxAndWhiskerPlot boxAndWhiskerPlot, float width, float height, ProfileAnalysis analysis, MarkerData marker, float yAxisStart, float yAxisEnd, Color color, Color colorBackground)
- {
- boxAndWhiskerPlot.DrawHorizontal(width, height, marker.msMin, marker.msLowerQuartile, marker.msMedian, marker.msUpperQuartile, marker.msMax, yAxisStart, yAxisEnd, color, colorBackground);
- }
- void DrawFrameRatio(MarkerData marker)
- {
- var frameSummary = m_ProfileSingleView.analysis.GetFrameSummary();
- GUIStyle style = GUI.skin.label;
- float w = LayoutSize.WidthColumn0;
- float h = style.lineHeight;
- float ySpacing = 2;
- float barHeight = h - ySpacing;
- EditorGUILayout.BeginVertical(GUILayout.Width(w + LayoutSize.WidthColumn1 + LayoutSize.WidthColumn2));
- float barMax = frameSummary.msMean;
- float barValue = marker.msMean;
- string text = "Mean frame contribution";
- Units units = m_DisplayUnits.Units;
- if (DisplayCount())
- {
- units = Units.Count;
- barMax = frameSummary.markerCountMaxMean;
- barValue = marker.countMean;
- text = "Mean count";
- }
- DisplayUnits displayUnits = new DisplayUnits(units);
- float barLength = Math.Min((w * barValue) / barMax, w);
- EditorGUILayout.LabelField(text);
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- m_Columns.Draw2("", "");
- EditorGUILayout.BeginHorizontal();
- // NOTE: This can effect the whole width of the region its inside
- // Not clear why
- if (m_2D.DrawStart(w, h, Draw2D.Origin.TopLeft, style))
- {
- m_2D.DrawFilledBox(0, ySpacing, barLength, barHeight, UIColor.bar);
- m_2D.DrawFilledBox(barLength, ySpacing, w - barLength, barHeight, UIColor.barBackground);
- m_2D.DrawEnd();
- Rect rect = GUILayoutUtility.GetLastRect();
- string tooltip = string.Format("{0}", displayUnits.ToString(barValue, true, 5));
- GUI.Label(rect, new GUIContent("", tooltip));
- }
- EditorGUILayout.LabelField(ShowPercent((100 * barValue) / barMax), GUILayout.MaxWidth(50));
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.EndVertical();
- }
- GUIContent ShowPercent(float percent)
- {
- string text;
- string tooltip;
- if (percent >= 999.95f)
- {
- text = string.Format("{0:f0}%", percent);
- tooltip = string.Format("{0:f2}%", percent);
- }
- else if (percent >= 99.995f)
- {
- text = string.Format("{0:f1}%", percent);
- tooltip = string.Format("{0:f2}%", percent);
- }
- else
- {
- text = string.Format("{0:f2}%", percent);
- tooltip = text;
- }
- return new GUIContent(text, tooltip);
- }
- void DrawComparisonFrameRatio(MarkerData leftMarker, MarkerData rightMarker)
- {
- var leftFrameSummary = m_ProfileLeftView.analysis.GetFrameSummary();
- var rightFrameSummary = m_ProfileRightView.analysis.GetFrameSummary();
- GUIStyle style = GUI.skin.label;
- float w = LayoutSize.WidthColumn0;
- float h = style.lineHeight;
- float ySpacing = 2;
- float barHeight = (h - ySpacing) / 2;
- EditorGUILayout.BeginVertical(GUILayout.Width(w + LayoutSize.WidthColumn1 + LayoutSize.WidthColumn2));
- float leftBarValue = MarkerData.GetMsMean(leftMarker);
- float rightBarValue = MarkerData.GetMsMean(rightMarker);
- float leftBarMax = leftFrameSummary.msMean;
- float rightBarMax = rightFrameSummary.msMean;
- string text = "Mean frame contribution";
- Units units = m_DisplayUnits.Units;
- if (DisplayCount())
- {
- units = Units.Count;
- leftBarValue = MarkerData.GetCountMean(leftMarker);
- rightBarValue = MarkerData.GetCountMean(rightMarker);
- leftBarMax = leftFrameSummary.markerCountMaxMean;
- rightBarMax = rightFrameSummary.markerCountMaxMean;
- text = "Mean count";
- }
- DisplayUnits displayUnits = new DisplayUnits(units);
- float leftBarLength = (leftBarMax > 0) ? (w * leftBarValue) / leftBarMax : 0f;
- leftBarLength = Math.Min(leftBarLength, w);
- float rightBarLength = (rightBarMax > 0) ? (w * rightBarValue) / rightBarMax : 0f;
- rightBarLength = Math.Min(rightBarLength, w);
- EditorGUILayout.LabelField(text);
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- m_Columns.Draw4("", "Left", "Right", "Diff");
- EditorGUILayout.BeginHorizontal();
- if (m_2D.DrawStart(w, h, Draw2D.Origin.TopLeft, style))
- {
- m_2D.DrawFilledBox(0, ySpacing, w, h - ySpacing, UIColor.barBackground);
- m_2D.DrawFilledBox(0, ySpacing, leftBarLength, barHeight, UIColor.left);
- m_2D.DrawFilledBox(0, ySpacing + barHeight, rightBarLength, barHeight, UIColor.right);
- m_2D.DrawEnd();
- Rect rect = GUILayoutUtility.GetLastRect();
- string tooltip = string.Format("Left: {0}\nRight: {1}", displayUnits.ToTooltipString(leftBarValue, true), displayUnits.ToTooltipString(rightBarValue, true));
- GUI.Label(rect, new GUIContent("", tooltip));
- }
- float leftPercentage = leftBarMax > 0 ? (100 * leftBarValue) / leftBarMax : 0f;
- float rightPercentage = rightBarMax > 0 ? (100 * rightBarValue) / rightBarMax : 0f;
- EditorGUILayout.LabelField(ShowPercent(leftPercentage), GUILayout.Width(LayoutSize.WidthColumn1));
- EditorGUILayout.LabelField(ShowPercent(rightPercentage), GUILayout.Width(LayoutSize.WidthColumn2));
- if (leftMarker != null && rightMarker != null)
- EditorGUILayout.LabelField(ShowPercent(rightPercentage - leftPercentage), GUILayout.Width(LayoutSize.WidthColumn3));
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.EndVertical();
- }
- void DrawTopComparison(MarkerData leftMarker, MarkerData rightMarker)
- {
- GUIStyle style = GUI.skin.label;
- float w = LayoutSize.WidthColumn0;
- float h = style.lineHeight;
- float ySpacing = 2;
- float barHeight = (h - ySpacing) / 2;
- EditorGUILayout.BeginVertical(GUILayout.Width(w + LayoutSize.WidthColumn1 + LayoutSize.WidthColumn2));
- bool showCount = DisplayCount();
- float leftMax = MarkerData.GetMsMax(leftMarker);
- float rightMax = MarkerData.GetMsMax(rightMarker);
- Units units = m_DisplayUnits.Units;
- if (showCount)
- {
- units = Units.Count;
- leftMax = MarkerData.GetCountMax(leftMarker);
- rightMax = MarkerData.GetCountMax(rightMarker);
- }
- DisplayUnits displayUnits = new DisplayUnits(units);
- TopMarkerList topMarkerList = new TopMarkerList(m_2D, units,
- LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3,
- UIColor.bar, UIColor.barBackground, DrawFrameIndexButton);
- m_TopNumber = topMarkerList.DrawTopNumber(m_TopNumber, m_TopStrings, m_TopValues);
- float barMax = Math.Max(leftMax, rightMax);
- List<FrameTime> leftFrames = leftMarker != null ? topMarkerList.GetTopN(leftMarker, m_TopNumber, showCount) : new List<FrameTime>();
- List<FrameTime> rightFrames = rightMarker != null ? topMarkerList.GetTopN(rightMarker, m_TopNumber, showCount) : new List<FrameTime>();
- FrameTime zeroFrameTime = new FrameTime(-1, 0.0f, 0);
- for (int i = 0; i < m_TopNumber; i++)
- {
- bool leftValid = i < leftFrames.Count;
- bool rightValid = i < rightFrames.Count;
- FrameTime leftFrameTime = leftValid ? leftFrames[i] : zeroFrameTime;
- FrameTime rightFrameTime = rightValid ? rightFrames[i] : zeroFrameTime;
- float leftBarValue = showCount ? leftFrameTime.count : leftFrameTime.ms;
- float rightBarValue = showCount ? rightFrameTime.count : rightFrameTime.ms;
- float leftBarLength = Math.Min((w * leftBarValue) / barMax, w);
- float rightBarLength = Math.Min((w * rightBarValue) / barMax, w);
- EditorGUILayout.BeginHorizontal();
- if (m_2D.DrawStart(w, h, Draw2D.Origin.TopLeft, style))
- {
- if (leftValid || rightValid)
- {
- m_2D.DrawFilledBox(0, ySpacing, w, h - ySpacing, UIColor.barBackground);
- m_2D.DrawFilledBox(0, ySpacing, leftBarLength, barHeight, UIColor.left);
- m_2D.DrawFilledBox(0, ySpacing + barHeight, rightBarLength, barHeight, UIColor.right);
- }
- m_2D.DrawEnd();
- Rect rect = GUILayoutUtility.GetLastRect();
- string leftContent = leftValid ? displayUnits.ToTooltipString(leftBarValue, true, leftFrameTime.frameIndex) : "None";
- string rightContent = rightValid ? displayUnits.ToTooltipString(rightBarValue, true, rightFrameTime.frameIndex) : "None";
- GUI.Label(rect, new GUIContent("", string.Format("Left:\t{0}\nRight:\t{1}", leftContent, rightContent)));
- }
- EditorGUILayout.LabelField(leftValid ? displayUnits.ToGUIContentWithTooltips(leftBarValue, frameIndex: leftFrameTime.frameIndex) : Styles.emptyString, GUILayout.Width(LayoutSize.WidthColumn1));
- EditorGUILayout.LabelField(rightValid ? displayUnits.ToGUIContentWithTooltips(rightBarValue, frameIndex: rightFrameTime.frameIndex) : Styles.emptyString, GUILayout.Width(LayoutSize.WidthColumn2));
- if (leftValid || rightValid)
- EditorGUILayout.LabelField(displayUnits.ToGUIContentWithTooltips(rightBarValue - leftBarValue), GUILayout.Width(LayoutSize.WidthColumn3));
- EditorGUILayout.EndHorizontal();
- }
- EditorGUILayout.EndVertical();
- }
- void DrawSelectedStats(MarkerData marker, ProfileDataView markerContext)
- {
- GUIStyle style = GUI.skin.label;
- m_Columns.Draw3("", GetDisplayUnits(), "Frame");
- Draw3LabelMsFrame(Styles.max, marker.msMax, marker.maxFrameIndex, markerContext);
- Draw2LabelMs(Styles.upperQuartile, marker.msUpperQuartile);
- Draw3LabelMsFrame(Styles.median, marker.msMedian, marker.medianFrameIndex, markerContext);
- Draw2LabelMs(Styles.mean, marker.msMean);
- Draw2LabelMs(Styles.lowerQuartile, marker.msLowerQuartile);
- Draw3LabelMsFrame(Styles.min, marker.msMin, marker.minFrameIndex, markerContext);
- GUILayout.Space(style.lineHeight);
- Draw3LabelMsFrame(Styles.individualMax, marker.msMaxIndividual,
- marker.maxIndividualFrameIndex, markerContext);
- Draw3LabelMsFrame(Styles.individualMin, marker.msMinIndividual,
- marker.minIndividualFrameIndex, markerContext);
- }
- void DrawSelected()
- {
- EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.WidthRHS));
- bool lastMarkerSummary = m_ShowMarkerSummary;
- m_ShowMarkerSummary = BoldFoldout(m_ShowMarkerSummary, Styles.markerSummary);
- var analytic = ProfileAnalyzerAnalytics.BeginAnalytic();
- if (m_ShowMarkerSummary)
- {
- if (IsAnalysisValid())
- {
- List<MarkerData> markers = m_ProfileSingleView.analysis.GetMarkers();
- if (markers != null)
- {
- int markerAt = m_SelectedMarker.id;
- if (markerAt >= 0 && markerAt < markers.Count)
- {
- var marker = markers[markerAt];
- m_MarkerSummaryScroll = GUILayout.BeginScrollView(m_MarkerSummaryScroll, GUIStyle.none, GUI.skin.verticalScrollbar);
- Rect clipRect = new Rect(m_MarkerSummaryScroll.x, m_MarkerSummaryScroll.y, LayoutSize.WidthRHS, 500);
- m_2D.SetClipRect(clipRect);
- EditorGUILayout.BeginVertical();
- EditorGUILayout.LabelField(marker.name,
- GUILayout.MaxWidth(LayoutSize.WidthRHS -
- (GUI.skin.box.padding.horizontal + GUI.skin.box.margin.horizontal)));
- DrawFrameRatio(marker);
- m_Columns.SetColumnSizes(LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3);
- EditorGUILayout.BeginHorizontal();
- m_Columns.Draw(0, Styles.firstFrame);
- m_Columns.Draw(1, Styles.emptyString);
- DrawFrameIndexButton(marker.firstFrameIndex, m_ProfileSingleView);
- EditorGUILayout.EndHorizontal();
- GUIStyle style = GUI.skin.label;
- float min = marker.msMin;
- float max = marker.msMax;
- string fieldString = "marker time";
- Units units = m_DisplayUnits.Units;
- if (DisplayCount())
- {
- min = marker.countMin;
- max = marker.countMax;
- fieldString = "count";
- units = Units.Count;
- }
- TopMarkerList topMarkerList = new TopMarkerList(m_2D, units,
- LayoutSize.WidthColumn0, LayoutSize.WidthColumn1, LayoutSize.WidthColumn2, LayoutSize.WidthColumn3,
- UIColor.bar, UIColor.barBackground, DrawFrameIndexButton);
- m_TopNumber = topMarkerList.Draw(marker, m_ProfileSingleView, m_TopNumber, m_TopStrings, m_TopValues);
- GUILayout.Space(style.lineHeight);
- float plotWidth = 40 + GUI.skin.box.padding.horizontal;
- float plotHeight = 100;
- EditorGUILayout.BeginHorizontal();
- Histogram histogram = new Histogram(m_2D, units);
- DrawHistogramForMarker(histogram, marker);
- BoxAndWhiskerPlot boxAndWhiskerPlot = new BoxAndWhiskerPlot(m_2D, units);
- DrawBoxAndWhiskerPlotForMarker(boxAndWhiskerPlot, plotWidth, plotHeight, m_ProfileSingleView.analysis, marker,
- min, max, UIColor.standardLine, UIColor.boxAndWhiskerBoxColor);
- boxAndWhiskerPlot.DrawText(m_Columns.GetColumnWidth(3), plotHeight, min, max,
- string.Format("Min {0} for selected frames", fieldString),
- string.Format("Max {0} for selected frames", fieldString));
- EditorGUILayout.EndHorizontal();
- GUILayout.Space(style.lineHeight);
- DrawSelectedStats(marker, m_ProfileSingleView);
- EditorGUILayout.EndVertical();
- m_2D.ClearClipRect();
- GUILayout.EndScrollView();
- }
- else
- {
- EditorGUILayout.LabelField("Marker not in selection");
- }
- }
- }
- else
- {
- EditorGUILayout.LabelField("No marker data selected");
- }
- }
- if (m_ShowMarkerSummary != lastMarkerSummary)
- {
- ProfileAnalyzerAnalytics.SendUIVisibilityEvent(ProfileAnalyzerAnalytics.UIVisibility.Markers, analytic.GetDurationInSeconds(), m_ShowMarkerSummary);
- }
- EditorGUILayout.EndVertical();
- }
- internal static bool FileInTempDir(string filePath)
- {
- return Directory.Exists(TmpDir) && Directory.GetFiles(TmpDir).Contains(filePath);
- }
- }
- }
|