OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2015 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2015 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/range_utils.html"> | 8 <link rel="import" href="/tracing/base/range_utils.html"> |
9 <link rel="import" href="/tracing/extras/chrome/cc/input_latency_async_slice.htm
l"> | 9 <link rel="import" href="/tracing/extras/chrome/cc/input_latency_async_slice.htm
l"> |
10 <link rel="import" href="/tracing/importer/proto_expectation.html"> | 10 <link rel="import" href="/tracing/importer/proto_expectation.html"> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 var MOUSE_WHEEL_THRESHOLD_MS = 40; | 94 var MOUSE_WHEEL_THRESHOLD_MS = 40; |
95 | 95 |
96 /** | 96 /** |
97 * If two MouseMoves are more than this far apart, then they're two Responses, | 97 * If two MouseMoves are more than this far apart, then they're two Responses, |
98 * not Animation. | 98 * not Animation. |
99 */ | 99 */ |
100 var MOUSE_MOVE_THRESHOLD_MS = 40; | 100 var MOUSE_MOVE_THRESHOLD_MS = 40; |
101 | 101 |
102 // TODO(benjhayden) Find a better home for this. | 102 // TODO(benjhayden) Find a better home for this. |
103 function compareEvents(x, y) { | 103 function compareEvents(x, y) { |
104 if (x.start !== y.start) | 104 if (x.start !== y.start) { |
105 return x.start - y.start; | 105 return x.start - y.start; |
106 if (x.end !== y.end) | 106 } |
| 107 if (x.end !== y.end) { |
107 return x.end - y.end; | 108 return x.end - y.end; |
108 if (x.guid && y.guid) | 109 } |
| 110 if (x.guid && y.guid) { |
109 return x.guid - y.guid; | 111 return x.guid - y.guid; |
| 112 } |
110 return 0; | 113 return 0; |
111 } | 114 } |
112 | 115 |
113 function forEventTypesIn(events, typeNames, cb, opt_this) { | 116 function forEventTypesIn(events, typeNames, cb, opt_this) { |
114 events.forEach(function(event) { | 117 events.forEach(function(event) { |
115 if (typeNames.indexOf(event.typeName) >= 0) { | 118 if (typeNames.indexOf(event.typeName) >= 0) { |
116 cb.call(opt_this, event); | 119 cb.call(opt_this, event); |
117 } | 120 } |
118 }); | 121 }); |
119 } | 122 } |
(...skipping 13 matching lines...) Expand all Loading... |
133 return frameEventsByPid; | 136 return frameEventsByPid; |
134 } | 137 } |
135 | 138 |
136 function getSortedInputEvents(modelHelper) { | 139 function getSortedInputEvents(modelHelper) { |
137 var inputEvents = []; | 140 var inputEvents = []; |
138 | 141 |
139 var browserProcess = modelHelper.browserHelper.process; | 142 var browserProcess = modelHelper.browserHelper.process; |
140 var mainThread = browserProcess.findAtMostOneThreadNamed( | 143 var mainThread = browserProcess.findAtMostOneThreadNamed( |
141 'CrBrowserMain'); | 144 'CrBrowserMain'); |
142 for (var slice of mainThread.asyncSliceGroup.getDescendantEvents()) { | 145 for (var slice of mainThread.asyncSliceGroup.getDescendantEvents()) { |
143 if (!slice.isTopLevel) | 146 if (!slice.isTopLevel) continue; |
144 continue; | |
145 | 147 |
146 if (!(slice instanceof tr.e.cc.InputLatencyAsyncSlice)) | 148 if (!(slice instanceof tr.e.cc.InputLatencyAsyncSlice)) continue; |
147 continue; | |
148 | 149 |
149 // TODO(beaudoin): This should never happen but it does. Investigate | 150 // TODO(beaudoin): This should never happen but it does. Investigate |
150 // the trace linked at in #1567 and remove that when it's fixed. | 151 // the trace linked at in #1567 and remove that when it's fixed. |
151 if (isNaN(slice.start) || | 152 if (isNaN(slice.start) || |
152 isNaN(slice.duration) || | 153 isNaN(slice.duration) || |
153 isNaN(slice.end)) | 154 isNaN(slice.end)) { |
154 continue; | 155 continue; |
| 156 } |
155 | 157 |
156 inputEvents.push(slice); | 158 inputEvents.push(slice); |
157 } | 159 } |
158 | 160 |
159 return inputEvents.sort(compareEvents); | 161 return inputEvents.sort(compareEvents); |
160 } | 162 } |
161 | 163 |
162 function findProtoExpectations(modelHelper, sortedInputEvents) { | 164 function findProtoExpectations(modelHelper, sortedInputEvents) { |
163 var protoExpectations = []; | 165 var protoExpectations = []; |
164 // This order is not important. Handlers are independent. | 166 // This order is not important. Handlers are independent. |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 pe.pushEvent(event); | 342 pe.pushEvent(event); |
341 protoExpectations.push(pe); | 343 protoExpectations.push(pe); |
342 break; | 344 break; |
343 } | 345 } |
344 | 346 |
345 if (currentPE) { | 347 if (currentPE) { |
346 currentPE.pushEvent(event); | 348 currentPE.pushEvent(event); |
347 } else { | 349 } else { |
348 currentPE = new ProtoExpectation( | 350 currentPE = new ProtoExpectation( |
349 ProtoExpectation.RESPONSE_TYPE, INITIATOR_TYPE.MOUSE); | 351 ProtoExpectation.RESPONSE_TYPE, INITIATOR_TYPE.MOUSE); |
350 if (mouseDownEvent) | 352 if (mouseDownEvent) { |
351 currentPE.associatedEvents.push(mouseDownEvent); | 353 currentPE.associatedEvents.push(mouseDownEvent); |
| 354 } |
352 currentPE.pushEvent(event); | 355 currentPE.pushEvent(event); |
353 protoExpectations.push(currentPE); | 356 protoExpectations.push(currentPE); |
354 } | 357 } |
355 mouseDownEvent = undefined; | 358 mouseDownEvent = undefined; |
356 currentPE = undefined; | 359 currentPE = undefined; |
357 break; | 360 break; |
358 } | 361 } |
359 }); | 362 }); |
360 if (mouseDownEvent) { | 363 if (mouseDownEvent) { |
361 currentPE = new ProtoExpectation(ProtoExpectation.IGNORED_TYPE); | 364 currentPE = new ProtoExpectation(ProtoExpectation.IGNORED_TYPE); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 var pe = new ProtoExpectation(ProtoExpectation.IGNORED_TYPE); | 579 var pe = new ProtoExpectation(ProtoExpectation.IGNORED_TYPE); |
577 pe.pushEvent(event); | 580 pe.pushEvent(event); |
578 protoExpectations.push(pe); | 581 protoExpectations.push(pe); |
579 } | 582 } |
580 break; | 583 break; |
581 } | 584 } |
582 }); | 585 }); |
583 // If there was neither a FLING_CANCEL nor a renderer fling after the | 586 // If there was neither a FLING_CANCEL nor a renderer fling after the |
584 // FLING_START, then assume that it ends at the end of the model, so set | 587 // FLING_START, then assume that it ends at the end of the model, so set |
585 // the end of currentPE to the end of the model. | 588 // the end of currentPE to the end of the model. |
586 if (currentPE && !currentPE.end) | 589 if (currentPE && !currentPE.end) { |
587 currentPE.end = modelHelper.model.bounds.max; | 590 currentPE.end = modelHelper.model.bounds.max; |
| 591 } |
588 return protoExpectations; | 592 return protoExpectations; |
589 } | 593 } |
590 | 594 |
591 /** | 595 /** |
592 * The TouchStart and the first TouchMove comprise a Response, then the | 596 * The TouchStart and the first TouchMove comprise a Response, then the |
593 * rest of the TouchMoves comprise an Animation. | 597 * rest of the TouchMoves comprise an Animation. |
594 * | 598 * |
595 * RRRRRRRAAAAAAAAAAAAAAAAAAAA | 599 * RRRRRRRAAAAAAAAAAAAAAAAAAAA |
596 * SSS MMM MMM MMM MMM MMM EEE | 600 * SSS MMM MMM MMM MMM MMM EEE |
597 * | 601 * |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 * VideoPlayback async events (going from the VideoFrameCompositor::Start | 752 * VideoPlayback async events (going from the VideoFrameCompositor::Start |
749 * to VideoFrameCompositor::Stop calls) | 753 * to VideoFrameCompositor::Stop calls) |
750 */ | 754 */ |
751 function handleVideoAnimations(modelHelper, sortedInputEvents) { | 755 function handleVideoAnimations(modelHelper, sortedInputEvents) { |
752 var events = []; | 756 var events = []; |
753 for (var pid in modelHelper.rendererHelpers) { | 757 for (var pid in modelHelper.rendererHelpers) { |
754 for (var tid in modelHelper.rendererHelpers[pid].process.threads) { | 758 for (var tid in modelHelper.rendererHelpers[pid].process.threads) { |
755 for (var asyncSlice of | 759 for (var asyncSlice of |
756 modelHelper.rendererHelpers[pid].process.threads[tid] | 760 modelHelper.rendererHelpers[pid].process.threads[tid] |
757 .asyncSliceGroup.slices) { | 761 .asyncSliceGroup.slices) { |
758 if (asyncSlice.title === PLAYBACK_EVENT_TITLE) | 762 if (asyncSlice.title === PLAYBACK_EVENT_TITLE) { |
759 events.push(asyncSlice); | 763 events.push(asyncSlice); |
| 764 } |
760 } | 765 } |
761 } | 766 } |
762 } | 767 } |
763 | 768 |
764 events.sort(tr.importer.compareEvents); | 769 events.sort(tr.importer.compareEvents); |
765 | 770 |
766 var protoExpectations = []; | 771 var protoExpectations = []; |
767 for (var event of events) { | 772 for (var event of events) { |
768 var currentPE = new ProtoExpectation( | 773 var currentPE = new ProtoExpectation( |
769 ProtoExpectation.ANIMATION_TYPE, INITIATOR_TYPE.VIDEO); | 774 ProtoExpectation.ANIMATION_TYPE, INITIATOR_TYPE.VIDEO); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 start = modelHelper.model.bounds.min; | 834 start = modelHelper.model.bounds.min; |
830 } | 835 } |
831 | 836 |
832 pushAnimationRange(start, sub.start, animation); | 837 pushAnimationRange(start, sub.start, animation); |
833 start = undefined; | 838 start = undefined; |
834 } | 839 } |
835 }); | 840 }); |
836 | 841 |
837 // An animation was still running when the | 842 // An animation was still running when the |
838 // top-level animation event ended. | 843 // top-level animation event ended. |
839 if (start !== undefined) | 844 if (start !== undefined) { |
840 pushAnimationRange(start, animation.end, animation); | 845 pushAnimationRange(start, animation.end, animation); |
| 846 } |
841 } | 847 } |
842 }); | 848 }); |
843 | 849 |
844 // Now we have a set of time ranges when css animations were actually | 850 // Now we have a set of time ranges when css animations were actually |
845 // running. | 851 // running. |
846 // Leave merging intersecting animations to mergeIntersectingAnimations(), | 852 // Leave merging intersecting animations to mergeIntersectingAnimations(), |
847 // after findFrameEventsForAnimations removes frame-less animations. | 853 // after findFrameEventsForAnimations removes frame-less animations. |
848 | 854 |
849 return animationRanges.map(function(range) { | 855 return animationRanges.map(function(range) { |
850 var protoExpectation = new ProtoExpectation( | 856 var protoExpectation = new ProtoExpectation( |
851 ProtoExpectation.ANIMATION_TYPE, INITIATOR_TYPE.CSS); | 857 ProtoExpectation.ANIMATION_TYPE, INITIATOR_TYPE.CSS); |
852 protoExpectation.start = range.min; | 858 protoExpectation.start = range.min; |
853 protoExpectation.end = range.max; | 859 protoExpectation.end = range.max; |
854 protoExpectation.associatedEvents.push(range.animation); | 860 protoExpectation.associatedEvents.push(range.animation); |
855 return protoExpectation; | 861 return protoExpectation; |
856 }); | 862 }); |
857 } | 863 } |
858 | 864 |
859 /** | 865 /** |
860 * Get all the events (prepareMailbox and serviceScriptedAnimations) | 866 * Get all the events (prepareMailbox and serviceScriptedAnimations) |
861 * relevant to WebGL. Note that modelHelper is the helper object containing | 867 * relevant to WebGL. Note that modelHelper is the helper object containing |
862 * the model, and mailboxEvents and animationEvents are arrays where the | 868 * the model, and mailboxEvents and animationEvents are arrays where the |
863 * events are being pushed into (DrawingBuffer::prepareMailbox events go | 869 * events are being pushed into (DrawingBuffer::prepareMailbox events go |
864 * into mailboxEvents; PageAnimator::serviceScriptedAnimations events go | 870 * into mailboxEvents; PageAnimator::serviceScriptedAnimations events go |
865 * into animationEvents). The function does not return anything but | 871 * into animationEvents). The function does not return anything but |
866 * modifies mailboxEvents and animationEvents. | 872 * modifies mailboxEvents and animationEvents. |
867 */ | 873 */ |
868 function findWebGLEvents(modelHelper, mailboxEvents, animationEvents) { | 874 function findWebGLEvents(modelHelper, mailboxEvents, animationEvents) { |
869 for (var event of modelHelper.model.getDescendantEvents()) { | 875 for (var event of modelHelper.model.getDescendantEvents()) { |
870 if (event.title === 'DrawingBuffer::prepareMailbox') | 876 if (event.title === 'DrawingBuffer::prepareMailbox') { |
871 mailboxEvents.push(event); | 877 mailboxEvents.push(event); |
872 else if (event.title === 'PageAnimator::serviceScriptedAnimations') | 878 } else if (event.title === 'PageAnimator::serviceScriptedAnimations') { |
873 animationEvents.push(event); | 879 animationEvents.push(event); |
| 880 } |
874 } | 881 } |
875 } | 882 } |
876 | 883 |
877 /** | 884 /** |
878 * Returns a list of events in mailboxEvents that have an event in | 885 * Returns a list of events in mailboxEvents that have an event in |
879 * animationEvents close by (within ANIMATION_MERGE_THRESHOLD_MS). | 886 * animationEvents close by (within ANIMATION_MERGE_THRESHOLD_MS). |
880 */ | 887 */ |
881 function findMailboxEventsNearAnimationEvents( | 888 function findMailboxEventsNearAnimationEvents( |
882 mailboxEvents, animationEvents) { | 889 mailboxEvents, animationEvents) { |
883 if (animationEvents.length === 0) | 890 if (animationEvents.length === 0) return []; |
884 return []; | |
885 | 891 |
886 mailboxEvents.sort(compareEvents); | 892 mailboxEvents.sort(compareEvents); |
887 animationEvents.sort(compareEvents); | 893 animationEvents.sort(compareEvents); |
888 var animationIterator = animationEvents[Symbol.iterator](); | 894 var animationIterator = animationEvents[Symbol.iterator](); |
889 var animationEvent = animationIterator.next().value; | 895 var animationEvent = animationIterator.next().value; |
890 | 896 |
891 var filteredEvents = []; | 897 var filteredEvents = []; |
892 | 898 |
893 // We iterate through the mailboxEvents. With each event, we check if | 899 // We iterate through the mailboxEvents. With each event, we check if |
894 // there is a animationEvent near it, and if so, add it to the result. | 900 // there is a animationEvent near it, and if so, add it to the result. |
895 for (var event of mailboxEvents) { | 901 for (var event of mailboxEvents) { |
896 // If the current animationEvent is too far before the mailboxEvent, | 902 // If the current animationEvent is too far before the mailboxEvent, |
897 // we advance until we get to the next animationEvent that is not too | 903 // we advance until we get to the next animationEvent that is not too |
898 // far before the animationEvent. | 904 // far before the animationEvent. |
899 while (animationEvent && | 905 while (animationEvent && |
900 (animationEvent.start < ( | 906 (animationEvent.start < ( |
901 event.start - ANIMATION_MERGE_THRESHOLD_MS))) | 907 event.start - ANIMATION_MERGE_THRESHOLD_MS))) { |
902 animationEvent = animationIterator.next().value; | 908 animationEvent = animationIterator.next().value; |
| 909 } |
903 | 910 |
904 // If there aren't any more animationEvents, then that means all the | 911 // If there aren't any more animationEvents, then that means all the |
905 // remaining mailboxEvents are too far after the animationEvents, so | 912 // remaining mailboxEvents are too far after the animationEvents, so |
906 // we can quit now. | 913 // we can quit now. |
907 if (!animationEvent) | 914 if (!animationEvent) break; |
908 break; | |
909 | 915 |
910 // If there's a animationEvent close to the mailboxEvent, then we push | 916 // If there's a animationEvent close to the mailboxEvent, then we push |
911 // the current mailboxEvent onto the stack. | 917 // the current mailboxEvent onto the stack. |
912 if (animationEvent.start < (event.start + ANIMATION_MERGE_THRESHOLD_MS)) | 918 if (animationEvent.start < (event.start + ANIMATION_MERGE_THRESHOLD_MS)) { |
913 filteredEvents.push(event); | 919 filteredEvents.push(event); |
| 920 } |
914 } | 921 } |
915 return filteredEvents; | 922 return filteredEvents; |
916 } | 923 } |
917 | 924 |
918 /** | 925 /** |
919 * Merge consecutive mailbox events into a ProtoExpectation. Note: Only | 926 * Merge consecutive mailbox events into a ProtoExpectation. Note: Only |
920 * the drawingBuffer::prepareMailbox events will end up in the | 927 * the drawingBuffer::prepareMailbox events will end up in the |
921 * associatedEvents. The PageAnimator::serviceScriptedAnimations events | 928 * associatedEvents. The PageAnimator::serviceScriptedAnimations events |
922 * will not end up in the associatedEvents. | 929 * will not end up in the associatedEvents. |
923 */ | 930 */ |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 * protoExpectations is input only. | 987 * protoExpectations is input only. |
981 * Returns a modified set of ProtoExpectations. | 988 * Returns a modified set of ProtoExpectations. |
982 */ | 989 */ |
983 function mergeIntersectingResponses(protoExpectations) { | 990 function mergeIntersectingResponses(protoExpectations) { |
984 var newPEs = []; | 991 var newPEs = []; |
985 while (protoExpectations.length) { | 992 while (protoExpectations.length) { |
986 var pe = protoExpectations.shift(); | 993 var pe = protoExpectations.shift(); |
987 newPEs.push(pe); | 994 newPEs.push(pe); |
988 | 995 |
989 // Only consider Responses for now. | 996 // Only consider Responses for now. |
990 if (pe.type !== ProtoExpectation.RESPONSE_TYPE) | 997 if (pe.type !== ProtoExpectation.RESPONSE_TYPE) continue; |
991 continue; | |
992 | 998 |
993 for (var i = 0; i < protoExpectations.length; ++i) { | 999 for (var i = 0; i < protoExpectations.length; ++i) { |
994 var otherPE = protoExpectations[i]; | 1000 var otherPE = protoExpectations[i]; |
995 | 1001 |
996 if (otherPE.type !== pe.type) | 1002 if (otherPE.type !== pe.type) continue; |
997 continue; | |
998 | 1003 |
999 if (!otherPE.intersects(pe)) | 1004 if (!otherPE.intersects(pe)) continue; |
1000 continue; | |
1001 | 1005 |
1002 // Don't merge together Responses of the same type. | 1006 // Don't merge together Responses of the same type. |
1003 // If handleTouchEvents wanted two of its Responses to be merged, then | 1007 // If handleTouchEvents wanted two of its Responses to be merged, then |
1004 // it would have made them that way to begin with. | 1008 // it would have made them that way to begin with. |
1005 var typeNames = pe.associatedEvents.map(function(event) { | 1009 var typeNames = pe.associatedEvents.map(function(event) { |
1006 return event.typeName; | 1010 return event.typeName; |
1007 }); | 1011 }); |
1008 if (otherPE.containsTypeNames(typeNames)) | 1012 if (otherPE.containsTypeNames(typeNames)) continue; |
1009 continue; | |
1010 | 1013 |
1011 pe.merge(otherPE); | 1014 pe.merge(otherPE); |
1012 protoExpectations.splice(i, 1); | 1015 protoExpectations.splice(i, 1); |
1013 | 1016 |
1014 // Don't skip the next otherPE! | 1017 // Don't skip the next otherPE! |
1015 --i; | 1018 --i; |
1016 } | 1019 } |
1017 } | 1020 } |
1018 return newPEs; | 1021 return newPEs; |
1019 } | 1022 } |
(...skipping 10 matching lines...) Expand all Loading... |
1030 * protoExpectations is input only. | 1033 * protoExpectations is input only. |
1031 * Returns a modified set of ProtoExpectations. | 1034 * Returns a modified set of ProtoExpectations. |
1032 */ | 1035 */ |
1033 function mergeIntersectingAnimations(protoExpectations) { | 1036 function mergeIntersectingAnimations(protoExpectations) { |
1034 var newPEs = []; | 1037 var newPEs = []; |
1035 while (protoExpectations.length) { | 1038 while (protoExpectations.length) { |
1036 var pe = protoExpectations.shift(); | 1039 var pe = protoExpectations.shift(); |
1037 newPEs.push(pe); | 1040 newPEs.push(pe); |
1038 | 1041 |
1039 // Only consider Animations for now. | 1042 // Only consider Animations for now. |
1040 if (pe.type !== ProtoExpectation.ANIMATION_TYPE) | 1043 if (pe.type !== ProtoExpectation.ANIMATION_TYPE) continue; |
1041 continue; | |
1042 | 1044 |
1043 var isCSS = pe.containsSliceTitle(CSS_ANIMATION_TITLE); | 1045 var isCSS = pe.containsSliceTitle(CSS_ANIMATION_TITLE); |
1044 var isFling = pe.containsTypeNames([INPUT_TYPE.FLING_START]); | 1046 var isFling = pe.containsTypeNames([INPUT_TYPE.FLING_START]); |
1045 var isVideo = pe.containsTypeNames([INITIATOR_TYPE.VIDEO]); | 1047 var isVideo = pe.containsTypeNames([INITIATOR_TYPE.VIDEO]); |
1046 | 1048 |
1047 for (var i = 0; i < protoExpectations.length; ++i) { | 1049 for (var i = 0; i < protoExpectations.length; ++i) { |
1048 var otherPE = protoExpectations[i]; | 1050 var otherPE = protoExpectations[i]; |
1049 | 1051 |
1050 if (otherPE.type !== pe.type) | 1052 if (otherPE.type !== pe.type) continue; |
1051 continue; | |
1052 | 1053 |
1053 // Don't merge CSS Animations with any other types. | 1054 // Don't merge CSS Animations with any other types. |
1054 if (isCSS !== otherPE.containsSliceTitle(CSS_ANIMATION_TITLE)) | 1055 if (isCSS !== otherPE.containsSliceTitle(CSS_ANIMATION_TITLE)) { |
1055 continue; | 1056 continue; |
| 1057 } |
1056 | 1058 |
1057 if (isCSS) { | 1059 if (isCSS) { |
1058 if (!pe.isNear(otherPE, ANIMATION_MERGE_THRESHOLD_MS)) | 1060 if (!pe.isNear(otherPE, ANIMATION_MERGE_THRESHOLD_MS)) { |
1059 continue; | 1061 continue; |
| 1062 } |
1060 } else if (!otherPE.intersects(pe)) { | 1063 } else if (!otherPE.intersects(pe)) { |
1061 continue; | 1064 continue; |
1062 } | 1065 } |
1063 | 1066 |
1064 // Don't merge Fling Animations with any other types. | 1067 // Don't merge Fling Animations with any other types. |
1065 if (isFling !== otherPE.containsTypeNames([INPUT_TYPE.FLING_START])) | 1068 if (isFling !== otherPE.containsTypeNames([INPUT_TYPE.FLING_START])) { |
1066 continue; | 1069 continue; |
| 1070 } |
1067 | 1071 |
1068 // Don't merge Video Animations with any other types. | 1072 // Don't merge Video Animations with any other types. |
1069 if (isVideo !== otherPE.containsTypeNames([INITIATOR_TYPE.VIDEO])) | 1073 if (isVideo !== otherPE.containsTypeNames([INITIATOR_TYPE.VIDEO])) { |
1070 continue; | 1074 continue; |
| 1075 } |
1071 | 1076 |
1072 pe.merge(otherPE); | 1077 pe.merge(otherPE); |
1073 protoExpectations.splice(i, 1); | 1078 protoExpectations.splice(i, 1); |
1074 // Don't skip the next otherPE! | 1079 // Don't skip the next otherPE! |
1075 --i; | 1080 --i; |
1076 } | 1081 } |
1077 } | 1082 } |
1078 return newPEs; | 1083 return newPEs; |
1079 } | 1084 } |
1080 | 1085 |
1081 /** | 1086 /** |
1082 * The ends of responses frequently overlap the starts of animations. | 1087 * The ends of responses frequently overlap the starts of animations. |
1083 * Fix the animations to reflect the fact that the user can only start to | 1088 * Fix the animations to reflect the fact that the user can only start to |
1084 * expect 60fps after the response. | 1089 * expect 60fps after the response. |
1085 * | 1090 * |
1086 * For example: | 1091 * For example: |
1087 * RRR -> RRRAA | 1092 * RRR -> RRRAA |
1088 * AAAA | 1093 * AAAA |
1089 * | 1094 * |
1090 * protoExpectations is input only. | 1095 * protoExpectations is input only. |
1091 * Returns a modified set of ProtoExpectations. | 1096 * Returns a modified set of ProtoExpectations. |
1092 */ | 1097 */ |
1093 function fixResponseAnimationStarts(protoExpectations) { | 1098 function fixResponseAnimationStarts(protoExpectations) { |
1094 protoExpectations.forEach(function(ape) { | 1099 protoExpectations.forEach(function(ape) { |
1095 // Only consider animations for now. | 1100 // Only consider animations for now. |
1096 if (ape.type !== ProtoExpectation.ANIMATION_TYPE) | 1101 if (ape.type !== ProtoExpectation.ANIMATION_TYPE) { |
1097 return; | 1102 return; |
| 1103 } |
1098 | 1104 |
1099 protoExpectations.forEach(function(rpe) { | 1105 protoExpectations.forEach(function(rpe) { |
1100 // Only consider responses for now. | 1106 // Only consider responses for now. |
1101 if (rpe.type !== ProtoExpectation.RESPONSE_TYPE) | 1107 if (rpe.type !== ProtoExpectation.RESPONSE_TYPE) { |
1102 return; | 1108 return; |
| 1109 } |
1103 | 1110 |
1104 // Only consider responses that end during the animation. | 1111 // Only consider responses that end during the animation. |
1105 if (!ape.containsTimestampInclusive(rpe.end)) | 1112 if (!ape.containsTimestampInclusive(rpe.end)) { |
1106 return; | 1113 return; |
| 1114 } |
1107 | 1115 |
1108 // Ignore Responses that are entirely contained by the animation. | 1116 // Ignore Responses that are entirely contained by the animation. |
1109 if (ape.containsTimestampInclusive(rpe.start)) | 1117 if (ape.containsTimestampInclusive(rpe.start)) { |
1110 return; | 1118 return; |
| 1119 } |
1111 | 1120 |
1112 // Move the animation start to the response end. | 1121 // Move the animation start to the response end. |
1113 ape.start = rpe.end; | 1122 ape.start = rpe.end; |
1114 }); | 1123 }); |
1115 }); | 1124 }); |
1116 return protoExpectations; | 1125 return protoExpectations; |
1117 } | 1126 } |
1118 | 1127 |
1119 /** | 1128 /** |
1120 * Merge Tap Responses that overlap Touch-only Animations. | 1129 * Merge Tap Responses that overlap Touch-only Animations. |
(...skipping 12 matching lines...) Expand all Loading... |
1133 } | 1142 } |
1134 var newPEs = []; | 1143 var newPEs = []; |
1135 while (protoExpectations.length) { | 1144 while (protoExpectations.length) { |
1136 var pe = protoExpectations.shift(); | 1145 var pe = protoExpectations.shift(); |
1137 newPEs.push(pe); | 1146 newPEs.push(pe); |
1138 | 1147 |
1139 // protoExpectations are sorted by start time, and we don't know whether | 1148 // protoExpectations are sorted by start time, and we don't know whether |
1140 // the Tap Response or the Touch Animation will be first | 1149 // the Tap Response or the Touch Animation will be first |
1141 var peIsTapResponse = isTapResponse(pe); | 1150 var peIsTapResponse = isTapResponse(pe); |
1142 var peIsTouchAnimation = isTouchAnimation(pe); | 1151 var peIsTouchAnimation = isTouchAnimation(pe); |
1143 if (!peIsTapResponse && !peIsTouchAnimation) | 1152 if (!peIsTapResponse && !peIsTouchAnimation) { |
1144 continue; | 1153 continue; |
| 1154 } |
1145 | 1155 |
1146 for (var i = 0; i < protoExpectations.length; ++i) { | 1156 for (var i = 0; i < protoExpectations.length; ++i) { |
1147 var otherPE = protoExpectations[i]; | 1157 var otherPE = protoExpectations[i]; |
1148 | 1158 |
1149 if (!otherPE.intersects(pe)) | 1159 if (!otherPE.intersects(pe)) continue; |
1150 continue; | |
1151 | 1160 |
1152 if (peIsTapResponse && !isTouchAnimation(otherPE)) | 1161 if (peIsTapResponse && !isTouchAnimation(otherPE)) continue; |
1153 continue; | |
1154 | 1162 |
1155 if (peIsTouchAnimation && !isTapResponse(otherPE)) | 1163 if (peIsTouchAnimation && !isTapResponse(otherPE)) continue; |
1156 continue; | |
1157 | 1164 |
1158 // pe might be the Touch Animation, but the merged ProtoExpectation | 1165 // pe might be the Touch Animation, but the merged ProtoExpectation |
1159 // should be a Response. | 1166 // should be a Response. |
1160 pe.type = ProtoExpectation.RESPONSE_TYPE; | 1167 pe.type = ProtoExpectation.RESPONSE_TYPE; |
1161 | 1168 |
1162 pe.merge(otherPE); | 1169 pe.merge(otherPE); |
1163 protoExpectations.splice(i, 1); | 1170 protoExpectations.splice(i, 1); |
1164 // Don't skip the next otherPE! | 1171 // Don't skip the next otherPE! |
1165 --i; | 1172 --i; |
1166 } | 1173 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 | 1218 |
1212 /** | 1219 /** |
1213 * Check that none of the handlers accidentally ignored an input event. | 1220 * Check that none of the handlers accidentally ignored an input event. |
1214 */ | 1221 */ |
1215 function checkAllInputEventsHandled(sortedInputEvents, protoExpectations) { | 1222 function checkAllInputEventsHandled(sortedInputEvents, protoExpectations) { |
1216 var handledEvents = []; | 1223 var handledEvents = []; |
1217 protoExpectations.forEach(function(protoExpectation) { | 1224 protoExpectations.forEach(function(protoExpectation) { |
1218 protoExpectation.associatedEvents.forEach(function(event) { | 1225 protoExpectation.associatedEvents.forEach(function(event) { |
1219 // Ignore CSS Animations that might have multiple active ranges. | 1226 // Ignore CSS Animations that might have multiple active ranges. |
1220 if ((event.title === CSS_ANIMATION_TITLE) && | 1227 if ((event.title === CSS_ANIMATION_TITLE) && |
1221 (event.subSlices.length > 0)) | 1228 (event.subSlices.length > 0)) { |
1222 return; | 1229 return; |
| 1230 } |
1223 | 1231 |
1224 if ((handledEvents.indexOf(event) >= 0) && | 1232 if ((handledEvents.indexOf(event) >= 0) && |
1225 (event.title !== tr.model.helpers.IMPL_RENDERING_STATS)) { | 1233 (event.title !== tr.model.helpers.IMPL_RENDERING_STATS)) { |
1226 modelHelper.model.importWarning({ | 1234 modelHelper.model.importWarning({ |
1227 type: 'UserModelBuilder', | 1235 type: 'UserModelBuilder', |
1228 message: 'Please file a bug with this trace: ' + | 1236 message: 'Please file a bug with this trace: ' + |
1229 `double-handled event: ${event.typeName} @ ${event.start}`, | 1237 `double-handled event: ${event.typeName} @ ${event.start}`, |
1230 showToUser: true | 1238 showToUser: true |
1231 }); | 1239 }); |
1232 return; | 1240 return; |
(...skipping 21 matching lines...) Expand all Loading... |
1254 var sortedInputEvents = getSortedInputEvents(modelHelper); | 1262 var sortedInputEvents = getSortedInputEvents(modelHelper); |
1255 var protoExpectations = findProtoExpectations( | 1263 var protoExpectations = findProtoExpectations( |
1256 modelHelper, sortedInputEvents); | 1264 modelHelper, sortedInputEvents); |
1257 protoExpectations = postProcessProtoExpectations( | 1265 protoExpectations = postProcessProtoExpectations( |
1258 modelHelper, protoExpectations); | 1266 modelHelper, protoExpectations); |
1259 checkAllInputEventsHandled(sortedInputEvents, protoExpectations); | 1267 checkAllInputEventsHandled(sortedInputEvents, protoExpectations); |
1260 | 1268 |
1261 var expectations = []; | 1269 var expectations = []; |
1262 protoExpectations.forEach(function(protoExpectation) { | 1270 protoExpectations.forEach(function(protoExpectation) { |
1263 var ir = protoExpectation.createInteractionRecord(modelHelper.model); | 1271 var ir = protoExpectation.createInteractionRecord(modelHelper.model); |
1264 if (ir) | 1272 if (ir) { |
1265 expectations.push(ir); | 1273 expectations.push(ir); |
| 1274 } |
1266 }); | 1275 }); |
1267 return expectations; | 1276 return expectations; |
1268 } | 1277 } |
1269 | 1278 |
1270 return { | 1279 return { |
1271 findInputExpectations, | 1280 findInputExpectations, |
1272 compareEvents, | 1281 compareEvents, |
1273 CSS_ANIMATION_TITLE, | 1282 CSS_ANIMATION_TITLE, |
1274 INITIATOR_TYPE, | 1283 INITIATOR_TYPE, |
1275 }; | 1284 }; |
1276 }); | 1285 }); |
1277 </script> | 1286 </script> |
OLD | NEW |