mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix low-res rasterized images on Fuchsia. (#4325)
Plumb through Scenic display metrics to use during Preroll.
This commit is contained in:
parent
d615678e6c
commit
0e8331aa1a
@ -27,6 +27,10 @@ class SessionConnection {
|
||||
|
||||
bool has_metrics() const { return scene_update_context_.has_metrics(); }
|
||||
|
||||
const scenic::MetricsPtr& metrics() const {
|
||||
return scene_update_context_.metrics();
|
||||
}
|
||||
|
||||
void set_metrics_changed_callback(fxl::Closure callback) {
|
||||
metrics_changed_callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ void VulkanRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
|
||||
// Preroll the Flutter layer tree. This allows Flutter to perform pre-paint
|
||||
// optimizations.
|
||||
TRACE_EVENT0("flutter", "Preroll");
|
||||
layer_tree->Preroll(frame);
|
||||
layer_tree->Preroll(frame, session_connection_->metrics().get());
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@ -72,6 +72,11 @@ std::ostream& operator<<(std::ostream& os, const SkPoint& r) {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const flow::RasterCacheKey& k) {
|
||||
os << "Picture: " << k.picture_id() << " Scale: " << k.scale_key().width()
|
||||
<< ", " << k.scale_key().height();
|
||||
<< ", " << k.scale_key().height()
|
||||
#if defined(OS_FUCHSIA)
|
||||
<< " Metrics scale: (" << k.metrics_scale_x() << ", "
|
||||
<< k.metrics_scale_y() << ")"
|
||||
#endif
|
||||
;
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -44,6 +44,9 @@ class Layer {
|
||||
virtual ~Layer();
|
||||
|
||||
struct PrerollContext {
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics = nullptr;
|
||||
#endif
|
||||
RasterCache* raster_cache;
|
||||
GrContext* gr_context;
|
||||
SkColorSpace* dst_color_space;
|
||||
|
||||
@ -18,23 +18,42 @@ LayerTree::LayerTree()
|
||||
LayerTree::~LayerTree() = default;
|
||||
|
||||
void LayerTree::Raster(CompositorContext::ScopedFrame& frame,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool ignore_raster_cache) {
|
||||
Preroll(frame, ignore_raster_cache);
|
||||
#if defined(OS_FUCHSIA)
|
||||
FXL_DCHECK(metrics);
|
||||
#endif
|
||||
Preroll(frame,
|
||||
#if defined(OS_FUCHSIA)
|
||||
metrics,
|
||||
#endif
|
||||
ignore_raster_cache);
|
||||
Paint(frame);
|
||||
}
|
||||
|
||||
void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool ignore_raster_cache) {
|
||||
#if defined(OS_FUCHSIA)
|
||||
FXL_DCHECK(metrics);
|
||||
#endif
|
||||
TRACE_EVENT0("flutter", "LayerTree::Preroll");
|
||||
SkColorSpace* color_space =
|
||||
frame.canvas() ? frame.canvas()->imageInfo().colorSpace() : nullptr;
|
||||
frame.context().raster_cache().SetCheckboardCacheImages(
|
||||
checkerboard_raster_cache_images_);
|
||||
Layer::PrerollContext context = {
|
||||
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
|
||||
frame.gr_context(),
|
||||
color_space,
|
||||
SkRect::MakeEmpty(),
|
||||
#if defined(OS_FUCHSIA)
|
||||
metrics,
|
||||
#endif
|
||||
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
|
||||
frame.gr_context(),
|
||||
color_space,
|
||||
SkRect::MakeEmpty(),
|
||||
};
|
||||
|
||||
root_layer_->Preroll(&context, SkMatrix::I());
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
#include "flutter/flow/layers/layer.h"
|
||||
#include "lib/fxl/macros.h"
|
||||
#include "lib/fxl/time/time_delta.h"
|
||||
#if defined(OS_FUCHSIA)
|
||||
#include "lib/ui/scenic/fidl/events.fidl.h"
|
||||
#endif
|
||||
#include "third_party/skia/include/core/SkSize.h"
|
||||
|
||||
namespace flow {
|
||||
@ -25,9 +28,15 @@ class LayerTree {
|
||||
|
||||
// Raster includes both Preroll and Paint.
|
||||
void Raster(CompositorContext::ScopedFrame& frame,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool ignore_raster_cache = false);
|
||||
|
||||
void Preroll(CompositorContext::ScopedFrame& frame,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool ignore_raster_cache = false);
|
||||
|
||||
#if defined(OS_FUCHSIA)
|
||||
|
||||
@ -24,6 +24,9 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
|
||||
if (auto cache = context->raster_cache) {
|
||||
raster_cache_result_ = cache->GetPrerolledImage(
|
||||
context->gr_context, picture_.get(), matrix, context->dst_color_space,
|
||||
#if defined(OS_FUCHSIA)
|
||||
context->metrics,
|
||||
#endif
|
||||
is_complex_, will_change_);
|
||||
}
|
||||
|
||||
|
||||
@ -72,15 +72,27 @@ RasterCacheResult RasterizePicture(SkPicture* picture,
|
||||
GrContext* context,
|
||||
const MatrixDecomposition& matrix,
|
||||
SkColorSpace* dst_color_space,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool checkerboard) {
|
||||
TRACE_EVENT0("flutter", "RasterCachePopulate");
|
||||
|
||||
const SkVector3& scale = matrix.scale();
|
||||
|
||||
const SkRect logical_rect = picture->cullRect();
|
||||
const SkRect physical_rect =
|
||||
SkRect::MakeWH(std::fabs(logical_rect.width() * scale.x()),
|
||||
std::fabs(logical_rect.height() * scale.y()));
|
||||
|
||||
#if defined(OS_FUCHSIA)
|
||||
float metrics_scale_x = metrics->scale_x;
|
||||
float metrics_scale_y = metrics->scale_y;
|
||||
#else
|
||||
float metrics_scale_x = 1.f;
|
||||
float metrics_scale_y = 1.f;
|
||||
#endif
|
||||
|
||||
const SkRect physical_rect = SkRect::MakeWH(
|
||||
std::fabs(logical_rect.width() * metrics_scale_x * scale.x()),
|
||||
std::fabs(logical_rect.height() * metrics_scale_y * scale.y()));
|
||||
|
||||
const SkImageInfo image_info = SkImageInfo::MakeN32Premul(
|
||||
std::ceil(physical_rect.width()), // physical width
|
||||
@ -100,7 +112,8 @@ RasterCacheResult RasterizePicture(SkPicture* picture,
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
|
||||
canvas->clear(SK_ColorTRANSPARENT);
|
||||
canvas->scale(std::abs(scale.x()), std::abs(scale.y()));
|
||||
canvas->scale(std::abs(scale.x() * metrics_scale_x),
|
||||
std::abs(scale.y() * metrics_scale_y));
|
||||
canvas->translate(-logical_rect.left(), -logical_rect.top());
|
||||
canvas->drawPicture(picture);
|
||||
|
||||
@ -132,6 +145,9 @@ RasterCacheResult RasterCache::GetPrerolledImage(
|
||||
SkPicture* picture,
|
||||
const SkMatrix& transformation_matrix,
|
||||
SkColorSpace* dst_color_space,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool is_complex,
|
||||
bool will_change) {
|
||||
if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) {
|
||||
@ -148,7 +164,11 @@ RasterCacheResult RasterCache::GetPrerolledImage(
|
||||
return {};
|
||||
}
|
||||
|
||||
RasterCacheKey cache_key(*picture, matrix);
|
||||
RasterCacheKey cache_key(*picture,
|
||||
#if defined(OS_FUCHSIA)
|
||||
metrics->scale_x, metrics->scale_y,
|
||||
#endif
|
||||
matrix);
|
||||
|
||||
Entry& entry = cache_[cache_key];
|
||||
entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_);
|
||||
@ -161,6 +181,9 @@ RasterCacheResult RasterCache::GetPrerolledImage(
|
||||
|
||||
if (!entry.image.is_valid()) {
|
||||
entry.image = RasterizePicture(picture, context, matrix, dst_color_space,
|
||||
#if defined(OS_FUCHSIA)
|
||||
metrics,
|
||||
#endif
|
||||
checkerboard_images_);
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@
|
||||
#include "flutter/flow/raster_cache_key.h"
|
||||
#include "lib/fxl/macros.h"
|
||||
#include "lib/fxl/memory/weak_ptr.h"
|
||||
#if defined(OS_FUCHSIA)
|
||||
#include "lib/ui/scenic/fidl/events.fidl.h"
|
||||
#endif
|
||||
#include "third_party/skia/include/core/SkImage.h"
|
||||
#include "third_party/skia/include/core/SkSize.h"
|
||||
|
||||
@ -54,6 +57,9 @@ class RasterCache {
|
||||
SkPicture* picture,
|
||||
const SkMatrix& transformation_matrix,
|
||||
SkColorSpace* dst_color_space,
|
||||
#if defined(OS_FUCHSIA)
|
||||
scenic::Metrics* metrics,
|
||||
#endif
|
||||
bool is_complex,
|
||||
bool will_change);
|
||||
|
||||
|
||||
@ -15,15 +15,30 @@ namespace flow {
|
||||
|
||||
class RasterCacheKey {
|
||||
public:
|
||||
RasterCacheKey(const SkPicture& picture, const MatrixDecomposition& matrix)
|
||||
RasterCacheKey(const SkPicture& picture,
|
||||
#if defined(OS_FUCHSIA)
|
||||
float metrics_scale_x,
|
||||
float metrics_scale_y,
|
||||
#endif
|
||||
const MatrixDecomposition& matrix)
|
||||
: picture_id_(picture.uniqueID()),
|
||||
scale_key_(SkISize::Make(matrix.scale().x() * 1e3,
|
||||
matrix.scale().y() * 1e3)) {}
|
||||
#if defined(OS_FUCHSIA)
|
||||
metrics_scale_x_(metrics_scale_x),
|
||||
metrics_scale_y_(metrics_scale_y),
|
||||
#endif
|
||||
scale_key_(
|
||||
SkISize::Make(matrix.scale().x() * 1e3, matrix.scale().y() * 1e3)) {
|
||||
}
|
||||
|
||||
uint32_t picture_id() const { return picture_id_; }
|
||||
|
||||
const SkISize& scale_key() const { return scale_key_; }
|
||||
|
||||
#if defined(OS_FUCHSIA)
|
||||
float metrics_scale_x() const { return metrics_scale_x_; }
|
||||
float metrics_scale_y() const { return metrics_scale_y_; }
|
||||
#endif
|
||||
|
||||
struct Hash {
|
||||
std::size_t operator()(RasterCacheKey const& key) const {
|
||||
return key.picture_id_;
|
||||
@ -34,6 +49,11 @@ class RasterCacheKey {
|
||||
constexpr bool operator()(const RasterCacheKey& lhs,
|
||||
const RasterCacheKey& rhs) const {
|
||||
return lhs.picture_id_ == rhs.picture_id_ &&
|
||||
#if defined(OS_FUCHSIA)
|
||||
lhs.metrics_scale_x_ == rhs.metrics_scale_x_ &&
|
||||
|
||||
lhs.metrics_scale_y_ == rhs.metrics_scale_y_ &&
|
||||
#endif
|
||||
lhs.scale_key_ == rhs.scale_key_;
|
||||
}
|
||||
};
|
||||
@ -43,6 +63,10 @@ class RasterCacheKey {
|
||||
|
||||
private:
|
||||
uint32_t picture_id_;
|
||||
#if defined(OS_FUCHSIA)
|
||||
float metrics_scale_x_;
|
||||
float metrics_scale_y_;
|
||||
#endif
|
||||
SkISize scale_key_;
|
||||
};
|
||||
|
||||
|
||||
@ -121,6 +121,7 @@ class SceneUpdateContext {
|
||||
void set_metrics(scenic::MetricsPtr metrics) {
|
||||
metrics_ = std::move(metrics);
|
||||
}
|
||||
const scenic::MetricsPtr& metrics() const { return metrics_; }
|
||||
|
||||
void AddChildScene(ExportNode* export_node,
|
||||
SkPoint offset,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user