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

Side by Side Diff: Source/devtools/front_end/TimelineOverviewPane.js

Issue 61923003: Timeline: show impl-side frames on the Timeline overview (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 * @param {WebInspector.TimelineModel} model 635 * @param {WebInspector.TimelineModel} model
636 */ 636 */
637 WebInspector.TimelineFrameOverview = function(model) 637 WebInspector.TimelineFrameOverview = function(model)
638 { 638 {
639 WebInspector.TimelineOverviewBase.call(this, model); 639 WebInspector.TimelineOverviewBase.call(this, model);
640 this.element.id = "timeline-overview-frames"; 640 this.element.id = "timeline-overview-frames";
641 this.reset(); 641 this.reset();
642 642
643 this._outerPadding = 4 * window.devicePixelRatio; 643 this._outerPadding = 4 * window.devicePixelRatio;
644 this._maxInnerBarWidth = 10 * window.devicePixelRatio; 644 this._maxInnerBarWidth = 10 * window.devicePixelRatio;
645 this._topPadding = 6 * window.devicePixelRatio;
645 646
646 // The below two are really computed by update() -- but let's have something so that windowTimes() is happy. 647 // The below two are really computed by update() -- but let's have something so that windowTimes() is happy.
647 this._actualPadding = 5 * window.devicePixelRatio; 648 this._actualPadding = 5 * window.devicePixelRatio;
648 this._actualOuterBarWidth = this._maxInnerBarWidth + this._actualPadding; 649 this._actualOuterBarWidth = this._maxInnerBarWidth + this._actualPadding;
649 650
650 this._fillStyles = {}; 651 this._fillStyles = {};
651 var categories = WebInspector.TimelinePresentationModel.categories(); 652 var categories = WebInspector.TimelinePresentationModel.categories();
652 for (var category in categories) 653 for (var category in categories)
653 this._fillStyles[category] = WebInspector.TimelinePresentationModel.crea teFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[cate gory]); 654 this._fillStyles[category] = WebInspector.TimelinePresentationModel.crea teFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[cate gory]);
655 this._frameTopShadeGradient = this._context.createLinearGradient(0, 0, 0, th is._topPadding);
656 this._frameTopShadeGradient.addColorStop(0, "rgba(255, 255, 255, 0.9)");
657 this._frameTopShadeGradient.addColorStop(1, "rgba(255, 255, 255, 0.2)");
654 } 658 }
655 659
656 WebInspector.TimelineFrameOverview.prototype = { 660 WebInspector.TimelineFrameOverview.prototype = {
657 reset: function() 661 reset: function()
658 { 662 {
659 this._recordsPerBar = 1; 663 this._recordsPerBar = 1;
660 /** @type {!Array.<{startTime:number, endTime:number}>} */ 664 /** @type {!Array.<{startTime:number, endTime:number}>} */
661 this._barTimes = []; 665 this._barTimes = [];
662 this._frames = []; 666 this._mainThreadFrames = [];
667 this._backgroundFrames = [];
668 this._framesById = {};
663 }, 669 },
664 670
665 update: function() 671 update: function()
666 { 672 {
667 this._resetCanvas(); 673 this._resetCanvas();
668 this._barTimes = []; 674 this._barTimes = [];
669 675
676 var backgroundFramesHeight = 15;
677 var mainThreadFramesHeight = this._canvas.height - backgroundFramesHeigh t;
670 const minBarWidth = 4 * window.devicePixelRatio; 678 const minBarWidth = 4 * window.devicePixelRatio;
671 var frameCount = this._frames.length; 679 var frameCount = Math.max(this._mainThreadFrames.length, this._backgroun dFrames.length);
pfeldman 2013/11/06 17:21:05 this._backgroundFrames.length || this._mainThreadF
672 var framesPerBar = Math.max(1, frameCount * minBarWidth / this._canvas.w idth); 680 var framesPerBar = Math.max(1, frameCount * minBarWidth / this._canvas.w idth);
673 var visibleFrames = this._aggregateFrames(this._frames, framesPerBar); 681
674 var windowHeight = this._canvas.height; 682 var mainThreadVisibleFrames;
675 const paddingTop = 4 * window.devicePixelRatio; 683 var backgroundVisibleFrames;
676 var scale = (windowHeight - paddingTop) / this._computeTargetFrameLength (visibleFrames); 684 if (this._backgroundFrames.length) {
677 this._renderBars(visibleFrames, scale, windowHeight); 685 backgroundVisibleFrames = this._aggregateFrames(this._backgroundFram es, framesPerBar);
678 this._drawFPSMarks(scale, windowHeight); 686 mainThreadVisibleFrames = Array(backgroundVisibleFrames.length);
pfeldman 2013/11/06 17:21:05 This can not compile - new Array.
687 for (var i = 0; i < backgroundVisibleFrames.length; ++i) {
688 var frameId = backgroundVisibleFrames[i].mainThreadFrameId;
689 mainThreadVisibleFrames[i] = frameId && this._framesById[frameId ];
690 }
691 } else {
692 mainThreadVisibleFrames = this._aggregateFrames(this._mainThreadFram es, framesPerBar);
693 }
694
695 this._context.save();
696 this._setCanvasWindow(0, backgroundFramesHeight, this._canvas.width, mai nThreadFramesHeight);
697 var scale = (mainThreadFramesHeight - this._topPadding) / this._computeT argetFrameLength(mainThreadVisibleFrames);
698 this._renderBars(mainThreadVisibleFrames, scale, mainThreadFramesHeight) ;
699 this._context.fillStyle = this._frameTopShadeGradient;
700 this._context.fillRect(0, 0, this._canvas.width, this._topPadding);
701 this._drawFPSMarks(scale, mainThreadFramesHeight);
702 this._context.restore();
703
704 var bottom = backgroundFramesHeight + 0.5;
705 this._context.strokeStyle = "rgba(120, 120, 120, 0.8)";
706 this._context.beginPath();
707 this._context.moveTo(0, bottom);
708 this._context.lineTo(this._canvas.width, bottom);
709 this._context.stroke();
710
711 if (backgroundVisibleFrames) {
712 const targetFPS = 30.0;
713 scale = (backgroundFramesHeight - this._topPadding) / (1.0 / targetF PS);
714 this._renderBars(backgroundVisibleFrames, scale, backgroundFramesHei ght);
715 }
679 }, 716 },
680 717
681 /** 718 /**
682 * @param {WebInspector.TimelineFrame} frame 719 * @param {WebInspector.TimelineFrame} frame
683 */ 720 */
684 addFrame: function(frame) 721 addFrame: function(frame)
685 { 722 {
686 this._frames.push(frame); 723 var frames;
724 if (frame.isBackground) {
725 frames = this._backgroundFrames;
726 } else {
727 frames = this._mainThreadFrames;
728 this._framesById[frame.id] = frame;
729 }
730 frames.push(frame);
687 }, 731 },
688 732
733 /**
734 * @param {number} x0
735 * @param {number} y0
736 * @param {number} width
737 * @param {number} height
738 */
739 _setCanvasWindow: function(x0, y0, width, height)
740 {
741 this._context.translate(x0, y0);
742 this._context.beginPath();
743 this._context.moveTo(0, 0);
744 this._context.lineTo(width, 0);
745 this._context.lineTo(width, height);
746 this._context.lineTo(0, height);
747 this._context.lineTo(0, 0);
748 this._context.clip();
749 },
689 750
690 /** 751 /**
691 * @param {Array.<WebInspector.TimelineFrame>} frames 752 * @param {Array.<WebInspector.TimelineFrame>} frames
692 * @param {number} framesPerBar 753 * @param {number} framesPerBar
693 * @return {Array.<WebInspector.TimelineFrame>} 754 * @return {Array.<WebInspector.TimelineFrame>}
694 */ 755 */
695 _aggregateFrames: function(frames, framesPerBar) 756 _aggregateFrames: function(frames, framesPerBar)
696 { 757 {
697 var visibleFrames = []; 758 var visibleFrames = [];
698 for (var barNumber = 0, currentFrame = 0; currentFrame < frames.length; ++barNumber) { 759 for (var barNumber = 0, currentFrame = 0; currentFrame < frames.length; ++barNumber) {
699 var barStartTime = frames[currentFrame].startTime; 760 var barStartTime = frames[currentFrame].startTime;
700 var longestFrame = null; 761 var longestFrame = null;
701 var longestDuration = 0; 762 var longestDuration = 0;
702 763
703 for (var lastFrame = Math.min(Math.floor((barNumber + 1) * framesPer Bar), frames.length); 764 for (var lastFrame = Math.min(Math.floor((barNumber + 1) * framesPer Bar), frames.length);
704 currentFrame < lastFrame; ++currentFrame) { 765 currentFrame < lastFrame; ++currentFrame) {
705 var duration = frames[currentFrame].duration; 766 var duration = this._frameDuration(frames[currentFrame]);
706 if (!longestFrame || longestDuration < duration) { 767 if (!longestFrame || longestDuration < duration) {
707 longestFrame = frames[currentFrame]; 768 longestFrame = frames[currentFrame];
708 longestDuration = duration; 769 longestDuration = duration;
709 } 770 }
710 } 771 }
711 var barEndTime = frames[currentFrame - 1].endTime; 772 var barEndTime = frames[currentFrame - 1].endTime;
712 if (longestFrame) { 773 if (longestFrame) {
713 visibleFrames.push(longestFrame); 774 visibleFrames.push(longestFrame);
714 this._barTimes.push({ startTime: barStartTime, endTime: barEndTi me }); 775 this._barTimes.push({ startTime: barStartTime, endTime: barEndTi me });
715 } 776 }
716 } 777 }
717 return visibleFrames; 778 return visibleFrames;
718 }, 779 },
719 780
720 /** 781 /**
782 * @param {WebInspector.TimelineFrame} frame
783 */
784 _frameDuration: function(frame)
785 {
786 var relatedFrame = frame.mainThreadFrameId && this._framesById[frame.mai nThreadFrameId];
787 return frame.duration + (relatedFrame ? relatedFrame.duration : 0);
788 },
789
790 /**
721 * @param {Array.<WebInspector.TimelineFrame>} frames 791 * @param {Array.<WebInspector.TimelineFrame>} frames
722 * @return {number} 792 * @return {number}
723 */ 793 */
724 _computeTargetFrameLength: function(frames) 794 _computeTargetFrameLength: function(frames)
725 { 795 {
726 var durations = frames.select("duration"); 796 var durations = [];
797 for (var i = 0; i < frames.length; ++i) {
798 if (frames[i])
799 durations.push(frames[i].duration);
800 }
727 var medianFrameLength = durations.qselect(Math.floor(durations.length / 2)); 801 var medianFrameLength = durations.qselect(Math.floor(durations.length / 2));
728 802
729 // Optimize appearance for 30fps. However, if at least half frames won't fit at this scale, 803 // Optimize appearance for 30fps. However, if at least half frames won't fit at this scale,
730 // fall back to using autoscale. 804 // fall back to using autoscale.
731 const targetFPS = 30; 805 const targetFPS = 30;
732 var result = 1.0 / targetFPS; 806 var result = 1.0 / targetFPS;
733 if (result >= medianFrameLength) 807 if (result >= medianFrameLength)
734 return result; 808 return result;
735 809
736 var maxFrameLength = Math.max.apply(Math, durations); 810 var maxFrameLength = Math.max.apply(Math, durations);
737 return Math.min(medianFrameLength * 2, maxFrameLength); 811 return Math.min(medianFrameLength * 2, maxFrameLength);
738 }, 812 },
739 813
740 /** 814 /**
741 * @param {Array.<WebInspector.TimelineFrame>} frames 815 * @param {Array.<WebInspector.TimelineFrame>} frames
742 * @param {number} scale 816 * @param {number} scale
743 * @param {number} windowHeight 817 * @param {number} windowHeight
744 */ 818 */
745 _renderBars: function(frames, scale, windowHeight) 819 _renderBars: function(frames, scale, windowHeight)
746 { 820 {
747 const maxPadding = 5 * window.devicePixelRatio; 821 const maxPadding = 5 * window.devicePixelRatio;
748 this._actualOuterBarWidth = Math.min((this._canvas.width - 2 * this._out erPadding) / frames.length, this._maxInnerBarWidth + maxPadding); 822 this._actualOuterBarWidth = Math.min((this._canvas.width - 2 * this._out erPadding) / frames.length, this._maxInnerBarWidth + maxPadding);
749 this._actualPadding = Math.min(Math.floor(this._actualOuterBarWidth / 3) , maxPadding); 823 this._actualPadding = Math.min(Math.floor(this._actualOuterBarWidth / 3) , maxPadding);
750 824
751 var barWidth = this._actualOuterBarWidth - this._actualPadding; 825 var barWidth = this._actualOuterBarWidth - this._actualPadding;
752 for (var i = 0; i < frames.length; ++i) 826 for (var i = 0; i < frames.length; ++i) {
753 this._renderBar(this._barNumberToScreenPosition(i), barWidth, window Height, frames[i], scale); 827 if (frames[i])
828 this._renderBar(this._barNumberToScreenPosition(i), barWidth, wi ndowHeight, frames[i], scale);
829 }
754 }, 830 },
755 831
756 /** 832 /**
757 * @param {number} n 833 * @param {number} n
758 */ 834 */
759 _barNumberToScreenPosition: function(n) 835 _barNumberToScreenPosition: function(n)
760 { 836 {
761 return this._outerPadding + this._actualOuterBarWidth * n; 837 return this._outerPadding + this._actualOuterBarWidth * n;
762 }, 838 },
763 839
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 873
798 this._context.moveTo(0, y); 874 this._context.moveTo(0, y);
799 this._context.lineTo(this._canvas.width, y); 875 this._context.lineTo(this._canvas.width, y);
800 876
801 this._context.fillStyle = "rgba(255, 255, 255, 0.5)"; 877 this._context.fillStyle = "rgba(255, 255, 255, 0.5)";
802 this._context.fillRect(labelX - labelWidth, labelY, labelWidth, line Height); 878 this._context.fillRect(labelX - labelWidth, labelY, labelWidth, line Height);
803 this._context.fillStyle = "black"; 879 this._context.fillStyle = "black";
804 this._context.fillText(label, labelX - labelPadding, labelY + lineHe ight - baselineHeight); 880 this._context.fillText(label, labelX - labelPadding, labelY + lineHe ight - baselineHeight);
805 labelTopMargin = labelY + lineHeight; 881 labelTopMargin = labelY + lineHeight;
806 } 882 }
807 this._context.strokeStyle = "rgba(128, 128, 128, 0.5)"; 883 this._context.strokeStyle = "rgba(60, 60, 60, 0.4)";
808 this._context.stroke(); 884 this._context.stroke();
809 this._context.restore(); 885 this._context.restore();
810 }, 886 },
811 887
812 /** 888 /**
813 * @param {number} left 889 * @param {number} left
814 * @param {number} width 890 * @param {number} width
815 * @param {number} windowHeight 891 * @param {number} windowHeight
816 * @param {WebInspector.TimelineFrame} frame 892 * @param {WebInspector.TimelineFrame} frame
817 * @param {number} scale 893 * @param {number} scale
818 */ 894 */
819 _renderBar: function(left, width, windowHeight, frame, scale) 895 _renderBar: function(left, width, windowHeight, frame, scale)
820 { 896 {
821 var categories = Object.keys(WebInspector.TimelinePresentationModel.cate gories()); 897 var categories = Object.keys(WebInspector.TimelinePresentationModel.cate gories());
822 if (!categories.length) 898 if (!categories.length)
823 return; 899 return;
824 var x = Math.floor(left) + 0.5; 900 var x = Math.floor(left) + 0.5;
825 width = Math.floor(width); 901 width = Math.floor(width);
826 902
827 for (var i = 0, bottomOffset = windowHeight; i < categories.length; ++i) { 903 for (var i = 0, bottomOffset = windowHeight; i < categories.length; ++i) {
828 var category = categories[i]; 904 var category = categories[i];
829 var duration = frame.timeByCategory[category]; 905 var duration = frame.timeByCategory[category];
830 906
831 if (!duration) 907 if (!duration)
832 continue; 908 continue;
833 var height = duration * scale; 909 var height = Math.round(duration * scale);
834 var y = Math.floor(bottomOffset - height) + 0.5; 910 var y = Math.floor(bottomOffset - height) + 0.5;
835 911
836 this._context.save(); 912 this._context.save();
837 this._context.translate(x, 0); 913 this._context.translate(x, 0);
838 this._context.scale(width / this._maxInnerBarWidth, 1); 914 this._context.scale(width / this._maxInnerBarWidth, 1);
839 this._context.fillStyle = this._fillStyles[category]; 915 this._context.fillStyle = this._fillStyles[category];
840 this._context.fillRect(0, y, this._maxInnerBarWidth, Math.floor(heig ht)); 916 this._context.fillRect(0, y, this._maxInnerBarWidth, Math.floor(heig ht));
841 this._context.strokeStyle = WebInspector.TimelinePresentationModel.c ategories()[category].borderColor; 917 this._context.strokeStyle = WebInspector.TimelinePresentationModel.c ategories()[category].borderColor;
842 this._context.beginPath(); 918 this._context.beginPath();
843 this._context.moveTo(0, y); 919 this._context.moveTo(0, y);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 WebInspector.TimelineWindowFilter.prototype = { 1031 WebInspector.TimelineWindowFilter.prototype = {
956 /** 1032 /**
957 * @param {!WebInspector.TimelinePresentationModel.Record} record 1033 * @param {!WebInspector.TimelinePresentationModel.Record} record
958 * @return {boolean} 1034 * @return {boolean}
959 */ 1035 */
960 accept: function(record) 1036 accept: function(record)
961 { 1037 {
962 return record.lastChildEndTime >= this._pane._windowStartTime && record. startTime <= this._pane._windowEndTime; 1038 return record.lastChildEndTime >= this._pane._windowStartTime && record. startTime <= this._pane._windowEndTime;
963 } 1039 }
964 } 1040 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698