blob: 1f78695231ce57869287f269829cf8bd1e1ddf51 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/graphics/paint/DisplayItemList.h"
#include "platform/graphics/LoggingCanvas.h"
#include "platform/graphics/paint/DrawingDisplayItem.h"
#include "platform/graphics/paint/PaintChunk.h"
#ifndef NDEBUG
#include "platform/wtf/text/WTFString.h"
#endif
namespace blink {
DisplayItem& DisplayItemList::AppendByMoving(DisplayItem& item) {
#ifndef NDEBUG
String original_debug_string = item.AsDebugString();
#endif
DCHECK(item.HasValidClient());
DisplayItem& result =
ContiguousContainer::AppendByMoving(item, item.DerivedSize());
// ContiguousContainer::appendByMoving() calls an in-place constructor
// on item which replaces it with a tombstone/"dead display item" that
// can be safely destructed but should never be used.
DCHECK(!item.HasValidClient());
#ifndef NDEBUG
// Save original debug string in the old item to help debugging.
item.SetClientDebugString(original_debug_string);
#endif
return result;
}
void DisplayItemList::AppendVisualRect(const IntRect& visual_rect) {
visual_rects_.push_back(visual_rect);
}
DisplayItemList::Range<DisplayItemList::iterator>
DisplayItemList::ItemsInPaintChunk(const PaintChunk& paint_chunk) {
return Range<iterator>(begin() + paint_chunk.begin_index,
begin() + paint_chunk.end_index);
}
DisplayItemList::Range<DisplayItemList::const_iterator>
DisplayItemList::ItemsInPaintChunk(const PaintChunk& paint_chunk) const {
return Range<const_iterator>(begin() + paint_chunk.begin_index,
begin() + paint_chunk.end_index);
}
std::unique_ptr<JSONArray> DisplayItemList::SubsequenceAsJSON(
size_t begin_index,
size_t end_index,
JsonFlags options) const {
std::unique_ptr<JSONArray> json_array = JSONArray::Create();
size_t i = 0;
for (auto it = begin() + begin_index; it != begin() + end_index; ++it, ++i) {
std::unique_ptr<JSONObject> json = JSONObject::Create();
const DisplayItem& display_item = *it;
if ((options & kSkipNonDrawings) && !display_item.IsDrawing())
continue;
json->SetInteger("index", i);
#ifndef NDEBUG
StringBuilder string_builder;
display_item.DumpPropertiesAsDebugString(string_builder);
if (options & kShownOnlyDisplayItemTypes) {
json->SetString("type",
DisplayItem::TypeAsDebugString(display_item.GetType()));
} else {
json->SetString("properties", string_builder.ToString());
}
#endif
if (display_item.HasValidClient()) {
#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
if (!display_item.Client().IsAlive()) {
json->SetBoolean("clientIsAlive", true);
} else {
#else
if (options & kShowClientDebugName) {
#endif
json->SetString(
"clientDebugName",
String::Format("clientDebugName: \"%s\"",
display_item.Client().DebugName().Ascii().data()));
}
#ifndef NDEBUG
if ((options & kShowPaintRecords) && display_item.IsDrawing()) {
const DrawingDisplayItem& item =
static_cast<const DrawingDisplayItem&>(display_item);
if (const PaintRecord* record = item.GetPaintRecord().get()) {
json->SetString("record", RecordAsDebugString(
record, item.GetPaintRecordBounds()));
}
}
#endif
}
if (HasVisualRect(i)) {
IntRect local_visual_rect = VisualRect(i);
json->SetString(
"visualRect",
String::Format("[%d,%d %dx%d]", local_visual_rect.X(),
local_visual_rect.Y(), local_visual_rect.Width(),
local_visual_rect.Height()));
}
json_array->PushObject(std::move(json));
}
return json_array;
}
} // namespace blink