blob: c89941ca333804cc8b368e2c54c9419b323739f9 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// 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_RASTER_INVALIDATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_RASTER_INVALIDATOR_H_
#include "base/check_op.h"
#include "base/dcheck_is_on.h"
#include "third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/transform.h"
namespace blink {
class PaintArtifact;
class PLATFORM_EXPORT RasterInvalidator
: public GarbageCollected<RasterInvalidator> {
public:
class PLATFORM_EXPORT Callback {
public:
virtual ~Callback() = default;
virtual void InvalidateRect(const gfx::Rect&) = 0;
};
explicit RasterInvalidator(Callback& callback) : callback_(callback) {}
void Trace(Visitor*) const;
void SetTracksRasterInvalidations(bool);
RasterInvalidationTracking* GetTracking() const { return tracking_.Get(); }
RasterInvalidationTracking& EnsureTracking();
// Generate raster invalidations for a subset of the paint chunks in the
// paint artifact.
void Generate(const PaintChunkSubset&,
const gfx::Vector2dF& layer_offset,
const gfx::Size& layer_bounds,
const PropertyTreeState& layer_state);
// Called when we repainted PaintArtifact but a ContentLayerClientImpl doesn't
// have anything changed. We just need to let |old_paint_artifact_| point to
// the real old one.
void SetOldPaintArtifact(const PaintArtifact&);
const gfx::Size& LayerBounds() const { return layer_bounds_; }
size_t ApproximateUnsharedMemoryUsage() const;
void ClearOldStates();
private:
friend class DisplayItemRasterInvalidator;
friend class RasterInvalidatorTest;
struct PaintChunkInfo {
DISALLOW_NEW();
public:
PaintChunkInfo(const RasterInvalidator& invalidator,
const ChunkToLayerMapper& mapper,
const PaintChunkIterator& chunk_it)
: index_in_paint_artifact(chunk_it.IndexInPaintArtifact()),
#if DCHECK_IS_ON()
id(chunk_it->id),
#endif
bounds_in_layer(invalidator.ClipByLayerBounds(
mapper.MapVisualRect(chunk_it->drawable_bounds))),
chunk_to_layer_clip(mapper.ClipRect()),
chunk_to_layer_transform(mapper.Transform()) {
}
PaintChunkInfo(const PaintChunkInfo& old_chunk_info,
const PaintChunkIterator& chunk_it)
: index_in_paint_artifact(chunk_it.IndexInPaintArtifact()),
#if DCHECK_IS_ON()
id(chunk_it->id),
#endif
bounds_in_layer(old_chunk_info.bounds_in_layer),
chunk_to_layer_clip(old_chunk_info.chunk_to_layer_clip),
chunk_to_layer_transform(old_chunk_info.chunk_to_layer_transform) {
#if DCHECK_IS_ON()
DCHECK_EQ(id, old_chunk_info.id);
#endif
}
// The index of the chunk in the PaintArtifact. It may be different from
// the index of this PaintChunkInfo in paint_chunks_info_ when a subset of
// the paint chunks is handled by the RasterInvalidator.
wtf_size_t index_in_paint_artifact;
#if DCHECK_IS_ON()
PaintChunk::Id id;
#endif
gfx::Rect bounds_in_layer;
FloatClipRect chunk_to_layer_clip;
gfx::Transform chunk_to_layer_transform;
};
void GenerateRasterInvalidations(const PaintChunkSubset&,
bool layer_offset_or_state_changed,
bool layer_effect_changed,
Vector<PaintChunkInfo>& new_chunks_info);
ALWAYS_INLINE const PaintChunk& GetOldChunk(wtf_size_t index) const;
ALWAYS_INLINE wtf_size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk,
wtf_size_t old_index) const;
ALWAYS_INLINE void IncrementallyInvalidateChunk(
const PaintChunkInfo& old_chunk_info,
const PaintChunkInfo& new_chunk_info,
DisplayItemClientId);
// |old_or_new| indicates whether |client| is from the old or new
// PaintArtifact, so we know which one can provide the client's debug name.
enum ClientIsOldOrNew { kClientIsOld, kClientIsNew };
void AddRasterInvalidation(const gfx::Rect& rect,
DisplayItemClientId client_id,
PaintInvalidationReason reason,
ClientIsOldOrNew old_or_new) {
if (rect.IsEmpty())
return;
callback_.InvalidateRect(rect);
if (tracking_)
TrackRasterInvalidation(rect, client_id, reason, old_or_new);
}
void TrackRasterInvalidation(const gfx::Rect&,
DisplayItemClientId,
PaintInvalidationReason,
ClientIsOldOrNew);
ALWAYS_INLINE PaintInvalidationReason
ChunkPropertiesChanged(const PaintChunk& new_chunk,
const PaintChunk& old_chunk,
const PaintChunkInfo& new_chunk_info,
const PaintChunkInfo& old_chunk_info,
const PropertyTreeState& layer_state,
const float absolute_translation_tolerance,
const float other_transform_tolerance) const;
// Clip a rect in the layer space by the layer bounds.
template <typename Rect>
Rect ClipByLayerBounds(const Rect& r) const {
return IntersectRects(r, Rect(gfx::Rect(layer_bounds_)));
}
Callback& callback_;
gfx::Vector2dF layer_offset_;
gfx::Size layer_bounds_;
PropertyTreeState layer_state_ = PropertyTreeState::Root();
Vector<PaintChunkInfo> old_paint_chunks_info_;
Member<const PaintArtifact> current_paint_artifact_;
Member<const PaintArtifact> old_paint_artifact_;
Member<RasterInvalidationTracking> tracking_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_RASTER_INVALIDATOR_H_