blob: b53889e1620ed2c5e798c3ac172be87078207e6b [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 PaintChunk_h
#define PaintChunk_h
#include <iosfwd>
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/paint/DisplayItem.h"
#include "platform/graphics/paint/PaintChunkProperties.h"
#include "platform/graphics/paint/RasterInvalidationTracking.h"
#include "platform/wtf/Allocator.h"
#include "platform/wtf/Optional.h"
#include "platform/wtf/Vector.h"
namespace blink {
// A contiguous sequence of drawings with common paint properties.
//
// This is expected to be owned by the paint artifact which also owns the
// related drawings.
//
// This is a Slimming Paint v2 class.
struct PaintChunk {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
using Id = DisplayItem::Id;
PaintChunk()
: begin_index(0),
end_index(0),
outset_for_raster_effects(0),
known_to_be_opaque(false) {}
PaintChunk(size_t begin,
size_t end,
const Id* chunk_id,
const PaintChunkProperties& props)
: begin_index(begin),
end_index(end),
properties(props),
outset_for_raster_effects(0),
known_to_be_opaque(false) {
if (chunk_id)
id.emplace(*chunk_id);
}
size_t size() const {
DCHECK_GE(end_index, begin_index);
return end_index - begin_index;
}
// Check if a new PaintChunk (this) created in the latest paint matches an old
// PaintChunk created in the previous paint.
bool Matches(const PaintChunk& old) const {
return Matches(old.id ? &*old.id : nullptr);
}
bool Matches(const Id* other_id) const {
// A PaintChunk without an id doesn't match any other PaintChunks.
if (!id || !other_id)
return false;
if (*id != *other_id)
return false;
#if DCHECK_IS_ON()
DCHECK(id->client.IsAlive());
#endif
// A chunk whose client is just created should not match any cached chunk,
// even if it's id equals the old chunk's id (which may happen if this
// chunk's client is just created at the same address of the old chunk's
// deleted client).
return !id->client.IsJustCreated();
}
// Index of the first drawing in this chunk.
size_t begin_index;
// Index of the first drawing not in this chunk, so that there are
// |endIndex - beginIndex| drawings in the chunk.
size_t end_index;
// Identifier of this chunk. If it has a value, it should be unique. This is
// used to match a new chunk to a cached old chunk to track changes of chunk
// contents, so the id should be stable across document cycles. If the
// contents of the chunk can't be cached (e.g. it's created when
// PaintController is skipping the cache, normally because display items can't
// be uniquely identified), |id| is nullopt so that the chunk won't match any
// other chunk.
Optional<Id> id;
// The paint properties which apply to this chunk.
PaintChunkProperties properties;
// The total bounds of this paint chunk's contents, in the coordinate space of
// the containing transform node.
FloatRect bounds;
// Some raster effects can exceed |bounds| in the rasterization space. This
// is the maximum DisplayItemClient::VisualRectOutsetForRasterEffects() of
// all clients of items in this chunk.
float outset_for_raster_effects;
// True if the bounds are filled entirely with opaque contents.
bool known_to_be_opaque;
// SPv2 only. Rectangles that need to be re-rasterized in this chunk, in the
// coordinate space of the containing transform node.
Vector<FloatRect> raster_invalidation_rects;
Vector<RasterInvalidationInfo> raster_invalidation_tracking;
};
inline bool operator==(const PaintChunk& a, const PaintChunk& b) {
return a.begin_index == b.begin_index && a.end_index == b.end_index &&
a.id == b.id && a.properties == b.properties && a.bounds == b.bounds &&
a.known_to_be_opaque == b.known_to_be_opaque &&
a.raster_invalidation_rects == b.raster_invalidation_rects;
}
inline bool operator!=(const PaintChunk& a, const PaintChunk& b) {
return !(a == b);
}
inline bool ChunkLessThanIndex(const PaintChunk& chunk, size_t index) {
return chunk.end_index <= index;
}
inline Vector<PaintChunk>::iterator FindChunkInVectorByDisplayItemIndex(
Vector<PaintChunk>& chunks,
size_t index) {
auto chunk =
std::lower_bound(chunks.begin(), chunks.end(), index, ChunkLessThanIndex);
DCHECK(chunk == chunks.end() ||
(index >= chunk->begin_index && index < chunk->end_index));
return chunk;
}
inline Vector<PaintChunk>::const_iterator FindChunkInVectorByDisplayItemIndex(
const Vector<PaintChunk>& chunks,
size_t index) {
return FindChunkInVectorByDisplayItemIndex(
const_cast<Vector<PaintChunk>&>(chunks), index);
}
// Redeclared here to avoid ODR issues.
// See platform/testing/PaintPrinters.h.
void PrintTo(const PaintChunk&, std::ostream*);
} // namespace blink
#endif // PaintChunk_h