Bug 1050770 - Add paint details to timeline. r=smaug, r=mattwoodrow

This commit is contained in:
Tom Tromey 2014-12-11 10:40:00 -05:00
parent 7b6aeb4ee5
commit 4863a3d084
5 changed files with 83 additions and 4 deletions

View File

@ -2898,6 +2898,11 @@ nsDocShell::PopProfileTimelineMarkers(JSContext* aCx,
const char* startMarkerName = startPayload->GetName();
bool hasSeenPaintedLayer = false;
bool isPaint = strcmp(startMarkerName, "Paint") == 0;
// If we are processing a Paint marker, we append information from
// all the embedded Layer markers to this array.
mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect> layerRectangles;
if (startPayload->GetMetaData() == TRACING_INTERVAL_START) {
bool hasSeenEnd = false;
@ -2915,14 +2920,14 @@ nsDocShell::PopProfileTimelineMarkers(JSContext* aCx,
const char* endMarkerName = endPayload->GetName();
// Look for Layer markers to stream out paint markers.
if (strcmp(endMarkerName, "Layer") == 0) {
if (isPaint && strcmp(endMarkerName, "Layer") == 0) {
hasSeenPaintedLayer = true;
endPayload->AddLayerRectangles(layerRectangles);
}
if (!startPayload->Equals(endPayload)) {
continue;
}
bool isPaint = strcmp(startMarkerName, "Paint") == 0;
// Pair start and end markers.
if (endPayload->GetMetaData() == TRACING_INTERVAL_START) {
@ -2938,7 +2943,11 @@ nsDocShell::PopProfileTimelineMarkers(JSContext* aCx,
marker.mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
marker.mStart = startPayload->GetTime();
marker.mEnd = endPayload->GetTime();
startPayload->AddDetails(marker);
if (isPaint) {
marker.mRectangles.Construct(layerRectangles);
} else {
startPayload->AddDetails(marker);
}
profileTimelineMarkers.AppendElement(marker);
}

View File

@ -305,6 +305,11 @@ public:
{
}
virtual void AddLayerRectangles(mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect>&)
{
MOZ_ASSERT_UNREACHABLE("can only be called on layer markers");
}
const char* GetName() const
{
return mName;

View File

@ -7,6 +7,7 @@
// restyles, reflows and paints occur
let URL = '<!DOCTYPE html><style>' +
'body {margin:0; padding: 0;} ' +
'div {width:100px;height:100px;background:red;} ' +
'.resize-change-color {width:50px;height:50px;background:blue;} ' +
'.change-color {width:50px;height:50px;background:yellow;} ' +
@ -21,8 +22,15 @@ let TESTS = [{
check: function(markers) {
ok(markers.length > 0, "markers were returned");
console.log(markers);
info(JSON.stringify(markers.filter(m => m.name == "Paint")));
ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow");
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
for (let marker of markers.filter(m => m.name == "Paint")) {
// This change should generate at least one rectangle.
ok(marker.rectangles.length >= 1, "marker has one rectangle");
// One of the rectangles should contain the div.
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100)));
}
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
}
}, {
@ -34,6 +42,12 @@ let TESTS = [{
ok(markers.length > 0, "markers were returned");
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
for (let marker of markers.filter(m => m.name == "Paint")) {
// This change should generate at least one rectangle.
ok(marker.rectangles.length >= 1, "marker has one rectangle");
// One of the rectangles should contain the div.
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50)));
}
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
}
}, {
@ -145,3 +159,8 @@ function waitForMarkers(docshell) {
}, 200);
});
}
function rectangleContains(rect, x, y, width, height) {
return rect.x <= x && rect.y <= y && rect.width >= width &&
rect.height >= height;
}

View File

@ -4,6 +4,13 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
dictionary ProfileTimelineLayerRect {
long x = 0;
long y = 0;
long width = 0;
long height = 0;
};
dictionary ProfileTimelineMarker {
DOMString name = "";
DOMHighResTimeStamp start = 0;
@ -13,4 +20,6 @@ dictionary ProfileTimelineMarker {
/* For DOMEvent markers. */
DOMString type;
unsigned short eventPhase;
/* For Paint markers. */
sequence<ProfileTimelineLayerRect> rectangles;
};

View File

@ -26,6 +26,7 @@
#include "mozilla/LookAndFeel.h"
#include "nsDocShell.h"
#include "nsImageFrame.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
#include "GeckoProfiler.h"
#include "mozilla/gfx/Tools.h"
@ -4419,6 +4420,36 @@ static void DrawForcedBackgroundColor(DrawTarget& aDrawTarget,
}
}
class LayerTimelineMarker : public nsDocShell::TimelineMarker
{
public:
LayerTimelineMarker(nsDocShell* aDocShell, const nsIntRegion& aRegion)
: nsDocShell::TimelineMarker(aDocShell, "Layer", TRACING_EVENT)
, mRegion(aRegion)
{
}
~LayerTimelineMarker()
{
}
virtual void AddLayerRectangles(mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect>& aRectangles)
{
nsIntRegionRectIterator it(mRegion);
while (const nsIntRect* iterRect = it.Next()) {
mozilla::dom::ProfileTimelineLayerRect rect;
rect.mX = iterRect->X();
rect.mY = iterRect->Y();
rect.mWidth = iterRect->Width();
rect.mHeight = iterRect->Height();
aRectangles.AppendElement(rect);
}
}
private:
nsIntRegion mRegion;
};
/*
* A note on residual transforms:
*
@ -4568,7 +4599,13 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
if (presContext && presContext->GetDocShell() && isActiveLayerManager) {
nsDocShell* docShell = static_cast<nsDocShell*>(presContext->GetDocShell());
docShell->AddProfileTimelineMarker("Layer", TRACING_EVENT);
bool isRecording;
docShell->GetRecordProfileTimelineMarkers(&isRecording);
if (isRecording) {
mozilla::UniquePtr<nsDocShell::TimelineMarker> marker =
MakeUnique<LayerTimelineMarker>(docShell, aRegionToDraw);
docShell->AddProfileTimelineMarker(marker);
}
}
if (!aRegionToInvalidate.IsEmpty()) {