提交 8ee1910c 编写于 作者: J Jeff Brown 提交者: GitHub

Use metrics provided by scene events. (#3922)

Compute the necessary texture resolution using more accurate scaling
information provided by Mozart scene node metrics events instead of the
device pixel ratio provided by the Mozart view properties (which we
might remove in the future).

This allows us to allocate smaller textures when a Flutter view is
being scaled down.
上级 3a12bc09
...@@ -21,8 +21,10 @@ class Rasterizer { ...@@ -21,8 +21,10 @@ class Rasterizer {
static std::unique_ptr<Rasterizer> Create(); static std::unique_ptr<Rasterizer> Create();
virtual void SetSession(fidl::InterfaceHandle<mozart2::Session> session, virtual void SetScene(
mx::eventpair import_token) = 0; fidl::InterfaceHandle<mozart2::SceneManager> scene_manager,
mx::eventpair import_token,
ftl::Closure metrics_changed_callback) = 0;
virtual void Draw(std::unique_ptr<flow::LayerTree> layer_tree, virtual void Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) = 0; ftl::Closure callback) = 0;
......
...@@ -206,20 +206,36 @@ void RuntimeHolder::CreateView( ...@@ -206,20 +206,36 @@ void RuntimeHolder::CreateView(
input_connection_->SetEventListener(std::move(input_listener)); input_connection_->SetEventListener(std::move(input_listener));
// Setup the session. // Setup the session.
mozart2::SessionPtr session; fidl::InterfaceHandle<mozart2::SceneManager> scene_manager;
mozart2::SceneManagerPtr scene_manager;
view_manager_->GetSceneManager(scene_manager.NewRequest()); view_manager_->GetSceneManager(scene_manager.NewRequest());
scene_manager->CreateSession(session.NewRequest(),
nullptr /* session listener */);
blink::Threads::Gpu()->PostTask(ftl::MakeCopyable([ blink::Threads::Gpu()->PostTask(ftl::MakeCopyable([
rasterizer = rasterizer_.get(), // rasterizer = rasterizer_.get(), //
session = session.PassInterfaceHandle(), // scene_manager = std::move(scene_manager), //
import_token = std::move(import_token) // import_token = std::move(import_token), //
weak_runtime_holder = GetWeakPtr()
]() mutable { ]() mutable {
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
rasterizer->SetSession(std::move(session), std::move(import_token)); rasterizer->SetScene(
std::move(scene_manager), std::move(import_token),
// TODO(MZ-222): Ideally we would immediately redraw the previous layer
// tree when the metrics change since there's no need to rerecord it.
// However, we want to make sure there's only one outstanding frame.
// We should improve the frame scheduling so that the rasterizer thread
// can self-schedule re-rasterization.
[weak_runtime_holder] {
// This is on the GPU thread thread. Post to the Platform/UI
// thread for the completion callback.
ASSERT_IS_GPU_THREAD;
blink::Threads::Platform()->PostTask([weak_runtime_holder]() {
// On the Platform/UI thread.
ASSERT_IS_UI_THREAD;
if (weak_runtime_holder) {
weak_runtime_holder->OnRedrawFrame();
}
});
});
})); }));
runtime_ = blink::RuntimeController::Create(this); runtime_ = blink::RuntimeController::Create(this);
const uint8_t* isolate_snapshot_data; const uint8_t* isolate_snapshot_data;
...@@ -290,6 +306,7 @@ void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) { ...@@ -290,6 +306,7 @@ void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
last_begin_frame_time_); last_begin_frame_time_);
layer_tree->set_frame_size(SkISize::Make(viewport_metrics_.physical_width, layer_tree->set_frame_size(SkISize::Make(viewport_metrics_.physical_width,
viewport_metrics_.physical_height)); viewport_metrics_.physical_height));
layer_tree->set_device_pixel_ratio(viewport_metrics_.device_pixel_ratio);
// We are on the Platform/UI thread. Post to the GPU thread to render. // We are on the Platform/UI thread. Post to the GPU thread to render.
ASSERT_IS_PLATFORM_THREAD; ASSERT_IS_PLATFORM_THREAD;
...@@ -301,8 +318,8 @@ void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) { ...@@ -301,8 +318,8 @@ void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
// On the GPU Thread. // On the GPU Thread.
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
rasterizer->Draw(std::move(layer_tree), [weak_runtime_holder]() { rasterizer->Draw(std::move(layer_tree), [weak_runtime_holder]() {
// This is on the GPU thread thread. Post to the Platform/UI thread for // This is on the GPU thread thread. Post to the Platform/UI thread
// the completion callback. // for the completion callback.
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
blink::Threads::Platform()->PostTask([weak_runtime_holder]() { blink::Threads::Platform()->PostTask([weak_runtime_holder]() {
// On the Platform/UI thread. // On the Platform/UI thread.
...@@ -516,8 +533,8 @@ void RuntimeHolder::OnEvent(mozart::InputEventPtr event, ...@@ -516,8 +533,8 @@ void RuntimeHolder::OnEvent(mozart::InputEventPtr event,
pointer_data.change = GetChangeFromPointerEventPhase(pointer->phase); pointer_data.change = GetChangeFromPointerEventPhase(pointer->phase);
pointer_data.kind = GetKindFromPointerType(pointer->type); pointer_data.kind = GetKindFromPointerType(pointer->type);
pointer_data.device = pointer->pointer_id; pointer_data.device = pointer->pointer_id;
pointer_data.physical_x = pointer->x; pointer_data.physical_x = pointer->x * viewport_metrics_.device_pixel_ratio;
pointer_data.physical_y = pointer->y; pointer_data.physical_y = pointer->y * viewport_metrics_.device_pixel_ratio;
switch (pointer_data.change) { switch (pointer_data.change) {
case blink::PointerData::Change::kDown: case blink::PointerData::Change::kDown:
...@@ -585,15 +602,21 @@ void RuntimeHolder::OnPropertiesChanged( ...@@ -585,15 +602,21 @@ void RuntimeHolder::OnPropertiesChanged(
FTL_DCHECK(properties); FTL_DCHECK(properties);
// Attempt to read the device pixel ratio. // Attempt to read the device pixel ratio.
float pixel_ratio = 1.0; float pixel_ratio = 1.f;
if (auto& metrics = properties->display_metrics) { if (auto& metrics = properties->display_metrics) {
pixel_ratio = metrics->device_pixel_ratio; pixel_ratio = metrics->device_pixel_ratio;
} }
// Apply view property changes. // Apply view property changes.
if (auto& layout = properties->view_layout) { if (auto& layout = properties->view_layout) {
viewport_metrics_.physical_width = layout->size->width; viewport_metrics_.physical_width = layout->size->width * pixel_ratio;
viewport_metrics_.physical_height = layout->size->height; viewport_metrics_.physical_height = layout->size->height * pixel_ratio;
viewport_metrics_.physical_padding_top = layout->inset->top * pixel_ratio;
viewport_metrics_.physical_padding_right =
layout->inset->right * pixel_ratio;
viewport_metrics_.physical_padding_bottom =
layout->inset->bottom * pixel_ratio;
viewport_metrics_.physical_padding_left = layout->inset->left * pixel_ratio;
viewport_metrics_.device_pixel_ratio = pixel_ratio; viewport_metrics_.device_pixel_ratio = pixel_ratio;
runtime_->SetViewportMetrics(viewport_metrics_); runtime_->SetViewportMetrics(viewport_metrics_);
} }
...@@ -706,4 +729,9 @@ void RuntimeHolder::OnFrameComplete() { ...@@ -706,4 +729,9 @@ void RuntimeHolder::OnFrameComplete() {
PostBeginFrame(); PostBeginFrame();
} }
void RuntimeHolder::OnRedrawFrame() {
if (!frame_outstanding_)
ScheduleFrame();
}
} // namespace flutter_runner } // namespace flutter_runner
...@@ -89,6 +89,7 @@ class RuntimeHolder : public blink::RuntimeDelegate, ...@@ -89,6 +89,7 @@ class RuntimeHolder : public blink::RuntimeDelegate,
void PostBeginFrame(); void PostBeginFrame();
void BeginFrame(); void BeginFrame();
void OnFrameComplete(); void OnFrameComplete();
void OnRedrawFrame();
void Invalidate(); void Invalidate();
std::unique_ptr<app::ApplicationContext> context_; std::unique_ptr<app::ApplicationContext> context_;
......
...@@ -7,17 +7,24 @@ ...@@ -7,17 +7,24 @@
namespace flutter_runner { namespace flutter_runner {
SessionConnection::SessionConnection( SessionConnection::SessionConnection(mozart2::SceneManagerPtr scene_manager,
fidl::InterfaceHandle<mozart2::Session> session_handle,
mx::eventpair import_token) mx::eventpair import_token)
: session_(mozart2::SessionPtr::Create(std::move(session_handle))), : session_(scene_manager.get()),
root_node_(&session_), root_node_(&session_),
surface_producer_(std::make_unique<VulkanSurfaceProducer>(&session_)), surface_producer_(std::make_unique<VulkanSurfaceProducer>(&session_)),
scene_update_context_(&session_, surface_producer_.get()) { scene_update_context_(&session_, surface_producer_.get()) {
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
root_node_.Bind(std::move(import_token));
session_.set_connection_error_handler( session_.set_connection_error_handler(
std::bind(&SessionConnection::OnSessionError, this)); std::bind(&SessionConnection::OnSessionError, this));
session_.set_event_handler(std::bind(&SessionConnection::OnSessionEvents,
this, std::placeholders::_1,
std::placeholders::_2));
root_node_.Bind(std::move(import_token));
root_node_.SetEventMask(mozart2::kMetricsEventMask);
session_.Present(0, [](mozart2::PresentationInfoPtr info) {});
present_callback_ = present_callback_ =
std::bind(&SessionConnection::OnPresent, this, std::placeholders::_1); std::bind(&SessionConnection::OnPresent, this, std::placeholders::_1);
} }
...@@ -32,6 +39,24 @@ void SessionConnection::OnSessionError() { ...@@ -32,6 +39,24 @@ void SessionConnection::OnSessionError() {
FTL_CHECK(false) << "Session connection was terminated."; FTL_CHECK(false) << "Session connection was terminated.";
} }
void SessionConnection::OnSessionEvents(uint64_t presentation_time,
fidl::Array<mozart2::EventPtr> events) {
mozart2::MetricsPtr new_metrics;
for (const auto& event : events) {
if (event->is_metrics() &&
event->get_metrics()->node_id == root_node_.id()) {
new_metrics = std::move(event->get_metrics()->metrics);
}
}
if (!new_metrics)
return;
scene_update_context_.set_metrics(std::move(new_metrics));
if (metrics_changed_callback_)
metrics_changed_callback_();
}
void SessionConnection::Present(flow::CompositorContext::ScopedFrame& frame, void SessionConnection::Present(flow::CompositorContext::ScopedFrame& frame,
ftl::Closure on_present_callback) { ftl::Closure on_present_callback) {
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "flutter/flow/compositor_context.h" #include "flutter/flow/compositor_context.h"
#include "flutter/flow/scene_update_context.h" #include "flutter/flow/scene_update_context.h"
#include "lib/fidl/cpp/bindings/interface_handle.h" #include "lib/fidl/cpp/bindings/interface_handle.h"
#include "lib/ftl/functional/closure.h"
#include "lib/ftl/macros.h" #include "lib/ftl/macros.h"
#include "magenta/system/ulib/mx/include/mx/eventpair.h" #include "magenta/system/ulib/mx/include/mx/eventpair.h"
...@@ -19,11 +20,17 @@ namespace flutter_runner { ...@@ -19,11 +20,17 @@ namespace flutter_runner {
class SessionConnection { class SessionConnection {
public: public:
SessionConnection(fidl::InterfaceHandle<mozart2::Session> session_handle, SessionConnection(mozart2::SceneManagerPtr scene_manager,
mx::eventpair import_token); mx::eventpair import_token);
~SessionConnection(); ~SessionConnection();
bool has_metrics() const { return scene_update_context_.has_metrics(); }
void set_metrics_changed_callback(ftl::Closure callback) {
metrics_changed_callback_ = std::move(callback);
}
flow::SceneUpdateContext& scene_update_context() { flow::SceneUpdateContext& scene_update_context() {
return scene_update_context_; return scene_update_context_;
} }
...@@ -43,8 +50,11 @@ class SessionConnection { ...@@ -43,8 +50,11 @@ class SessionConnection {
ftl::Closure pending_on_present_callback_; ftl::Closure pending_on_present_callback_;
std::unique_ptr<VulkanSurfaceProducer> surface_producer_; std::unique_ptr<VulkanSurfaceProducer> surface_producer_;
flow::SceneUpdateContext scene_update_context_; flow::SceneUpdateContext scene_update_context_;
ftl::Closure metrics_changed_callback_;
void OnSessionError(); void OnSessionError();
void OnSessionEvents(uint64_t presentation_time,
fidl::Array<mozart2::EventPtr> events);
void EnqueueClearOps(); void EnqueueClearOps();
......
...@@ -53,13 +53,17 @@ bool VulkanRasterizer::IsValid() const { ...@@ -53,13 +53,17 @@ bool VulkanRasterizer::IsValid() const {
return valid_; return valid_;
} }
void VulkanRasterizer::SetSession( void VulkanRasterizer::SetScene(
fidl::InterfaceHandle<mozart2::Session> session, fidl::InterfaceHandle<mozart2::SceneManager> scene_manager,
mx::eventpair import_token) { mx::eventpair import_token,
ftl::Closure metrics_changed_callback) {
ASSERT_IS_GPU_THREAD; ASSERT_IS_GPU_THREAD;
FTL_DCHECK(valid_ && !session_connection_); FTL_DCHECK(valid_ && !session_connection_);
session_connection_ = std::make_unique<SessionConnection>( session_connection_ = std::make_unique<SessionConnection>(
std::move(session), std::move(import_token)); mozart2::SceneManagerPtr::Create(std::move(scene_manager)),
std::move(import_token));
session_connection_->set_metrics_changed_callback(
std::move(metrics_changed_callback));
} }
void VulkanRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree, void VulkanRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
...@@ -79,6 +83,12 @@ void VulkanRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree, ...@@ -79,6 +83,12 @@ void VulkanRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
return; return;
} }
if (!session_connection_->has_metrics()) {
// Still awaiting metrics. Will redraw when we get them.
callback();
return;
}
compositor_context_.engine_time().SetLapTime(layer_tree->construction_time()); compositor_context_.engine_time().SetLapTime(layer_tree->construction_time());
flow::CompositorContext::ScopedFrame frame = compositor_context_.AcquireFrame( flow::CompositorContext::ScopedFrame frame = compositor_context_.AcquireFrame(
......
...@@ -22,8 +22,9 @@ class VulkanRasterizer : public Rasterizer { ...@@ -22,8 +22,9 @@ class VulkanRasterizer : public Rasterizer {
bool IsValid() const; bool IsValid() const;
void SetSession(fidl::InterfaceHandle<mozart2::Session> session, void SetScene(fidl::InterfaceHandle<mozart2::SceneManager> scene_manager,
mx::eventpair import_token) override; mx::eventpair import_token,
ftl::Closure metrics_changed_callback) override;
void Draw(std::unique_ptr<flow::LayerTree> layer_tree, void Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) override; ftl::Closure callback) override;
......
...@@ -17,7 +17,6 @@ ExportNode::~ExportNode() { ...@@ -17,7 +17,6 @@ ExportNode::~ExportNode() {
void ExportNode::Bind(SceneUpdateContext& context, void ExportNode::Bind(SceneUpdateContext& context,
mozart::client::ContainerNode& container, mozart::client::ContainerNode& container,
const SkPoint& offset, const SkPoint& offset,
float scale,
bool hit_testable) { bool hit_testable) {
ftl::MutexLocker lock(&mutex_); ftl::MutexLocker lock(&mutex_);
...@@ -29,7 +28,6 @@ void ExportNode::Bind(SceneUpdateContext& context, ...@@ -29,7 +28,6 @@ void ExportNode::Bind(SceneUpdateContext& context,
if (node_) { if (node_) {
container.AddChild(*node_); container.AddChild(*node_);
node_->SetTranslation(offset.x(), offset.y(), 0.f); node_->SetTranslation(offset.x(), offset.y(), 0.f);
node_->SetScale(scale, scale, 1.f);
node_->SetHitTestBehavior(hit_testable node_->SetHitTestBehavior(hit_testable
? mozart2::HitTestBehavior::kDefault ? mozart2::HitTestBehavior::kDefault
: mozart2::HitTestBehavior::kSuppress); : mozart2::HitTestBehavior::kSuppress);
......
...@@ -34,7 +34,6 @@ class ExportNode : public ftl::RefCountedThreadSafe<ExportNode> { ...@@ -34,7 +34,6 @@ class ExportNode : public ftl::RefCountedThreadSafe<ExportNode> {
void Bind(SceneUpdateContext& context, void Bind(SceneUpdateContext& context,
mozart::client::ContainerNode& container, mozart::client::ContainerNode& container,
const SkPoint& offset, const SkPoint& offset,
float scale,
bool hit_testable); bool hit_testable);
private: private:
......
...@@ -26,15 +26,8 @@ void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) { ...@@ -26,15 +26,8 @@ void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) {
// or whether we should leave this up to the Flutter application to decide. // or whether we should leave this up to the Flutter application to decide.
// In some situations, it might be useful to allow children to draw // In some situations, it might be useful to allow children to draw
// outside of their layout bounds. // outside of their layout bounds.
//
// float inverse_device_pixel_ratio = 1.f / device_pixel_ratio_;
// SkRect bounds =
// SkRect::MakeXYWH(offset_.x(), offset_.y(),
// physical_size_.width() * inverse_device_pixel_ratio,
// physical_size_.height() * inverse_device_pixel_ratio);
if (export_node_) { if (export_node_) {
context.AddChildScene(export_node_.get(), offset_, device_pixel_ratio_, context.AddChildScene(export_node_.get(), offset_, hit_testable_);
hit_testable_);
} }
} }
......
...@@ -17,13 +17,7 @@ class ChildSceneLayer : public Layer { ...@@ -17,13 +17,7 @@ class ChildSceneLayer : public Layer {
void set_offset(const SkPoint& offset) { offset_ = offset; } void set_offset(const SkPoint& offset) { offset_ = offset; }
void set_device_pixel_ratio(float device_pixel_ratio) { void set_size(const SkSize& size) { size_ = size; }
device_pixel_ratio_ = device_pixel_ratio;
}
void set_physical_size(const SkISize& physical_size) {
physical_size_ = physical_size;
}
void set_export_node(ftl::RefPtr<ExportNode> export_node) { void set_export_node(ftl::RefPtr<ExportNode> export_node) {
export_node_ = std::move(export_node); export_node_ = std::move(export_node);
...@@ -39,8 +33,7 @@ class ChildSceneLayer : public Layer { ...@@ -39,8 +33,7 @@ class ChildSceneLayer : public Layer {
private: private:
SkPoint offset_; SkPoint offset_;
float device_pixel_ratio_ = 1.0; SkSize size_;
SkISize physical_size_;
ftl::RefPtr<ExportNode> export_node_; ftl::RefPtr<ExportNode> export_node_;
bool hit_testable_ = true; bool hit_testable_ = true;
......
...@@ -34,6 +34,7 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, ...@@ -34,6 +34,7 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
ignore_raster_cache ? nullptr : &frame.context().raster_cache(), ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
frame.gr_context(), color_space, SkRect::MakeEmpty(), frame.gr_context(), color_space, SkRect::MakeEmpty(),
}; };
root_layer_->Preroll(&context, SkMatrix::I()); root_layer_->Preroll(&context, SkMatrix::I());
} }
...@@ -42,18 +43,20 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, ...@@ -42,18 +43,20 @@ void LayerTree::UpdateScene(SceneUpdateContext& context,
mozart::client::ContainerNode& container) { mozart::client::ContainerNode& container) {
TRACE_EVENT0("flutter", "LayerTree::UpdateScene"); TRACE_EVENT0("flutter", "LayerTree::UpdateScene");
SceneUpdateContext::Transform transform(context, 1.f / device_pixel_ratio_,
1.f / device_pixel_ratio_, 1.f);
SceneUpdateContext::Frame frame( SceneUpdateContext::Frame frame(
context, context,
SkRRect::MakeRect( SkRRect::MakeRect(
SkRect::MakeIWH(frame_size_.width(), frame_size_.height())), SkRect::MakeWH(frame_size_.width(), frame_size_.height())),
SK_ColorTRANSPARENT, 0.f, 1.f, 1.f); SK_ColorTRANSPARENT, 0.f);
if (root_layer_->needs_system_composite()) { if (root_layer_->needs_system_composite()) {
root_layer_->UpdateScene(context); root_layer_->UpdateScene(context);
} }
if (root_layer_->needs_painting()) { if (root_layer_->needs_painting()) {
frame.AddPaintedLayer(root_layer_.get()); frame.AddPaintedLayer(root_layer_.get());
} }
container.AddChild(frame.entity_node()); container.AddChild(transform.entity_node());
} }
#endif #endif
......
...@@ -31,6 +31,10 @@ class LayerTree { ...@@ -31,6 +31,10 @@ class LayerTree {
bool ignore_raster_cache = false); bool ignore_raster_cache = false);
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
void set_device_pixel_ratio(float device_pixel_ratio) {
device_pixel_ratio_ = device_pixel_ratio;
}
void UpdateScene(SceneUpdateContext& context, void UpdateScene(SceneUpdateContext& context,
mozart::client::ContainerNode& container); mozart::client::ContainerNode& container);
#endif #endif
...@@ -80,6 +84,10 @@ class LayerTree { ...@@ -80,6 +84,10 @@ class LayerTree {
bool checkerboard_raster_cache_images_; bool checkerboard_raster_cache_images_;
bool checkerboard_offscreen_layers_; bool checkerboard_offscreen_layers_;
#if defined(OS_FUCHSIA)
float device_pixel_ratio_ = 1.f;
#endif
FTL_DISALLOW_COPY_AND_ASSIGN(LayerTree); FTL_DISALLOW_COPY_AND_ASSIGN(LayerTree);
}; };
......
...@@ -34,13 +34,6 @@ void PhysicalModelLayer::Preroll(PrerollContext* context, ...@@ -34,13 +34,6 @@ void PhysicalModelLayer::Preroll(PrerollContext* context,
set_paint_bounds(bounds); set_paint_bounds(bounds);
#endif // defined(OS_FUCHSIA) #endif // defined(OS_FUCHSIA)
} }
#if defined(OS_FUCHSIA)
if (needs_system_composite()) {
scale_x_ = matrix.getScaleX();
scale_y_ = matrix.getScaleY();
}
#endif // defined(OS_FUCHSIA)
} }
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
...@@ -48,8 +41,7 @@ void PhysicalModelLayer::Preroll(PrerollContext* context, ...@@ -48,8 +41,7 @@ void PhysicalModelLayer::Preroll(PrerollContext* context,
void PhysicalModelLayer::UpdateScene(SceneUpdateContext& context) { void PhysicalModelLayer::UpdateScene(SceneUpdateContext& context) {
FTL_DCHECK(needs_system_composite()); FTL_DCHECK(needs_system_composite());
SceneUpdateContext::Frame frame(context, rrect_, color_, elevation_, scale_x_, SceneUpdateContext::Frame frame(context, rrect_, color_, elevation_);
scale_y_);
for (auto& layer : layers()) { for (auto& layer : layers()) {
if (layer->needs_painting()) { if (layer->needs_painting()) {
frame.AddPaintedLayer(layer.get()); frame.AddPaintedLayer(layer.get());
......
...@@ -38,11 +38,6 @@ class PhysicalModelLayer : public ContainerLayer { ...@@ -38,11 +38,6 @@ class PhysicalModelLayer : public ContainerLayer {
float elevation_; float elevation_;
SkColor color_; SkColor color_;
SkScalar device_pixel_ratio_; SkScalar device_pixel_ratio_;
#if defined(OS_FUCHSIA)
SkScalar scale_x_;
SkScalar scale_y_;
#endif // defined(OS_FUCHSIA)
}; };
} // namespace flow } // namespace flow
......
...@@ -21,19 +21,15 @@ SceneUpdateContext::~SceneUpdateContext() = default; ...@@ -21,19 +21,15 @@ SceneUpdateContext::~SceneUpdateContext() = default;
void SceneUpdateContext::AddChildScene(ExportNode* export_node, void SceneUpdateContext::AddChildScene(ExportNode* export_node,
SkPoint offset, SkPoint offset,
float device_pixel_ratio,
bool hit_testable) { bool hit_testable) {
FTL_DCHECK(top_entity_); FTL_DCHECK(top_entity_);
export_node->Bind(*this, top_entity_->entity_node(), offset, export_node->Bind(*this, top_entity_->entity_node(), offset, hit_testable);
1.f / device_pixel_ratio, hit_testable);
} }
void SceneUpdateContext::CreateFrame(mozart::client::EntityNode& entity_node, void SceneUpdateContext::CreateFrame(mozart::client::EntityNode& entity_node,
const SkRRect& rrect, const SkRRect& rrect,
SkColor color, SkColor color,
SkScalar scale_x,
SkScalar scale_y,
const SkRect& paint_bounds, const SkRect& paint_bounds,
std::vector<Layer*> paint_layers) { std::vector<Layer*> paint_layers) {
// Frames always clip their children. // Frames always clip their children.
...@@ -73,6 +69,10 @@ void SceneUpdateContext::CreateFrame(mozart::client::EntityNode& entity_node, ...@@ -73,6 +69,10 @@ void SceneUpdateContext::CreateFrame(mozart::client::EntityNode& entity_node,
return; return;
} }
// Apply current metrics and transformation scale factors.
const float scale_x = metrics_->scale_x * top_scale_x_;
const float scale_y = metrics_->scale_y * top_scale_y_;
// If the painted area only covers a portion of the frame then we can // If the painted area only covers a portion of the frame then we can
// reduce the texture size by drawing just that smaller area. // reduce the texture size by drawing just that smaller area.
SkRect inner_bounds = shape_bounds; SkRect inner_bounds = shape_bounds;
...@@ -223,7 +223,10 @@ SceneUpdateContext::Clip::~Clip() = default; ...@@ -223,7 +223,10 @@ SceneUpdateContext::Clip::~Clip() = default;
SceneUpdateContext::Transform::Transform(SceneUpdateContext& context, SceneUpdateContext::Transform::Transform(SceneUpdateContext& context,
const SkMatrix& transform) const SkMatrix& transform)
: Entity(context) { : Entity(context),
previous_scale_x_(context.top_scale_x_),
previous_scale_y_(context.top_scale_y_) {
if (!transform.isIdentity()) {
// TODO(MZ-192): The perspective and shear components in the matrix // TODO(MZ-192): The perspective and shear components in the matrix
// are not handled correctly. // are not handled correctly.
MatrixDecomposition decomposition(transform); MatrixDecomposition decomposition(transform);
...@@ -232,38 +235,57 @@ SceneUpdateContext::Transform::Transform(SceneUpdateContext& context, ...@@ -232,38 +235,57 @@ SceneUpdateContext::Transform::Transform(SceneUpdateContext& context,
decomposition.translation().y(), // decomposition.translation().y(), //
decomposition.translation().z() // decomposition.translation().z() //
); );
entity_node().SetScale(decomposition.scale().x(), // entity_node().SetScale(decomposition.scale().x(), //
decomposition.scale().y(), // decomposition.scale().y(), //
decomposition.scale().z() // decomposition.scale().z() //
); );
context.top_scale_x_ *= decomposition.scale().x();
context.top_scale_y_ *= decomposition.scale().y();
entity_node().SetRotation(decomposition.rotation().fData[0], // entity_node().SetRotation(decomposition.rotation().fData[0], //
decomposition.rotation().fData[1], // decomposition.rotation().fData[1], //
decomposition.rotation().fData[2], // decomposition.rotation().fData[2], //
decomposition.rotation().fData[3] // decomposition.rotation().fData[3] //
); );
} }
}
} }
SceneUpdateContext::Transform::~Transform() = default; SceneUpdateContext::Transform::Transform(SceneUpdateContext& context,
float scale_x,
float scale_y,
float scale_z)
: Entity(context),
previous_scale_x_(context.top_scale_x_),
previous_scale_y_(context.top_scale_y_) {
if (scale_x != 1.f || scale_y != 1.f || scale_z != 1.f) {
entity_node().SetScale(scale_x, scale_y, scale_z);
context.top_scale_x_ *= scale_x;
context.top_scale_y_ *= scale_y;
}
}
SceneUpdateContext::Transform::~Transform() {
context().top_scale_x_ = previous_scale_x_;
context().top_scale_y_ = previous_scale_y_;
}
SceneUpdateContext::Frame::Frame(SceneUpdateContext& context, SceneUpdateContext::Frame::Frame(SceneUpdateContext& context,
const SkRRect& rrect, const SkRRect& rrect,
SkColor color, SkColor color,
float elevation, float elevation)
SkScalar scale_x,
SkScalar scale_y)
: Entity(context), : Entity(context),
rrect_(rrect), rrect_(rrect),
color_(color), color_(color),
scale_x_(scale_x),
scale_y_(scale_y),
paint_bounds_(SkRect::MakeEmpty()) { paint_bounds_(SkRect::MakeEmpty()) {
if (elevation != 0.0)
entity_node().SetTranslation(0.f, 0.f, elevation); entity_node().SetTranslation(0.f, 0.f, elevation);
} }
SceneUpdateContext::Frame::~Frame() { SceneUpdateContext::Frame::~Frame() {
context().CreateFrame(entity_node(), rrect_, color_, scale_x_, scale_y_, context().CreateFrame(entity_node(), rrect_, color_, paint_bounds_,
paint_bounds_, std::move(paint_layers_)); std::move(paint_layers_));
} }
void SceneUpdateContext::Frame::AddPaintedLayer(Layer* layer) { void SceneUpdateContext::Frame::AddPaintedLayer(Layer* layer) {
......
...@@ -52,13 +52,6 @@ class SceneUpdateContext { ...@@ -52,13 +52,6 @@ class SceneUpdateContext {
std::unique_ptr<SurfaceProducerSurface> surface) = 0; std::unique_ptr<SurfaceProducerSurface> surface) = 0;
}; };
SceneUpdateContext(mozart::client::Session* session,
SurfaceProducer* surface_producer);
~SceneUpdateContext();
mozart::client::Session* session() { return session_; }
class Entity { class Entity {
public: public:
Entity(SceneUpdateContext& context); Entity(SceneUpdateContext& context);
...@@ -85,7 +78,15 @@ class SceneUpdateContext { ...@@ -85,7 +78,15 @@ class SceneUpdateContext {
class Transform : public Entity { class Transform : public Entity {
public: public:
Transform(SceneUpdateContext& context, const SkMatrix& transform); Transform(SceneUpdateContext& context, const SkMatrix& transform);
Transform(SceneUpdateContext& context,
float scale_x,
float scale_y,
float scale_z);
~Transform(); ~Transform();
private:
float const previous_scale_x_;
float const previous_scale_y_;
}; };
class Frame : public Entity { class Frame : public Entity {
...@@ -93,9 +94,7 @@ class SceneUpdateContext { ...@@ -93,9 +94,7 @@ class SceneUpdateContext {
Frame(SceneUpdateContext& context, Frame(SceneUpdateContext& context,
const SkRRect& rrect, const SkRRect& rrect,
SkColor color, SkColor color,
float elevation, float elevation);
SkScalar scale_x,
SkScalar scale_y);
~Frame(); ~Frame();
void AddPaintedLayer(Layer* layer); void AddPaintedLayer(Layer* layer);
...@@ -103,16 +102,25 @@ class SceneUpdateContext { ...@@ -103,16 +102,25 @@ class SceneUpdateContext {
private: private:
const SkRRect& rrect_; const SkRRect& rrect_;
SkColor const color_; SkColor const color_;
SkScalar const scale_x_;
SkScalar const scale_y_;
std::vector<Layer*> paint_layers_; std::vector<Layer*> paint_layers_;
SkRect paint_bounds_; SkRect paint_bounds_;
}; };
SceneUpdateContext(mozart::client::Session* session,
SurfaceProducer* surface_producer);
~SceneUpdateContext();
mozart::client::Session* session() { return session_; }
bool has_metrics() const { return !!metrics_; }
void set_metrics(mozart2::MetricsPtr metrics) {
metrics_ = std::move(metrics);
}
void AddChildScene(ExportNode* export_node, void AddChildScene(ExportNode* export_node,
SkPoint offset, SkPoint offset,
float device_pixel_ratio,
bool hit_testable); bool hit_testable);
// TODO(chinmaygarde): This method must submit the surfaces as soon as paint // TODO(chinmaygarde): This method must submit the surfaces as soon as paint
...@@ -139,8 +147,6 @@ class SceneUpdateContext { ...@@ -139,8 +147,6 @@ class SceneUpdateContext {
void CreateFrame(mozart::client::EntityNode& entity_node, void CreateFrame(mozart::client::EntityNode& entity_node,
const SkRRect& rrect, const SkRRect& rrect,
SkColor color, SkColor color,
SkScalar scale_x,
SkScalar scale_y,
const SkRect& paint_bounds, const SkRect& paint_bounds,
std::vector<Layer*> paint_layers); std::vector<Layer*> paint_layers);
void SetShapeTextureOrColor(mozart::client::ShapeNode& shape_node, void SetShapeTextureOrColor(mozart::client::ShapeNode& shape_node,
...@@ -158,10 +164,14 @@ class SceneUpdateContext { ...@@ -158,10 +164,14 @@ class SceneUpdateContext {
std::vector<Layer*> paint_layers); std::vector<Layer*> paint_layers);
Entity* top_entity_ = nullptr; Entity* top_entity_ = nullptr;
float top_scale_x_ = 1.f;
float top_scale_y_ = 1.f;
mozart::client::Session* const session_; mozart::client::Session* const session_;
SurfaceProducer* const surface_producer_; SurfaceProducer* const surface_producer_;
mozart2::MetricsPtr metrics_;
std::vector<PaintTask> paint_tasks_; std::vector<PaintTask> paint_tasks_;
FTL_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext); FTL_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext);
......
...@@ -201,25 +201,22 @@ class SceneBuilder extends NativeFieldWrapperClass2 { ...@@ -201,25 +201,22 @@ class SceneBuilder extends NativeFieldWrapperClass2 {
/// for this application. /// for this application.
void addChildScene({ void addChildScene({
Offset offset: Offset.zero, Offset offset: Offset.zero,
double devicePixelRatio: 1.0, double width: 0.0,
int physicalWidth: 0, double height: 0.0,
int physicalHeight: 0,
SceneHost sceneHost, SceneHost sceneHost,
bool hitTestable: true bool hitTestable: true
}) { }) {
_addChildScene(offset.dx, _addChildScene(offset.dx,
offset.dy, offset.dy,
devicePixelRatio, width,
physicalWidth, height,
physicalHeight,
sceneHost, sceneHost,
hitTestable); hitTestable);
} }
void _addChildScene(double dx, void _addChildScene(double dx,
double dy, double dy,
double devicePixelRatio, double width,
int physicalWidth, double height,
int physicalHeight,
SceneHost sceneHost, SceneHost sceneHost,
bool hitTestable) native "SceneBuilder_addChildScene"; bool hitTestable) native "SceneBuilder_addChildScene";
......
...@@ -224,24 +224,21 @@ void SceneBuilder::addPicture(double dx, ...@@ -224,24 +224,21 @@ void SceneBuilder::addPicture(double dx,
void SceneBuilder::addChildScene(double dx, void SceneBuilder::addChildScene(double dx,
double dy, double dy,
double devicePixelRatio, double width,
int physicalWidth, double height,
int physicalHeight,
SceneHost* sceneHost, SceneHost* sceneHost,
bool hitTestable) { bool hitTestable) {
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
if (!m_currentLayer) if (!m_currentLayer)
return; return;
SkRect sceneRect = SkRect::MakeXYWH(dx, dy, physicalWidth / devicePixelRatio, SkRect sceneRect = SkRect::MakeXYWH(dx, dy, width, height);
physicalHeight / devicePixelRatio);
if (!SkRect::Intersects(sceneRect, m_cullRects.top())) if (!SkRect::Intersects(sceneRect, m_cullRects.top()))
return; return;
std::unique_ptr<flow::ChildSceneLayer> layer(new flow::ChildSceneLayer()); std::unique_ptr<flow::ChildSceneLayer> layer(new flow::ChildSceneLayer());
layer->set_offset(SkPoint::Make(dx, dy)); layer->set_offset(SkPoint::Make(dx, dy));
layer->set_device_pixel_ratio(devicePixelRatio); layer->set_size(SkSize::Make(width, height));
layer->set_physical_size(SkISize::Make(physicalWidth, physicalHeight));
layer->set_export_node(sceneHost->exportNode()); layer->set_export_node(sceneHost->exportNode());
layer->set_hit_testable(hitTestable); layer->set_hit_testable(hitTestable);
m_currentLayer->Add(std::move(layer)); m_currentLayer->Add(std::move(layer));
......
...@@ -59,9 +59,8 @@ class SceneBuilder : public ftl::RefCountedThreadSafe<SceneBuilder>, ...@@ -59,9 +59,8 @@ class SceneBuilder : public ftl::RefCountedThreadSafe<SceneBuilder>,
void addPicture(double dx, double dy, Picture* picture, int hints); void addPicture(double dx, double dy, Picture* picture, int hints);
void addChildScene(double dx, void addChildScene(double dx,
double dy, double dy,
double devicePixelRatio, double width,
int physicalWidth, double height,
int physicalHeight,
SceneHost* sceneHost, SceneHost* sceneHost,
bool hitTestable); bool hitTestable);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册