From 7563775b0cdd120aa82cb11248d4b3c760322ccd Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 12 Feb 2021 13:57:23 -0500 Subject: [PATCH] Defer making skshader until we know quality --- flow/paint_utils.cc | 3 ++- lib/ui/compositing/scene_builder.cc | 4 +++- lib/ui/painting/gradient.cc | 24 +++++++++++++----------- lib/ui/painting/gradient.h | 3 +++ lib/ui/painting/image_shader.cc | 18 +++++++++++++++--- lib/ui/painting/image_shader.h | 10 ++++++++++ lib/ui/painting/paint.cc | 21 +++++++++------------ lib/ui/painting/shader.cc | 3 --- lib/ui/painting/shader.h | 11 ++++------- 9 files changed, 59 insertions(+), 38 deletions(-) diff --git a/flow/paint_utils.cc b/flow/paint_utils.cc index 38fc17979a0c3..647ca3da0bae4 100644 --- a/flow/paint_utils.cc +++ b/flow/paint_utils.cc @@ -20,7 +20,8 @@ sk_sp CreateCheckerboardShader(SkColor c1, SkColor c2, int size) { bm.eraseColor(c1); bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2); bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2); - return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat); + return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, + SkSamplingOptions()); } } // anonymous namespace diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index b9d96ead946b2..d1d8f0042654c 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -183,8 +183,10 @@ void SceneBuilder::pushShaderMask(Dart_Handle layer_handle, int blendMode) { SkRect rect = SkRect::MakeLTRB(maskRectLeft, maskRectTop, maskRectRight, maskRectBottom); + // TODO: should this come from the caller? + SkFilterQuality quality = kNone_SkFilterQuality; auto layer = std::make_shared( - shader->shader(), rect, static_cast(blendMode)); + shader->shader(quality), rect, static_cast(blendMode)); PushLayer(layer); EngineLayer::MakeRetained(layer_handle, layer); } diff --git a/lib/ui/painting/gradient.cc b/lib/ui/painting/gradient.cc index d71e75a495f94..0d2d2fc3ddb96 100644 --- a/lib/ui/painting/gradient.cc +++ b/lib/ui/painting/gradient.cc @@ -58,10 +58,10 @@ void CanvasGradient::initLinear(const tonic::Float32List& end_points, sk_matrix = ToSkMatrix(matrix4); } - set_shader(UIDartState::CreateGPUObject(SkGradientShader::MakeLinear( + sk_shader_ = UIDartState::CreateGPUObject(SkGradientShader::MakeLinear( reinterpret_cast(end_points.data()), reinterpret_cast(colors.data()), color_stops.data(), - colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr))); + colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr)); } void CanvasGradient::initRadial(double center_x, @@ -83,10 +83,10 @@ void CanvasGradient::initRadial(double center_x, sk_matrix = ToSkMatrix(matrix4); } - set_shader(UIDartState::CreateGPUObject(SkGradientShader::MakeRadial( + sk_shader_ = UIDartState::CreateGPUObject(SkGradientShader::MakeRadial( SkPoint::Make(center_x, center_y), radius, reinterpret_cast(colors.data()), color_stops.data(), - colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr))); + colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr)); } void CanvasGradient::initSweep(double center_x, @@ -109,11 +109,11 @@ void CanvasGradient::initSweep(double center_x, sk_matrix = ToSkMatrix(matrix4); } - set_shader(UIDartState::CreateGPUObject(SkGradientShader::MakeSweep( + sk_shader_ = UIDartState::CreateGPUObject(SkGradientShader::MakeSweep( center_x, center_y, reinterpret_cast(colors.data()), color_stops.data(), colors.num_elements(), tile_mode, start_angle * 180.0 / M_PI, end_angle * 180.0 / M_PI, 0, - has_matrix ? &sk_matrix : nullptr))); + has_matrix ? &sk_matrix : nullptr)); } void CanvasGradient::initTwoPointConical(double start_x, @@ -138,11 +138,13 @@ void CanvasGradient::initTwoPointConical(double start_x, sk_matrix = ToSkMatrix(matrix4); } - set_shader(UIDartState::CreateGPUObject(SkGradientShader::MakeTwoPointConical( - SkPoint::Make(start_x, start_y), start_radius, - SkPoint::Make(end_x, end_y), end_radius, - reinterpret_cast(colors.data()), color_stops.data(), - colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr))); + sk_shader_ = + UIDartState::CreateGPUObject(SkGradientShader::MakeTwoPointConical( + SkPoint::Make(start_x, start_y), start_radius, + SkPoint::Make(end_x, end_y), end_radius, + reinterpret_cast(colors.data()), color_stops.data(), + colors.num_elements(), tile_mode, 0, + has_matrix ? &sk_matrix : nullptr)); } CanvasGradient::CanvasGradient() = default; diff --git a/lib/ui/painting/gradient.h b/lib/ui/painting/gradient.h index a0d142a5adab4..e3dc70ea450d2 100644 --- a/lib/ui/painting/gradient.h +++ b/lib/ui/painting/gradient.h @@ -62,10 +62,13 @@ class CanvasGradient : public Shader { SkTileMode tile_mode, const tonic::Float64List& matrix4); + sk_sp shader(SkFilterQuality) override { return sk_shader_.get(); } + static void RegisterNatives(tonic::DartLibraryNatives* natives); private: CanvasGradient(); + flutter::SkiaGPUObject sk_shader_; }; } // namespace flutter diff --git a/lib/ui/painting/image_shader.cc b/lib/ui/painting/image_shader.cc index 95c27a6007cbb..5e64e4633a4e0 100644 --- a/lib/ui/painting/image_shader.cc +++ b/lib/ui/painting/image_shader.cc @@ -43,11 +43,23 @@ void ImageShader::initWithImage(CanvasImage* image, ToDart("ImageShader constructor called with non-genuine Image.")); return; } - SkMatrix sk_matrix = ToSkMatrix(matrix4); - set_shader(UIDartState::CreateGPUObject( - image->image()->makeShader(tmx, tmy, &sk_matrix))); + sk_image_ = image->image(); + tmx_ = tmx; + tmy_ = tmy; + local_matrix_ = ToSkMatrix(matrix4); } +sk_sp ImageShader::shader(SkFilterQuality quality) { + if (!cached_shader_.get() || cached_quality_ != quality) { + SkSamplingOptions sampling(quality, + SkSamplingOptions::kMedium_asMipmapLinear); + + cached_quality_ = quality; + cached_shader_ = UIDartState::CreateGPUObject( + sk_image_->makeShader(tmx_, tmy_, sampling, &local_matrix_)); + } + return cached_shader_.get(); +} ImageShader::ImageShader() = default; ImageShader::~ImageShader() = default; diff --git a/lib/ui/painting/image_shader.h b/lib/ui/painting/image_shader.h index e57a7a5985c5c..afbfe7fbbf645 100644 --- a/lib/ui/painting/image_shader.h +++ b/lib/ui/painting/image_shader.h @@ -33,10 +33,20 @@ class ImageShader : public Shader { SkTileMode tmy, const tonic::Float64List& matrix4); + sk_sp shader(SkFilterQuality) override; + static void RegisterNatives(tonic::DartLibraryNatives* natives); private: ImageShader(); + + sk_sp sk_image_; + SkTileMode tmx_; + SkTileMode tmy_; + SkMatrix local_matrix_; + + SkFilterQuality cached_quality_ = kNone_SkFilterQuality; + flutter::SkiaGPUObject cached_shader_; }; } // namespace flutter diff --git a/lib/ui/painting/paint.cc b/lib/ui/painting/paint.cc index d3e49ad767460..c51126974b0ac 100644 --- a/lib/ui/painting/paint.cc +++ b/lib/ui/painting/paint.cc @@ -71,6 +71,12 @@ Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) { return; } + tonic::DartByteData byte_data(paint_data); + FML_CHECK(byte_data.length_in_bytes() == kDataByteCount); + + const uint32_t* uint_data = static_cast(byte_data.data()); + const float* float_data = static_cast(byte_data.data()); + Dart_Handle values[kObjectCount]; if (!Dart_IsNull(paint_objects)) { FML_DCHECK(Dart_IsList(paint_objects)); @@ -86,7 +92,9 @@ Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) { Dart_Handle shader = values[kShaderIndex]; if (!Dart_IsNull(shader)) { Shader* decoded = tonic::DartConverter::FromDart(shader); - paint_.setShader(decoded->shader()); + uint32_t filter_quality = uint_data[kFilterQualityIndex]; + paint_.setShader( + decoded->shader(static_cast(filter_quality))); } Dart_Handle color_filter = values[kColorFilterIndex]; @@ -104,12 +112,6 @@ Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) { } } - tonic::DartByteData byte_data(paint_data); - FML_CHECK(byte_data.length_in_bytes() == kDataByteCount); - - const uint32_t* uint_data = static_cast(byte_data.data()); - const float* float_data = static_cast(byte_data.data()); - paint_.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0); uint32_t encoded_color = uint_data[kColorIndex]; @@ -149,11 +151,6 @@ Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) { paint_.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault); } - uint32_t filter_quality = uint_data[kFilterQualityIndex]; - if (filter_quality) { - paint_.setFilterQuality(static_cast(filter_quality)); - } - if (uint_data[kInvertColorIndex]) { sk_sp invert_filter = ColorFilter::MakeColorMatrixFilter255(invert_colors); diff --git a/lib/ui/painting/shader.cc b/lib/ui/painting/shader.cc index c6f0e6b5617d5..e350033cf5ae0 100644 --- a/lib/ui/painting/shader.cc +++ b/lib/ui/painting/shader.cc @@ -10,9 +10,6 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Shader); -Shader::Shader(flutter::SkiaGPUObject shader) - : shader_(std::move(shader)) {} - Shader::~Shader() = default; } // namespace flutter diff --git a/lib/ui/painting/shader.h b/lib/ui/painting/shader.h index cb9043ae0b4da..509a06a94f7d7 100644 --- a/lib/ui/painting/shader.h +++ b/lib/ui/painting/shader.h @@ -8,6 +8,7 @@ #include "flutter/flow/skia_gpu_object.h" #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/ui_dart_state.h" +#include "third_party/skia/include/core/SkFilterQuality.h" #include "third_party/skia/include/core/SkShader.h" namespace flutter { @@ -19,17 +20,13 @@ class Shader : public RefCountedDartWrappable { public: ~Shader() override; - sk_sp shader() { return shader_.get(); } - - void set_shader(flutter::SkiaGPUObject shader) { - shader_ = std::move(shader); - } + virtual sk_sp shader(SkFilterQuality) = 0; protected: - Shader(flutter::SkiaGPUObject shader = {}); + Shader() {} private: - flutter::SkiaGPUObject shader_; + // flutter::SkiaGPUObject shader_; }; } // namespace flutter