Use sampling instead of (deprecated) filter-quality (flutter/engine#24101)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkSamplingOptions.h"
|
||||
|
||||
class GrDirectContext;
|
||||
|
||||
@@ -25,7 +26,7 @@ class Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality quality) = 0;
|
||||
const SkSamplingOptions& sampling) = 0;
|
||||
|
||||
// Called from raster thread.
|
||||
virtual void OnGrContextCreated() = 0;
|
||||
|
||||
@@ -12,12 +12,12 @@ TextureLayer::TextureLayer(const SkPoint& offset,
|
||||
const SkSize& size,
|
||||
int64_t texture_id,
|
||||
bool freeze,
|
||||
SkFilterQuality filter_quality)
|
||||
const SkSamplingOptions& sampling)
|
||||
: offset_(offset),
|
||||
size_(size),
|
||||
texture_id_(texture_id),
|
||||
freeze_(freeze),
|
||||
filter_quality_(filter_quality) {}
|
||||
sampling_(sampling) {}
|
||||
|
||||
void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
|
||||
TRACE_EVENT0("flutter", "TextureLayer::Preroll");
|
||||
@@ -42,7 +42,7 @@ void TextureLayer::Paint(PaintContext& context) const {
|
||||
return;
|
||||
}
|
||||
texture->Paint(*context.leaf_nodes_canvas, paint_bounds(), freeze_,
|
||||
context.gr_context, filter_quality_);
|
||||
context.gr_context, sampling_);
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -18,7 +18,7 @@ class TextureLayer : public Layer {
|
||||
const SkSize& size,
|
||||
int64_t texture_id,
|
||||
bool freeze,
|
||||
SkFilterQuality filter_quality);
|
||||
const SkSamplingOptions& sampling);
|
||||
|
||||
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
|
||||
void Paint(PaintContext& context) const override;
|
||||
@@ -28,7 +28,7 @@ class TextureLayer : public Layer {
|
||||
SkSize size_;
|
||||
int64_t texture_id_;
|
||||
bool freeze_;
|
||||
SkFilterQuality filter_quality_;
|
||||
SkSamplingOptions sampling_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(TextureLayer);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ TEST_F(TextureLayerTest, InvalidTexture) {
|
||||
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
|
||||
const SkSize layer_size = SkSize::Make(8.0f, 8.0f);
|
||||
auto layer = std::make_shared<TextureLayer>(layer_offset, layer_size, 0,
|
||||
false, kNone_SkFilterQuality);
|
||||
false, SkSamplingOptions());
|
||||
|
||||
layer->Preroll(preroll_context(), SkMatrix());
|
||||
EXPECT_EQ(layer->paint_bounds(),
|
||||
@@ -38,7 +38,7 @@ TEST_F(TextureLayerTest, PaintingEmptyLayerDies) {
|
||||
const int64_t texture_id = 0;
|
||||
auto mock_texture = std::make_shared<MockTexture>(texture_id);
|
||||
auto layer = std::make_shared<TextureLayer>(
|
||||
layer_offset, layer_size, texture_id, false, kNone_SkFilterQuality);
|
||||
layer_offset, layer_size, texture_id, false, SkSamplingOptions());
|
||||
|
||||
// Ensure the texture is located by the Layer.
|
||||
preroll_context()->texture_registry.RegisterTexture(mock_texture);
|
||||
@@ -57,7 +57,8 @@ TEST_F(TextureLayerTest, PaintBeforePreollDies) {
|
||||
const int64_t texture_id = 0;
|
||||
auto mock_texture = std::make_shared<MockTexture>(texture_id);
|
||||
auto layer = std::make_shared<TextureLayer>(
|
||||
layer_offset, layer_size, texture_id, false, kLow_SkFilterQuality);
|
||||
layer_offset, layer_size, texture_id, false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
// Ensure the texture is located by the Layer.
|
||||
preroll_context()->texture_registry.RegisterTexture(mock_texture);
|
||||
@@ -73,7 +74,8 @@ TEST_F(TextureLayerTest, PaintingWithLowFilterQuality) {
|
||||
const int64_t texture_id = 0;
|
||||
auto mock_texture = std::make_shared<MockTexture>(texture_id);
|
||||
auto layer = std::make_shared<TextureLayer>(
|
||||
layer_offset, layer_size, texture_id, false, kLow_SkFilterQuality);
|
||||
layer_offset, layer_size, texture_id, false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
// Ensure the texture is located by the Layer.
|
||||
preroll_context()->texture_registry.RegisterTexture(mock_texture);
|
||||
@@ -88,7 +90,7 @@ TEST_F(TextureLayerTest, PaintingWithLowFilterQuality) {
|
||||
EXPECT_EQ(mock_texture->paint_calls(),
|
||||
std::vector({MockTexture::PaintCall{
|
||||
mock_canvas(), layer->paint_bounds(), false, nullptr,
|
||||
kLow_SkFilterQuality}}));
|
||||
SkSamplingOptions(SkFilterMode::kLinear)}}));
|
||||
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const {
|
||||
std::abs(bounds.size().width() - image_->dimensions().width()) <= 1 &&
|
||||
std::abs(bounds.size().height() - image_->dimensions().height()) <= 1);
|
||||
canvas.resetMatrix();
|
||||
canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint);
|
||||
canvas.drawImage(image_, bounds.fLeft, bounds.fTop, SkSamplingOptions(),
|
||||
paint);
|
||||
}
|
||||
|
||||
RasterCache::RasterCache(size_t access_threshold,
|
||||
|
||||
@@ -13,21 +13,21 @@ void MockTexture::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
paint_calls_.emplace_back(
|
||||
PaintCall{canvas, bounds, freeze, context, filter_quality});
|
||||
PaintCall{canvas, bounds, freeze, context, sampling});
|
||||
}
|
||||
|
||||
bool operator==(const MockTexture::PaintCall& a,
|
||||
const MockTexture::PaintCall& b) {
|
||||
return &a.canvas == &b.canvas && a.bounds == b.bounds &&
|
||||
a.context == b.context && a.freeze == b.freeze &&
|
||||
a.filter_quality == b.filter_quality;
|
||||
a.sampling == b.sampling;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const MockTexture::PaintCall& data) {
|
||||
return os << &data.canvas << " " << data.bounds << " " << data.context << " "
|
||||
<< data.freeze << " " << data.filter_quality;
|
||||
<< data.freeze << " " << data.sampling;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -21,7 +21,7 @@ class MockTexture : public Texture {
|
||||
SkRect bounds;
|
||||
bool freeze;
|
||||
GrDirectContext* context;
|
||||
SkFilterQuality filter_quality;
|
||||
SkSamplingOptions sampling;
|
||||
};
|
||||
|
||||
explicit MockTexture(int64_t textureId);
|
||||
@@ -31,7 +31,7 @@ class MockTexture : public Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
void OnGrContextCreated() override { gr_context_created_ = true; }
|
||||
void OnGrContextDestroyed() override { gr_context_destroyed_ = true; }
|
||||
|
||||
@@ -29,15 +29,14 @@ TEST(MockTextureTest, PaintCalls) {
|
||||
SkCanvas canvas;
|
||||
const SkRect paint_bounds1 = SkRect::MakeWH(1.0f, 1.0f);
|
||||
const SkRect paint_bounds2 = SkRect::MakeWH(2.0f, 2.0f);
|
||||
const auto expected_paint_calls =
|
||||
std::vector{MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr,
|
||||
kNone_SkFilterQuality},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr,
|
||||
kNone_SkFilterQuality}};
|
||||
const SkSamplingOptions sampling;
|
||||
const auto expected_paint_calls = std::vector{
|
||||
MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr, sampling},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr, sampling}};
|
||||
auto texture = std::make_shared<MockTexture>(0);
|
||||
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, kNone_SkFilterQuality);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, kNone_SkFilterQuality);
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, sampling);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, sampling);
|
||||
EXPECT_EQ(texture->paint_calls(), expected_paint_calls);
|
||||
}
|
||||
|
||||
@@ -45,15 +44,14 @@ TEST(MockTextureTest, PaintCallsWithLowFilterQuality) {
|
||||
SkCanvas canvas;
|
||||
const SkRect paint_bounds1 = SkRect::MakeWH(1.0f, 1.0f);
|
||||
const SkRect paint_bounds2 = SkRect::MakeWH(2.0f, 2.0f);
|
||||
const auto expected_paint_calls =
|
||||
std::vector{MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr,
|
||||
kLow_SkFilterQuality},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr,
|
||||
kLow_SkFilterQuality}};
|
||||
const auto sampling = SkSamplingOptions(SkFilterMode::kLinear);
|
||||
const auto expected_paint_calls = std::vector{
|
||||
MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr, sampling},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr, sampling}};
|
||||
auto texture = std::make_shared<MockTexture>(0);
|
||||
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, kLow_SkFilterQuality);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, kLow_SkFilterQuality);
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, sampling);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, sampling);
|
||||
EXPECT_EQ(texture->paint_calls(), expected_paint_calls);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,9 +231,12 @@ void SceneBuilder::addTexture(double dx,
|
||||
int64_t textureId,
|
||||
bool freeze,
|
||||
int filterQuality) {
|
||||
// TODO: take sampling directly from caller: filter-quality is deprecated
|
||||
auto sampling = SkSamplingOptions(static_cast<SkFilterQuality>(filterQuality),
|
||||
SkSamplingOptions::kMedium_asMipmapLinear);
|
||||
auto layer = std::make_unique<flutter::TextureLayer>(
|
||||
SkPoint::Make(dx, dy), SkSize::Make(width, height), textureId, freeze,
|
||||
static_cast<SkFilterQuality>(filterQuality));
|
||||
sampling);
|
||||
AddLayer(std::move(layer));
|
||||
}
|
||||
|
||||
|
||||
@@ -311,6 +311,12 @@ void Canvas::drawPath(const CanvasPath* path,
|
||||
canvas_->drawPath(path->path(), *paint.paint());
|
||||
}
|
||||
|
||||
static SkSamplingOptions paint_to_sampling(const SkPaint* paint) {
|
||||
return SkSamplingOptions(
|
||||
paint ? paint->getFilterQuality() : kNone_SkFilterQuality,
|
||||
SkSamplingOptions::kMedium_asMipmapLinear);
|
||||
}
|
||||
|
||||
void Canvas::drawImage(const CanvasImage* image,
|
||||
double x,
|
||||
double y,
|
||||
@@ -324,7 +330,9 @@ void Canvas::drawImage(const CanvasImage* image,
|
||||
ToDart("Canvas.drawImage called with non-genuine Image."));
|
||||
return;
|
||||
}
|
||||
canvas_->drawImage(image->image(), x, y, paint.paint());
|
||||
// TODO: add filtering to public API, since paint's quality is deprecated
|
||||
SkSamplingOptions sampling = paint_to_sampling(paint.paint());
|
||||
canvas_->drawImage(image->image(), x, y, sampling, paint.paint());
|
||||
}
|
||||
|
||||
void Canvas::drawImageRect(const CanvasImage* image,
|
||||
@@ -348,7 +356,9 @@ void Canvas::drawImageRect(const CanvasImage* image,
|
||||
}
|
||||
SkRect src = SkRect::MakeLTRB(src_left, src_top, src_right, src_bottom);
|
||||
SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom);
|
||||
canvas_->drawImageRect(image->image(), src, dst, paint.paint(),
|
||||
// TODO: add filtering to public API, since paint's quality is deprecated
|
||||
SkSamplingOptions sampling = paint_to_sampling(paint.paint());
|
||||
canvas_->drawImageRect(image->image(), src, dst, sampling, paint.paint(),
|
||||
SkCanvas::kFast_SrcRectConstraint);
|
||||
}
|
||||
|
||||
@@ -358,12 +368,6 @@ static SkFilterMode paint_to_filter(const SkPaint* paint) {
|
||||
: SkFilterMode::kNearest;
|
||||
}
|
||||
|
||||
static SkSamplingOptions paint_to_sampling(const SkPaint* paint) {
|
||||
return SkSamplingOptions(
|
||||
paint ? paint->getFilterQuality() : kNone_SkFilterQuality,
|
||||
SkSamplingOptions::kMedium_asMipmapLinear);
|
||||
}
|
||||
|
||||
void Canvas::drawImageNine(const CanvasImage* image,
|
||||
double center_left,
|
||||
double center_top,
|
||||
|
||||
@@ -1650,7 +1650,7 @@ class MockTexture : public Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override {}
|
||||
const SkSamplingOptions&) override {}
|
||||
|
||||
void OnGrContextCreated() override {}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
if (state_ == AttachmentState::detached) {
|
||||
return;
|
||||
}
|
||||
@@ -69,9 +69,7 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
transformAroundCenter.postTranslate(0.5, 0.5);
|
||||
canvas.concat(transformAroundCenter);
|
||||
}
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(filter_quality);
|
||||
canvas.drawImage(image, 0, 0, &paint);
|
||||
canvas.drawImage(image, 0, 0, sampling, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class AndroidExternalTextureGL : public flutter::Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class IOSExternalTextureGL final : public Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -142,7 +142,7 @@ void IOSExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
EnsureTextureCacheExists();
|
||||
if (NeedUpdateTexture(freeze)) {
|
||||
auto pixelBuffer = [external_texture_.get() copyPixelBuffer];
|
||||
@@ -167,9 +167,7 @@ void IOSExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
|
||||
FML_DCHECK(image) << "Failed to create SkImage from Texture.";
|
||||
if (image) {
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(filter_quality);
|
||||
canvas.drawImage(image, bounds.x(), bounds.y(), &paint);
|
||||
canvas.drawImage(image, bounds.x(), bounds.y(), sampling, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class IOSExternalTextureMetal final : public Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -30,7 +30,7 @@ void IOSExternalTextureMetal::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
const bool needs_updated_texture = (!freeze && texture_frame_available_) || !external_image_;
|
||||
|
||||
if (needs_updated_texture) {
|
||||
@@ -51,12 +51,11 @@ void IOSExternalTextureMetal::Paint(SkCanvas& canvas,
|
||||
}
|
||||
|
||||
if (external_image_) {
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(filter_quality);
|
||||
canvas.drawImageRect(external_image_, // image
|
||||
external_image_->bounds(), // source rect
|
||||
bounds, // destination rect
|
||||
&paint, // paint
|
||||
canvas.drawImageRect(external_image_, // image
|
||||
SkRect::Make(external_image_->bounds()), // source rect
|
||||
bounds, // destination rect
|
||||
sampling,
|
||||
nullptr, // paint
|
||||
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint // constraint
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ void EmbedderExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
if (auto image = external_texture_callback_(
|
||||
Id(), //
|
||||
context, //
|
||||
@@ -32,12 +32,10 @@ void EmbedderExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
}
|
||||
|
||||
if (last_image_) {
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(filter_quality);
|
||||
if (bounds != SkRect::Make(last_image_->bounds())) {
|
||||
canvas.drawImageRect(last_image_, bounds, &paint);
|
||||
canvas.drawImageRect(last_image_, bounds, sampling);
|
||||
} else {
|
||||
canvas.drawImage(last_image_, bounds.x(), bounds.y(), &paint);
|
||||
canvas.drawImage(last_image_, bounds.x(), bounds.y(), sampling, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class EmbedderExternalTextureGL : public flutter::Texture {
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
SkFilterQuality filter_quality) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |flutter::Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -110,5 +110,14 @@ std::ostream& operator<<(std::ostream& os, const SkPaint& r) {
|
||||
<< ", AA: " << r.isAntiAlias() << ", Shader: " << r.getShader();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const SkSamplingOptions& s) {
|
||||
if (s.useCubic) {
|
||||
return os << "CubicResampler: " << s.cubic.B << ", " << s.cubic.C;
|
||||
} else {
|
||||
return os << "Filter: " << static_cast<int>(s.filter)
|
||||
<< ", Mipmap: " << static_cast<int>(s.mipmap);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "third_party/skia/include/core/SkPath.h"
|
||||
#include "third_party/skia/include/core/SkPoint3.h"
|
||||
#include "third_party/skia/include/core/SkRRect.h"
|
||||
#include "third_party/skia/include/core/SkSamplingOptions.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
@@ -29,6 +30,7 @@ extern std::ostream& operator<<(std::ostream& os, const SkPoint& r);
|
||||
extern std::ostream& operator<<(std::ostream& os, const SkISize& size);
|
||||
extern std::ostream& operator<<(std::ostream& os, const SkColor4f& r);
|
||||
extern std::ostream& operator<<(std::ostream& os, const SkPaint& r);
|
||||
extern std::ostream& operator<<(std::ostream& os, const SkSamplingOptions& s);
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
Reference in New Issue
Block a user