blob: 1dbedb10e79d1cb114b6c174e83fc8ab6199b150 [file] [log] [blame]
// Copyright 2015 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_DISPLAY_ITEM_LIST_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_DISPLAY_ITEM_LIST_H_
#include "third_party/blink/renderer/platform/graphics/contiguous_container.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
class JSONArray;
// kDisplayItemAlignment must be a multiple of alignof(derived display item) for
// each derived display item; the ideal value is the least common multiple.
// The validity of kDisplayItemAlignment and kMaximumDisplayItemSize are checked
// in PaintController::CreateAndAppend().
static constexpr wtf_size_t kDisplayItemAlignment =
alignof(ScrollbarDisplayItem);
static constexpr wtf_size_t kMaximumDisplayItemSize =
sizeof(ScrollbarDisplayItem);
// A container for a list of display items.
class PLATFORM_EXPORT DisplayItemList
: public ContiguousContainer<DisplayItem, kDisplayItemAlignment> {
public:
static constexpr wtf_size_t kDefaultCapacityInBytes = 512;
// Using 0 as the default value to make 0 also fall back to
// kDefaultCapacityInBytes.
explicit DisplayItemList(wtf_size_t initial_capacity_in_bytes = 0)
: ContiguousContainer(kMaximumDisplayItemSize,
initial_capacity_in_bytes
? initial_capacity_in_bytes
: kDefaultCapacityInBytes) {}
DisplayItem& AppendByMoving(DisplayItem& item) {
SECURITY_CHECK(!item.IsTombstone());
DisplayItem& result =
ContiguousContainer::AppendByMoving(item, item.DerivedSize());
SetupTombstone(item, result);
return result;
}
DisplayItem& ReplaceLastByMoving(DisplayItem& item) {
SECURITY_CHECK(!item.IsTombstone());
DCHECK_EQ(back().DerivedSize(), item.DerivedSize());
DisplayItem& result =
ContiguousContainer::ReplaceLastByMoving(item, item.DerivedSize());
SetupTombstone(item, result);
return result;
}
// Useful for iterating with a range-based for loop.
template <typename Iterator>
class Range {
public:
Range(const Iterator& begin, const Iterator& end)
: begin_(begin), end_(end) {}
Iterator begin() const { return begin_; }
Iterator end() const { return end_; }
wtf_size_t size() const { return end_ - begin_; }
// To meet the requirement of gmock ElementsAre().
using value_type = DisplayItem;
using const_iterator = DisplayItemList::const_iterator;
private:
Iterator begin_;
Iterator end_;
};
// In most cases, we should use PaintChunkSubset::Iterator::DisplayItems()
// instead of these.
Range<iterator> ItemsInRange(wtf_size_t begin_index, wtf_size_t end_index) {
return Range<iterator>(begin() + begin_index, begin() + end_index);
}
Range<const_iterator> ItemsInRange(wtf_size_t begin_index,
wtf_size_t end_index) const {
return Range<const_iterator>(begin() + begin_index, begin() + end_index);
}
#if DCHECK_IS_ON()
enum JsonOptions {
kDefault = 0,
kClientKnownToBeAlive = 1,
// Only show a compact representation of the display item list. This flag
// cannot be used with additional flags such as kShowPaintRecords.
kCompact = 1 << 1,
kShowPaintRecords = 1 << 2,
kShowOnlyDisplayItemTypes = 1 << 3
};
typedef unsigned JsonFlags;
static std::unique_ptr<JSONArray> DisplayItemsAsJSON(
wtf_size_t first_item_index,
const Range<const_iterator>& display_items,
JsonFlags);
#endif // DCHECK_IS_ON()
private:
// Called by AppendByMoving() and ReplaceLastByMoving() which created a
// tombstone/"dead display item" that can be safely destructed but should
// never be used except for debugging and raster invalidation.
void SetupTombstone(DisplayItem& item, const DisplayItem& new_item) {
DCHECK(item.IsTombstone());
// We need |visual_rect_| and |outset_for_raster_effects_| of the old
// display item for raster invalidation. Also, the fields that make up the
// ID (|client_|, |type_| and |fragment_|) need to match. As their values
// were either initialized to default values or were left uninitialized by
// DisplayItem's default constructor, now copy their original values back
// from |result|.
item.client_ = new_item.client_;
item.type_ = new_item.type_;
item.fragment_ = new_item.fragment_;
DCHECK_EQ(item.GetId(), new_item.GetId());
item.visual_rect_ = new_item.visual_rect_;
item.raster_effect_outset_ = new_item.raster_effect_outset_;
}
};
using DisplayItemIterator = DisplayItemList::const_iterator;
using DisplayItemRange = DisplayItemList::Range<DisplayItemIterator>;
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_DISPLAY_ITEM_LIST_H_