Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions flow/layers/image_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,9 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
RasterCacheResult layer_cache =
context.raster_cache->Get((Layer*)this, ctm);
if (layer_cache.is_valid()) {
layer_cache.draw(*context.leaf_nodes_canvas);
return;
}
if (context.raster_cache &&
context.raster_cache->Draw(this, *context.leaf_nodes_canvas)) {
return;
}

SkPaint paint;
Expand Down
12 changes: 4 additions & 8 deletions flow/layers/opacity_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,10 @@ void OpacityLayer::Paint(PaintContext& context) const {
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
ContainerLayer* container = GetChildContainer();
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
RasterCacheResult child_cache = context.raster_cache->Get(container, ctm);
if (child_cache.is_valid()) {
child_cache.draw(*context.leaf_nodes_canvas, &paint);
return;
}
if (context.raster_cache &&
context.raster_cache->Draw(GetChildContainer(),
*context.leaf_nodes_canvas, &paint)) {
return;
}

// Skia may clip the content with saveLayerBounds (although it's not a
Expand Down
13 changes: 4 additions & 9 deletions flow/layers/picture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,10 @@ void PictureLayer::Paint(PaintContext& context) const {
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
RasterCacheResult result = context.raster_cache->Get(*picture(), ctm);
if (result.is_valid()) {
TRACE_EVENT_INSTANT0("flutter", "raster cache hit");

result.draw(*context.leaf_nodes_canvas);
return;
}
if (context.raster_cache &&
context.raster_cache->Draw(*picture(), *context.leaf_nodes_canvas)) {
TRACE_EVENT_INSTANT0("flutter", "raster cache hit");
return;
}
picture()->playback(context.leaf_nodes_canvas);
}
Expand Down
29 changes: 20 additions & 9 deletions flow/raster_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,33 +210,44 @@ bool RasterCache::Prepare(GrContext* context,
return true;
}

RasterCacheResult RasterCache::Get(const SkPicture& picture,
const SkMatrix& ctm) const {
PictureRasterCacheKey cache_key(picture.uniqueID(), ctm);
bool RasterCache::Draw(const SkPicture& picture, SkCanvas& canvas) const {
PictureRasterCacheKey cache_key(picture.uniqueID(), canvas.getTotalMatrix());
auto it = picture_cache_.find(cache_key);
if (it == picture_cache_.end()) {
return RasterCacheResult();
return false;
}

Entry& entry = it->second;
entry.access_count++;
entry.used_this_frame = true;

return entry.image;
if (entry.image.is_valid()) {
entry.image.draw(canvas);
return true;
}

return false;
}

RasterCacheResult RasterCache::Get(Layer* layer, const SkMatrix& ctm) const {
LayerRasterCacheKey cache_key(layer->unique_id(), ctm);
bool RasterCache::Draw(const Layer* layer,
SkCanvas& canvas,
SkPaint* paint) const {
LayerRasterCacheKey cache_key(layer->unique_id(), canvas.getTotalMatrix());
auto it = layer_cache_.find(cache_key);
if (it == layer_cache_.end()) {
return RasterCacheResult();
return false;
}

Entry& entry = it->second;
entry.access_count++;
entry.used_this_frame = true;

return entry.image;
if (entry.image.is_valid()) {
entry.image.draw(canvas, paint);
return true;
}

return false;
}

void RasterCache::SweepAfterFrame() {
Expand Down
15 changes: 13 additions & 2 deletions flow/raster_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,20 @@ class RasterCache {

void Prepare(PrerollContext* context, Layer* layer, const SkMatrix& ctm);

RasterCacheResult Get(const SkPicture& picture, const SkMatrix& ctm) const;
// Find the raster cache for the picture and draw it to the canvas.
//
// Return true if it's found and drawn.
bool Draw(const SkPicture& picture, SkCanvas& canvas) const;

RasterCacheResult Get(Layer* layer, const SkMatrix& ctm) const;
// Find the raster cache for the layer and draw it to the canvas.
//
// Addional paint can be given to change how the raster cache is drawn (e.g.,
// draw the raster cache with some opacity).
//
// Return true if the layer raster cache is found and drawn.
bool Draw(const Layer* layer,
SkCanvas& canvas,
SkPaint* paint = nullptr) const;

void SweepAfterFrame();

Expand Down
41 changes: 26 additions & 15 deletions flow/raster_cache_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,28 @@ TEST(RasterCache, ThresholdIsRespected) {

sk_sp<SkImage> image;

SkCanvas dummy_canvas;

sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
ASSERT_FALSE(
cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
// 1st access.
ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));

cache.SweepAfterFrame();

ASSERT_FALSE(
cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));

// 2st access.
ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
// 2nd access.
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));

cache.SweepAfterFrame();

// Now Prepare should cache it.
ASSERT_TRUE(
cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
ASSERT_TRUE(cache.Get(*picture, matrix).is_valid());
ASSERT_TRUE(cache.Draw(*picture, dummy_canvas));
}

TEST(RasterCache, AccessThresholdOfZeroDisablesCaching) {
Expand All @@ -71,11 +73,13 @@ TEST(RasterCache, AccessThresholdOfZeroDisablesCaching) {

sk_sp<SkImage> image;

SkCanvas dummy_canvas;

sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
ASSERT_FALSE(
cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));

ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
}

TEST(RasterCache, PictureCacheLimitPerFrameIsRespectedWhenZero) {
Expand All @@ -88,11 +92,13 @@ TEST(RasterCache, PictureCacheLimitPerFrameIsRespectedWhenZero) {

sk_sp<SkImage> image;

SkCanvas dummy_canvas;

sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
ASSERT_FALSE(
cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));

ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
}

TEST(RasterCache, SweepsRemoveUnusedFrames) {
Expand All @@ -105,21 +111,23 @@ TEST(RasterCache, SweepsRemoveUnusedFrames) {

sk_sp<SkImage> image;

SkCanvas dummy_canvas;

sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true,
false)); // 1
ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));

cache.SweepAfterFrame();

ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true,
false)); // 2
ASSERT_TRUE(cache.Get(*picture, matrix).is_valid());
ASSERT_TRUE(cache.Draw(*picture, dummy_canvas));

cache.SweepAfterFrame();
cache.SweepAfterFrame(); // Extra frame without a Get image access.

ASSERT_FALSE(cache.Get(*picture, matrix).is_valid());
ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
}

// Construct a cache result whose device target rectangle rounds out to be one
Expand All @@ -139,19 +147,22 @@ TEST(RasterCache, DeviceRectRoundOut) {

SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1);

SkCanvas canvas(100, 100, nullptr);
canvas.setMatrix(ctm);

sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
ASSERT_FALSE(
cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false));
ASSERT_FALSE(cache.Get(*picture, ctm).is_valid());
ASSERT_FALSE(cache.Draw(*picture, canvas));
cache.SweepAfterFrame();
ASSERT_TRUE(cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false));
ASSERT_TRUE(cache.Get(*picture, ctm).is_valid());
ASSERT_TRUE(cache.Draw(*picture, canvas));

SkCanvas canvas(100, 100, nullptr);
canvas.setMatrix(ctm);
canvas.translate(248, 0);

cache.Get(*picture, ctm).draw(canvas);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
canvas.setMatrix(RasterCache::GetIntegralTransCTM(canvas.getTotalMatrix()));
#endif
ASSERT_TRUE(cache.Draw(*picture, canvas));
}

} // namespace testing
Expand Down