blob: 18ff35b5294332359f12a89d7efb539049c3f386 [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_RASTER_INVALIDATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_RASTER_INVALIDATOR_H_
#include "base/callback.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/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class PaintArtifact;
class IntRect;
class PLATFORM_EXPORT RasterInvalidator {
USING_FAST_MALLOC(RasterInvalidator);
public:
using RasterInvalidationFunction =
base::RepeatingCallback<void(const IntRect&)>;
RasterInvalidator() = default;
void SetTracksRasterInvalidations(bool);
RasterInvalidationTracking* GetTracking() const {
return tracking_info_ ? &tracking_info_->tracking : nullptr;
}
RasterInvalidationTracking& EnsureTracking();
// Generate raster invalidations for a subset of the paint chunks in the
// paint artifact.
void Generate(RasterInvalidationFunction,
const PaintChunkSubset&,
const gfx::Rect& layer_bounds,
const PropertyTreeState& layer_state,
const DisplayItemClient* layer_client = nullptr);
const gfx::Rect& LayerBounds() const { return layer_bounds_; }
size_t ApproximateUnsharedMemoryUsage() const;
void ClearOldStates();
private:
friend class DisplayItemRasterInvalidator;
friend class RasterInvalidatorTest;
void UpdateClientDebugNames();
struct PaintChunkInfo {
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()) {
}
// 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
IntRect bounds_in_layer;
FloatClipRect chunk_to_layer_clip;
SkMatrix chunk_to_layer_transform;
};
void GenerateRasterInvalidations(RasterInvalidationFunction,
const PaintChunkSubset&,
const PropertyTreeState& layer_state,
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(
RasterInvalidationFunction,
const PaintChunkInfo& old_chunk_info,
const PaintChunkInfo& new_chunk_info,
const DisplayItemClient&);
// |old_or_new| indicates if |client| is known to be new (alive) and we can
// get DebugName() directly or should get from |tracking_info_
// ->old_client_debug_names|.
enum ClientIsOldOrNew { kClientIsOld, kClientIsNew };
void AddRasterInvalidation(RasterInvalidationFunction function,
const IntRect& rect,
const DisplayItemClient& client,
PaintInvalidationReason reason,
ClientIsOldOrNew old_or_new) {
if (rect.IsEmpty())
return;
function.Run(rect);
if (tracking_info_)
TrackRasterInvalidation(rect, client, reason, old_or_new);
}
void TrackRasterInvalidation(const IntRect&,
const DisplayItemClient&,
PaintInvalidationReason,
ClientIsOldOrNew);
ALWAYS_INLINE PaintInvalidationReason
ChunkPropertiesChanged(const RefCountedPropertyTreeState& new_chunk_state,
const RefCountedPropertyTreeState& old_chunk_state,
const PaintChunkInfo& new_chunk_info,
const PaintChunkInfo& old_chunk_info,
const PropertyTreeState& layer_state) const;
// Clip a rect in the layer space by the layer bounds.
template <typename Rect>
Rect ClipByLayerBounds(const Rect& r) const {
return Intersection(
r, Rect(0, 0, layer_bounds_.width(), layer_bounds_.height()));
}
gfx::Rect layer_bounds_;
Vector<PaintChunkInfo> old_paint_chunks_info_;
scoped_refptr<const PaintArtifact> old_paint_artifact_;
struct RasterInvalidationTrackingInfo {
using ClientDebugNamesMap = HashMap<const DisplayItemClient*, String>;
ClientDebugNamesMap old_client_debug_names;
RasterInvalidationTracking tracking;
};
std::unique_ptr<RasterInvalidationTrackingInfo> tracking_info_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_RASTER_INVALIDATOR_H_