dont pixel snap raster cache if SUPPORT_FRACTIONAL_TRANSLATION is enabled (#34002)
diff --git a/flow/layer_snapshot_store.cc b/flow/layer_snapshot_store.cc
index 7e3cc8e..00f0ed9 100644
--- a/flow/layer_snapshot_store.cc
+++ b/flow/layer_snapshot_store.cc
@@ -12,7 +12,7 @@
LayerSnapshotData::LayerSnapshotData(int64_t layer_unique_id,
const fml::TimeDelta& duration,
const sk_sp<SkData>& snapshot,
- const SkIRect& bounds)
+ const SkRect& bounds)
: layer_unique_id_(layer_unique_id),
duration_(duration),
snapshot_(snapshot),
diff --git a/flow/layer_snapshot_store.h b/flow/layer_snapshot_store.h
index fd255b5..eb444d2 100644
--- a/flow/layer_snapshot_store.h
+++ b/flow/layer_snapshot_store.h
@@ -26,7 +26,7 @@
LayerSnapshotData(int64_t layer_unique_id,
const fml::TimeDelta& duration,
const sk_sp<SkData>& snapshot,
- const SkIRect& bounds);
+ const SkRect& bounds);
~LayerSnapshotData() = default;
@@ -36,13 +36,13 @@
sk_sp<SkData> GetSnapshot() const { return snapshot_; }
- SkIRect GetBounds() const { return bounds_; }
+ SkRect GetBounds() const { return bounds_; }
private:
const int64_t layer_unique_id_;
const fml::TimeDelta duration_;
const sk_sp<SkData> snapshot_;
- const SkIRect bounds_;
+ const SkRect bounds_;
};
/// Collects snapshots of layers during frame rasterization.
diff --git a/flow/layers/display_list_layer.cc b/flow/layers/display_list_layer.cc
index 5c02735..7ccea1e 100644
--- a/flow/layers/display_list_layer.cc
+++ b/flow/layers/display_list_layer.cc
@@ -155,7 +155,7 @@
const fml::TimeDelta offscreen_render_time =
fml::TimePoint::Now() - start_time;
- const SkIRect device_bounds =
+ const SkRect device_bounds =
RasterCache::GetDeviceBounds(paint_bounds(), ctm);
sk_sp<SkData> raster_data = offscreen_surface->GetRasterData(true);
LayerSnapshotData snapshot_data(unique_id(), offscreen_render_time,
diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc
index b5d1689..e6dbf96 100644
--- a/flow/raster_cache.cc
+++ b/flow/raster_cache.cc
@@ -29,11 +29,11 @@
void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const {
TRACE_EVENT0("flutter", "RasterCacheResult::draw");
SkAutoCanvasRestore auto_restore(&canvas, true);
- SkIRect bounds =
+
+ SkRect bounds =
RasterCache::GetDeviceBounds(logical_rect_, canvas.getTotalMatrix());
- FML_DCHECK(
- std::abs(bounds.size().width() - image_->dimensions().width()) <= 1 &&
- std::abs(bounds.size().height() - image_->dimensions().height()) <= 1);
+ FML_DCHECK(std::abs(bounds.width() - image_->dimensions().width()) <= 1 &&
+ std::abs(bounds.height() - image_->dimensions().height()) <= 1);
canvas.resetMatrix();
flow_.Step();
canvas.drawImage(image_, bounds.fLeft, bounds.fTop, SkSamplingOptions(),
@@ -125,10 +125,14 @@
const char* type,
const std::function<void(SkCanvas*)>& draw_function) {
TRACE_EVENT0("flutter", "RasterCachePopulate");
- SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
- const SkImageInfo image_info = SkImageInfo::MakeN32Premul(
- cache_rect.width(), cache_rect.height(), sk_ref_sp(dst_color_space));
+ SkRect dest_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
+ // we always round out here so that the texture is integer sized.
+ int width = SkScalarCeilToInt(dest_rect.width());
+ int height = SkScalarCeilToInt(dest_rect.height());
+
+ const SkImageInfo image_info =
+ SkImageInfo::MakeN32Premul(width, height, sk_ref_sp(dst_color_space));
sk_sp<SkSurface> surface =
context
@@ -141,7 +145,7 @@
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorTRANSPARENT);
- canvas->translate(-cache_rect.left(), -cache_rect.top());
+ canvas->translate(-dest_rect.left(), -dest_rect.top());
canvas->concat(ctm);
draw_function(canvas);
diff --git a/flow/raster_cache.h b/flow/raster_cache.h
index 51d1d17..f3dbac5 100644
--- a/flow/raster_cache.h
+++ b/flow/raster_cache.h
@@ -149,12 +149,13 @@
const SkMatrix& ctm,
bool checkerboard) const;
- static SkIRect GetDeviceBounds(const SkRect& rect, const SkMatrix& ctm) {
+ static SkRect GetDeviceBounds(const SkRect& rect, const SkMatrix& ctm) {
SkRect device_rect;
ctm.mapRect(&device_rect, rect);
- SkIRect bounds;
- device_rect.roundOut(&bounds);
- return bounds;
+#ifndef SUPPORT_FRACTIONAL_TRANSLATION
+ device_rect.roundOut(&device_rect);
+#endif
+ return device_rect;
}
/**
diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc
index ff0234d..cfb37b8 100644
--- a/flow/raster_cache_unittests.cc
+++ b/flow/raster_cache_unittests.cc
@@ -330,6 +330,19 @@
ASSERT_TRUE(cache.Draw(*picture, canvas));
}
+// The device rect is pixel snapped if SUPPORT_FRACTIONAL_TRANSLATION
+// is disabled.
+TEST(RasterCache, ComputeDeviceRectBasedOnFractionalTranslation) {
+ SkRect logical_rect = SkRect::MakeLTRB(0, 0, 300.2, 300.3);
+ SkMatrix ctm = SkMatrix::MakeAll(2.0, 0, 0, 0, 2.0, 0, 0, 0, 1);
+ auto result = RasterCache::GetDeviceBounds(logical_rect, ctm);
+#ifndef SUPPORT_FRACTIONAL_TRANSLATION
+ ASSERT_EQ(result, SkRect::MakeLTRB(0.0, 0.0, 601.0, 601.0));
+#else
+ ASSERT_EQ(result, SkRect::MakeLTRB(0.0, 0.0, 600.4, 600.6));
+#endif
+}
+
// Construct a cache result whose device target rectangle rounds out to be one
// pixel wider than the cached image. Verify that it can be drawn without
// triggering any assertions.
diff --git a/flow/testing/mock_raster_cache.cc b/flow/testing/mock_raster_cache.cc
index dafa827..4f1cf2c 100644
--- a/flow/testing/mock_raster_cache.cc
+++ b/flow/testing/mock_raster_cache.cc
@@ -9,7 +9,7 @@
namespace flutter {
namespace testing {
-MockRasterCacheResult::MockRasterCacheResult(SkIRect device_rect)
+MockRasterCacheResult::MockRasterCacheResult(SkRect device_rect)
: RasterCacheResult(nullptr, SkRect::MakeEmpty(), "RasterCacheFlow::test"),
device_rect_(device_rect) {}
@@ -20,7 +20,7 @@
SkColorSpace* dst_color_space,
bool checkerboard) const {
SkRect logical_rect = picture->cullRect();
- SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
+ SkRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
return std::make_unique<MockRasterCacheResult>(cache_rect);
}
@@ -32,7 +32,7 @@
SkColorSpace* dst_color_space,
bool checkerboard) const {
SkRect logical_rect = display_list->bounds();
- SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
+ SkRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
return std::make_unique<MockRasterCacheResult>(cache_rect);
}
@@ -44,7 +44,7 @@
const SkMatrix& ctm,
bool checkerboard) const {
SkRect logical_rect = layer->paint_bounds();
- SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
+ SkRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);
return std::make_unique<MockRasterCacheResult>(cache_rect);
}
diff --git a/flow/testing/mock_raster_cache.h b/flow/testing/mock_raster_cache.h
index 1bd54ab..d992172 100644
--- a/flow/testing/mock_raster_cache.h
+++ b/flow/testing/mock_raster_cache.h
@@ -26,11 +26,13 @@
*/
class MockRasterCacheResult : public RasterCacheResult {
public:
- explicit MockRasterCacheResult(SkIRect device_rect);
+ explicit MockRasterCacheResult(SkRect device_rect);
void draw(SkCanvas& canvas, const SkPaint* paint = nullptr) const override{};
- SkISize image_dimensions() const override { return device_rect_.size(); };
+ SkISize image_dimensions() const override {
+ return SkSize::Make(device_rect_.width(), device_rect_.height()).toCeil();
+ };
int64_t image_bytes() const override {
return image_dimensions().area() *
@@ -38,7 +40,7 @@
}
private:
- SkIRect device_rect_;
+ SkRect device_rect_;
};
/**
diff --git a/shell/common/shell.cc b/shell/common/shell.cc
index faa8461..eb95199 100644
--- a/shell/common/shell.cc
+++ b/shell/common/shell.cc
@@ -1819,7 +1819,7 @@
result.AddMember("duration_micros", snapshot.GetDuration().ToMicroseconds(),
allocator);
- const SkIRect bounds = snapshot.GetBounds();
+ const SkRect bounds = snapshot.GetBounds();
result.AddMember("top", bounds.top(), allocator);
result.AddMember("left", bounds.left(), allocator);
result.AddMember("width", bounds.width(), allocator);