Commit f604a06f authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Remove metrics record_time_context_painting_disabled and record_time_construction_disabled

They were to evaluate paint performance with the cost of
GraphicsContext or DisplayItem constructor excluded. They were
meaningful when we developed the early versions of display-item-based
painting (Slimming Paint V1), but seem to provide little value
nowadays.

Change-Id: I7b2ebf90364c51cf65ed1b65cd376e0eafdd7df3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2090760
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarCaleb Rouleau <crouleau@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747906}
parent 3d0006cc
......@@ -32,9 +32,7 @@ const int kDefaultRecordRepeatCount = 100;
const char* kModeSuffixes[RecordingSource::RECORDING_MODE_COUNT] = {
"",
"_painting_disabled",
"_caching_disabled",
"_construction_disabled",
"_subsequence_caching_disabled",
"_partial_invalidation"};
......@@ -43,12 +41,8 @@ RecordingModeToPaintingControlSetting(RecordingSource::RecordingMode mode) {
switch (mode) {
case RecordingSource::RECORD_NORMALLY:
return ContentLayerClient::PAINTING_BEHAVIOR_NORMAL_FOR_TEST;
case RecordingSource::RECORD_WITH_PAINTING_DISABLED:
return ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED;
case RecordingSource::RECORD_WITH_CACHING_DISABLED:
return ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
case RecordingSource::RECORD_WITH_CONSTRUCTION_DISABLED:
return ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED;
case RecordingSource::RECORD_WITH_SUBSEQUENCE_CACHING_DISABLED:
return ContentLayerClient::SUBSEQUENCE_CACHING_DISABLED;
case RecordingSource::RECORD_WITH_PARTIAL_INVALIDATION:
......
......@@ -21,9 +21,7 @@ class CC_EXPORT ContentLayerClient {
enum PaintingControlSetting {
PAINTING_BEHAVIOR_NORMAL,
PAINTING_BEHAVIOR_NORMAL_FOR_TEST,
DISPLAY_LIST_CONSTRUCTION_DISABLED,
DISPLAY_LIST_CACHING_DISABLED,
DISPLAY_LIST_PAINTING_DISABLED,
SUBSEQUENCE_CACHING_DISABLED,
PARTIAL_INVALIDATION,
};
......
......@@ -26,9 +26,7 @@ class CC_EXPORT RecordingSource {
public:
enum RecordingMode {
RECORD_NORMALLY,
RECORD_WITH_PAINTING_DISABLED,
RECORD_WITH_CACHING_DISABLED,
RECORD_WITH_CONSTRUCTION_DISABLED,
RECORD_WITH_SUBSEQUENCE_CACHING_DISABLED,
RECORD_WITH_PARTIAL_INVALIDATION,
RECORDING_MODE_COUNT, // Must be the last entry.
......
......@@ -758,53 +758,51 @@ void HTMLCanvasElement::PaintInternal(GraphicsContext& context,
const PhysicalRect& r) {
context_->PaintRenderingResultsToCanvas(kFrontBuffer);
if (HasResourceProvider()) {
if (!context.ContextDisabled()) {
const ComputedStyle* style = GetComputedStyle();
// For 2D Canvas, there are two ways of render Canvas for printing:
// display list or image snapshot. Display list allows better PDF printing
// and we prefer this method.
// Here are the requirements for display list to be used:
// 1. We must have had a full repaint of the Canvas after beginprint
// event has been fired. Otherwise, we don't have a PaintRecord.
// 2. CSS property 'image-rendering' must not be 'pixelated'.
// display list rendering: we replay the last full PaintRecord, if Canvas
// has been redraw since beginprint happened.
if (IsPrinting() && !Is3d() && canvas2d_bridge_) {
canvas2d_bridge_->FlushRecording();
if (canvas2d_bridge_->getLastRecord()) {
if (style && style->ImageRendering() != EImageRendering::kPixelated) {
context.Canvas()->save();
context.Canvas()->translate(r.X(), r.Y());
context.Canvas()->scale(r.Width() / Size().Width(),
r.Height() / Size().Height());
context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord());
context.Canvas()->restore();
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true);
return;
}
const ComputedStyle* style = GetComputedStyle();
// For 2D Canvas, there are two ways of render Canvas for printing:
// display list or image snapshot. Display list allows better PDF printing
// and we prefer this method.
// Here are the requirements for display list to be used:
// 1. We must have had a full repaint of the Canvas after beginprint
// event has been fired. Otherwise, we don't have a PaintRecord.
// 2. CSS property 'image-rendering' must not be 'pixelated'.
// display list rendering: we replay the last full PaintRecord, if Canvas
// has been redraw since beginprint happened.
if (IsPrinting() && !Is3d() && canvas2d_bridge_) {
canvas2d_bridge_->FlushRecording();
if (canvas2d_bridge_->getLastRecord()) {
if (style && style->ImageRendering() != EImageRendering::kPixelated) {
context.Canvas()->save();
context.Canvas()->translate(r.X(), r.Y());
context.Canvas()->scale(r.Width() / Size().Width(),
r.Height() / Size().Height());
context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord());
context.Canvas()->restore();
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true);
return;
}
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false);
}
// or image snapshot rendering: grab a snapshot and raster it.
SkBlendMode composite_operator =
!context_ || context_->CreationAttributes().alpha
? SkBlendMode::kSrcOver
: SkBlendMode::kSrc;
FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size()));
scoped_refptr<StaticBitmapImage> snapshot =
canvas2d_bridge_
? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration)
: (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr);
if (snapshot) {
// GraphicsContext cannot handle gpu resource serialization.
snapshot = snapshot->MakeUnaccelerated();
DCHECK(!snapshot->IsTextureBacked());
context.DrawImage(snapshot.get(), Image::kSyncDecode,
FloatRect(PixelSnappedIntRect(r)), &src_rect,
style && style->HasFilterInducingProperty(),
composite_operator);
}
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false);
}
// or image snapshot rendering: grab a snapshot and raster it.
SkBlendMode composite_operator =
!context_ || context_->CreationAttributes().alpha
? SkBlendMode::kSrcOver
: SkBlendMode::kSrc;
FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size()));
scoped_refptr<StaticBitmapImage> snapshot =
canvas2d_bridge_
? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration)
: (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr);
if (snapshot) {
// GraphicsContext cannot handle gpu resource serialization.
snapshot = snapshot->MakeUnaccelerated();
DCHECK(!snapshot->IsTextureBacked());
context.DrawImage(snapshot.get(), Image::kSyncDecode,
FloatRect(PixelSnappedIntRect(r)), &src_rect,
style && style->HasFilterInducingProperty(),
composite_operator);
}
} else {
// When alpha is false, we should draw to opaque black.
......
......@@ -252,8 +252,7 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
ImageResourceContent* image_content = image_resource.CachedImage();
if ((IsA<HTMLImageElement>(node) || IsA<HTMLVideoElement>(node)) &&
!context.ContextDisabled() && image_content &&
image_content->IsLoaded()) {
image_content && image_content->IsLoaded()) {
LocalDOMWindow* window = layout_image_.GetDocument().domWindow();
DCHECK(window);
ImageElementTiming::From(*window).NotifyImagePainted(
......
......@@ -79,7 +79,7 @@ void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
paint_info.context.DrawImage(
image.get(), decode_mode, dest_rect, &src_rect,
layout_svg_image_.StyleRef().HasFilterInducingProperty());
if (!paint_info.context.ContextDisabled() && image_resource->CachedImage() &&
if (image_resource->CachedImage() &&
image_resource->CachedImage()->IsLoaded()) {
LocalDOMWindow* window = layout_svg_image_.GetDocument().domWindow();
DCHECK(window);
......
......@@ -70,14 +70,7 @@ class PLATFORM_EXPORT GraphicsContext {
USING_FAST_MALLOC(GraphicsContext);
public:
enum DisabledMode {
kNothingDisabled = 0, // Run as normal.
kFullyDisabled = 1 // Do absolutely minimal work to remove the cost of
// the context from performance tests.
};
explicit GraphicsContext(PaintController&,
DisabledMode = kNothingDisabled,
printing::MetafileSkia* = nullptr,
paint_preview::PaintPreviewTracker* = nullptr);
......@@ -91,8 +84,6 @@ class PLATFORM_EXPORT GraphicsContext {
return paint_controller_;
}
bool ContextDisabled() const { return disabled_state_; }
const DarkModeSettings& dark_mode_settings() const {
return dark_mode_filter_.settings();
}
......@@ -500,9 +491,6 @@ class PLATFORM_EXPORT GraphicsContext {
// Apply deferred paint state saves
void RealizePaintSave() {
if (ContextDisabled())
return;
if (paint_state_->SaveCount()) {
paint_state_->DecrementSaveCount();
++paint_state_index_;
......@@ -524,7 +512,9 @@ class PLATFORM_EXPORT GraphicsContext {
class DarkModeFlags;
// null indicates painting is contextDisabled. Never delete this object.
// This is owned by paint_recorder_. Never delete this object.
// Drawing operations are allowed only after the first BeginRecording() which
// initializes this to not null.
cc::PaintCanvas* canvas_;
PaintController& paint_controller_;
......@@ -550,8 +540,6 @@ class PLATFORM_EXPORT GraphicsContext {
bool disable_destruction_checks_;
#endif
const DisabledMode disabled_state_;
float device_scale_factor_;
// TODO(gilmanmh): Investigate making this base::Optional<DarkModeFilter>
......
......@@ -308,7 +308,7 @@ void GraphicsLayer::PaintRecursivelyInternal(
child->PaintRecursivelyInternal(repainted_layers);
}
bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
bool GraphicsLayer::Paint() {
#if !DCHECK_IS_ON()
// TODO(crbug.com/853096): Investigate why we can ever reach here without
// a valid layer state. Seems to only happen on Android builds.
......@@ -316,7 +316,7 @@ bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
return false;
#endif
if (PaintWithoutCommit(disabled_mode)) {
if (PaintWithoutCommit()) {
GetPaintController().CommitNewDisplayItems();
UpdateSafeOpaqueBackgroundColor();
} else if (!needs_check_raster_invalidation_) {
......@@ -366,13 +366,10 @@ void GraphicsLayer::UpdateSafeOpaqueBackgroundColor() {
bool GraphicsLayer::PaintWithoutCommitForTesting(
const base::Optional<IntRect>& interest_rect) {
return PaintWithoutCommit(GraphicsContext::kNothingDisabled,
base::OptionalOrNullptr(interest_rect));
return PaintWithoutCommit(base::OptionalOrNullptr(interest_rect));
}
bool GraphicsLayer::PaintWithoutCommit(
GraphicsContext::DisabledMode disabled_mode,
const IntRect* interest_rect) {
bool GraphicsLayer::PaintWithoutCommit(const IntRect* interest_rect) {
DCHECK(PaintsContentOrHitTest());
if (client_.ShouldThrottleRendering() || client_.IsUnderSVGHiddenContainer())
......@@ -393,7 +390,7 @@ bool GraphicsLayer::PaintWithoutCommit(
return false;
}
GraphicsContext context(GetPaintController(), disabled_mode, nullptr);
GraphicsContext context(GetPaintController());
DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName();
GetPaintController().UpdateCurrentPaintChunkProperties(nullptr,
layer_state_->state);
......@@ -788,8 +785,6 @@ scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
TRACE_EVENT0("blink,benchmark", "GraphicsLayer::PaintContents");
PaintController& paint_controller = GetPaintController();
paint_controller.SetDisplayItemConstructionIsDisabled(
painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED);
paint_controller.SetSubsequenceCachingIsDisabled(
painting_control == SUBSEQUENCE_CACHING_DISABLED);
......@@ -799,23 +794,15 @@ scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
// We also disable caching when Painting or Construction are disabled. In both
// cases we would like to compare assuming the full cost of recording, not the
// cost of re-using cached content.
if (painting_control == DISPLAY_LIST_CACHING_DISABLED ||
painting_control == DISPLAY_LIST_PAINTING_DISABLED ||
painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED)
if (painting_control == DISPLAY_LIST_CACHING_DISABLED)
paint_controller.InvalidateAll();
GraphicsContext::DisabledMode disabled_mode =
GraphicsContext::kNothingDisabled;
if (painting_control == DISPLAY_LIST_PAINTING_DISABLED ||
painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED)
disabled_mode = GraphicsContext::kFullyDisabled;
// Anything other than PAINTING_BEHAVIOR_NORMAL is for testing. In non-testing
// scenarios, it is an error to call GraphicsLayer::Paint. Actual painting
// occurs in LocalFrameView::PaintTree() which calls GraphicsLayer::Paint();
// this method merely copies the painted output to the cc::DisplayItemList.
if (painting_control != PAINTING_BEHAVIOR_NORMAL)
Paint(disabled_mode);
Paint();
auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
......@@ -826,7 +813,6 @@ scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
VisualRectSubpixelOffset(),
paint_controller.GetPaintArtifact().GetDisplayItemList(), *display_list);
paint_controller.SetDisplayItemConstructionIsDisabled(false);
paint_controller.SetSubsequenceCachingIsDisabled(false);
display_list->Finalize();
......
......@@ -200,7 +200,7 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
IntRect InterestRect();
bool PaintRecursively();
// Returns true if this layer is repainted.
bool Paint(GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled);
bool Paint();
PaintController& GetPaintController() const;
......@@ -265,9 +265,7 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
void UpdateSafeOpaqueBackgroundColor();
// Returns true if PaintController::PaintArtifact() changed and needs commit.
bool PaintWithoutCommit(
GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled,
const IntRect* interest_rect = nullptr);
bool PaintWithoutCommit(const IntRect* interest_rect = nullptr);
// Adds a child without calling NotifyChildListChange(), so that adding
// children can be batched before updating.
......
......@@ -31,9 +31,6 @@ DrawingRecorder::DrawingRecorder(GraphicsContext& context,
context_.GetPaintController().NewDisplayItemList().size())
#endif
{
if (context.GetPaintController().DisplayItemConstructionIsDisabled())
return;
// Must check DrawingRecorder::UseCachedDrawingIfPossible before creating the
// DrawingRecorder.
DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
......@@ -54,9 +51,6 @@ DrawingRecorder::DrawingRecorder(GraphicsContext& context,
}
DrawingRecorder::~DrawingRecorder() {
if (context_.GetPaintController().DisplayItemConstructionIsDisabled())
return;
if (context_.Printing() && dom_node_id_to_restore_)
context_.SetDOMNodeId(dom_node_id_to_restore_.value());
......
......@@ -101,9 +101,6 @@ static void RecordForeignLayerInternal(GraphicsContext& context,
const LayerAsJSONClient* json_client,
const PropertyTreeState* properties) {
PaintController& paint_controller = context.GetPaintController();
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
// This is like ScopedPaintChunkProperties but uses null id because foreign
// layer chunk doesn't need an id nor a client.
base::Optional<PropertyTreeState> previous_properties;
......
......@@ -48,8 +48,6 @@ void RecordGraphicsLayer(GraphicsContext& context,
graphics_layer.CcLayer()->RemoveAllChildren();
PaintController& paint_controller = context.GetPaintController();
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
// This is like ScopedPaintChunkProperties but uses null id because graphics
// layer chunk doesn't need an id nor a client.
......
......@@ -13,13 +13,8 @@ void HitTestDisplayItem::Record(GraphicsContext& context,
const DisplayItemClient& client,
const HitTestRect& hit_test_rect) {
auto& paint_controller = context.GetPaintController();
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
if (paint_controller.UseCachedItemIfPossible(client, DisplayItem::kHitTest))
return;
paint_controller.CreateAndAppend<HitTestDisplayItem>(client, hit_test_rect);
if (!paint_controller.UseCachedItemIfPossible(client, DisplayItem::kHitTest))
paint_controller.CreateAndAppend<HitTestDisplayItem>(client, hit_test_rect);
}
#if DCHECK_IS_ON()
......
......@@ -36,9 +36,6 @@ bool PaintController::UseCachedItemIfPossible(const DisplayItemClient& client,
if (usage_ == kTransient)
return false;
if (DisplayItemConstructionIsDisabled())
return false;
if (!ClientCacheIsValid(client))
return false;
......@@ -89,7 +86,7 @@ bool PaintController::UseCachedSubsequenceIfPossible(
if (usage_ == kTransient)
return false;
if (DisplayItemConstructionIsDisabled() || SubsequenceCachingIsDisabled())
if (SubsequenceCachingIsDisabled())
return false;
if (!ClientCacheIsValid(client))
......@@ -227,7 +224,6 @@ void PaintController::EndSubsequence(const DisplayItemClient& client,
}
void PaintController::DidAppendItem(DisplayItem& display_item) {
DCHECK(!construction_disabled_);
if (usage_ == kTransient)
return;
......
......@@ -103,9 +103,6 @@ class PLATFORM_EXPORT PaintController {
"DisplayItem subclass alignment is not a factor of "
"kDisplayItemAlignment.");
if (DisplayItemConstructionIsDisabled())
return;
EnsureNewDisplayItemListInitialCapacity();
DisplayItemClass& display_item =
new_display_item_list_.AllocateAndConstruct<DisplayItemClass>(
......@@ -188,15 +185,6 @@ class PLATFORM_EXPORT PaintController {
return GetPaintArtifact().PaintChunks();
}
// For micro benchmarking of record time. If true, display item construction
// is disabled to isolate the costs of construction in performance metrics.
bool DisplayItemConstructionIsDisabled() const {
return construction_disabled_;
}
void SetDisplayItemConstructionIsDisabled(bool disable) {
construction_disabled_ = disable;
}
// For micro benchmarking of record time. If true, subsequence caching is
// disabled to test the cost of display item caching.
bool SubsequenceCachingIsDisabled() const {
......@@ -341,7 +329,6 @@ class PLATFORM_EXPORT PaintController {
DisplayItemList new_display_item_list_;
PaintChunker new_paint_chunks_;
bool construction_disabled_ = false;
bool subsequence_caching_disabled_ = false;
bool cache_is_all_invalid_ = true;
......
......@@ -16,11 +16,6 @@ PaintRecordBuilder::PaintRecordBuilder(
PaintController* paint_controller,
paint_preview::PaintPreviewTracker* tracker)
: paint_controller_(nullptr) {
GraphicsContext::DisabledMode disabled_mode =
GraphicsContext::kNothingDisabled;
if (containing_context && containing_context->ContextDisabled())
disabled_mode = GraphicsContext::kFullyDisabled;
if (paint_controller) {
paint_controller_ = paint_controller;
} else {
......@@ -32,8 +27,8 @@ PaintRecordBuilder::PaintRecordBuilder(
paint_controller_->UpdateCurrentPaintChunkProperties(
nullptr, PropertyTreeState::Root());
context_ = std::make_unique<GraphicsContext>(
*paint_controller_, disabled_mode, metafile, tracker);
context_ =
std::make_unique<GraphicsContext>(*paint_controller_, metafile, tracker);
if (containing_context) {
context_->SetDarkMode(containing_context->dark_mode_settings());
context_->SetDeviceScaleFactor(containing_context->DeviceScaleFactor());
......
......@@ -67,9 +67,6 @@ void ScrollHitTestDisplayItem::Record(
DCHECK_NE(&paint_controller.CurrentPaintChunkProperties().Transform(),
scroll_offset_node);
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
if (paint_controller.UseCachedItemIfPossible(client, type))
return;
......
......@@ -136,9 +136,6 @@ void ScrollbarDisplayItem::Record(
const TransformPaintPropertyNode* scroll_translation,
CompositorElementId element_id) {
PaintController& paint_controller = context.GetPaintController();
if (paint_controller.DisplayItemConstructionIsDisabled())
return;
// Must check PaintController::UseCachedItemIfPossible before this function.
DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
!paint_controller.UseCachedItemIfPossible(client, type));
......
......@@ -21,7 +21,7 @@ class PaintController;
// of DisplayItems, and supports caching via a CachedDisplayItem with the
// CachedSubsequence DisplayItem type.
//
// Also note that useCachedSubsequenceIfPossible is not sufficient to determine
// Also note that UseCachedSubsequenceIfPossible is not sufficient to determine
// whether a CachedSubsequence can be used. In particular, the client is
// responsible for checking that none of the DisplayItemClients that contribute
// to the subsequence have been invalidated.
......@@ -39,14 +39,10 @@ class SubsequenceRecorder final {
: paint_controller_(context.GetPaintController()),
client_(client),
start_(0) {
if (!paint_controller_.DisplayItemConstructionIsDisabled())
start_ = paint_controller_.BeginSubsequence();
start_ = paint_controller_.BeginSubsequence();
}
~SubsequenceRecorder() {
if (!paint_controller_.DisplayItemConstructionIsDisabled())
paint_controller_.EndSubsequence(client_, start_);
}
~SubsequenceRecorder() { paint_controller_.EndSubsequence(client_, start_); }
private:
PaintController& paint_controller_;
......
......@@ -81,20 +81,13 @@ class RasterizeAndRecordMicro(legacy_page_test.LegacyPageTest):
paint_op_memory_usage)
results.AddMeasurement('paint_op_count', 'count', paint_op_count)
record_time_painting_disabled = data['record_time_painting_disabled_ms']
record_time_caching_disabled = data['record_time_caching_disabled_ms']
record_time_construction_disabled = \
data['record_time_construction_disabled_ms']
record_time_subsequence_caching_disabled = \
data['record_time_subsequence_caching_disabled_ms']
record_time_partial_invalidation = \
data['record_time_partial_invalidation_ms']
results.AddMeasurement('record_time_painting_disabled', 'ms',
record_time_painting_disabled)
results.AddMeasurement('record_time_caching_disabled', 'ms',
record_time_caching_disabled)
results.AddMeasurement('record_time_construction_disabled', 'ms',
record_time_construction_disabled)
results.AddMeasurement('record_time_subsequence_caching_disabled', 'ms',
record_time_subsequence_caching_disabled)
results.AddMeasurement('record_time_partial_invalidation_ms', 'ms',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment