// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_ #define FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_ #include #include #include #include #include #include #include #include #include "flutter/flow/embedded_views.h" #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { class Layer; // Scenic currently lacks an API to enable rendering of alpha channel; this only // happens if there is a OpacityNode higher in the tree with opacity != 1. For // now, clamp to a infinitesimally smaller value than 1, which does not cause // visual problems in practice. constexpr float kOneMinusEpsilon = 1 - FLT_EPSILON; // How much layers are separated in Scenic z elevation. constexpr float kScenicZElevationBetweenLayers = 10.f; class SessionWrapper { public: virtual ~SessionWrapper() {} virtual scenic::Session* get() = 0; virtual void Present() = 0; }; class SceneUpdateContext : public flutter::ExternalViewEmbedder { public: class Entity { public: Entity(SceneUpdateContext& context); virtual ~Entity(); SceneUpdateContext& context() { return context_; } scenic::EntityNode& entity_node() { return entity_node_; } virtual scenic::ContainerNode& embedder_node() { return entity_node_; } private: SceneUpdateContext& context_; Entity* const previous_entity_; scenic::EntityNode entity_node_; }; class Transform : public Entity { public: Transform(SceneUpdateContext& context, const SkMatrix& transform); Transform(SceneUpdateContext& context, float scale_x, float scale_y, float scale_z); virtual ~Transform(); private: float const previous_scale_x_; float const previous_scale_y_; }; class Frame : public Entity { public: // When layer is not nullptr, the frame is associated with a layer subtree // rooted with that layer. The frame may then create a surface that will be // retained for that layer. Frame(SceneUpdateContext& context, const SkRRect& rrect, SkColor color, SkAlpha opacity, std::string label); virtual ~Frame(); scenic::ContainerNode& embedder_node() override { return opacity_node_; } void AddPaintLayer(Layer* layer); private: const float previous_elevation_; const SkRRect rrect_; SkColor const color_; SkAlpha const opacity_; scenic::OpacityNodeHACK opacity_node_; std::vector paint_layers_; SkRect paint_bounds_; }; class Clip : public Entity { public: Clip(SceneUpdateContext& context, const SkRect& shape_bounds); ~Clip() = default; }; struct PaintTask { SkRect paint_bounds; SkScalar scale_x; SkScalar scale_y; SkColor background_color; scenic::Material material; std::vector layers; }; SceneUpdateContext(std::string debug_label, fuchsia::ui::views::ViewToken view_token, scenic::ViewRefPair view_ref_pair, SessionWrapper& session); ~SceneUpdateContext() = default; scenic::ContainerNode& root_node() { return root_node_; } // The cumulative alpha value based on all the parent OpacityLayers. void set_alphaf(float alpha) { alpha_ = alpha; } float alphaf() { return alpha_; } // Returns all `PaintTask`s generated for the current frame. std::vector GetPaintTasks(); // Enable/disable wireframe rendering around the root view bounds. void EnableWireframe(bool enable); // Reset state for a new frame. void Reset(); // |ExternalViewEmbedder| SkCanvas* GetRootCanvas() override { return nullptr; } // |ExternalViewEmbedder| void CancelFrame() override {} // |ExternalViewEmbedder| void BeginFrame( SkISize frame_size, GrDirectContext* context, double device_pixel_ratio, fml::RefPtr raster_thread_merger) override {} // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int view_id, std::unique_ptr params) override {} // |ExternalViewEmbedder| std::vector GetCurrentCanvases() override { return std::vector(); } // |ExternalViewEmbedder| virtual SkCanvas* CompositeEmbeddedView(int view_id) override { return nullptr; } void CreateView(int64_t view_id, bool hit_testable, bool focusable); void UpdateView(int64_t view_id, bool hit_testable, bool focusable); void DestroyView(int64_t view_id); void UpdateView(int64_t view_id, const SkPoint& offset, const SkSize& size, std::optional override_hit_testable = std::nullopt); private: void CreateFrame(scenic::EntityNode& entity_node, const SkRRect& rrect, SkColor color, SkAlpha opacity, const SkRect& paint_bounds, std::vector paint_layers); SessionWrapper& session_; scenic::View root_view_; scenic::EntityNode root_node_; std::vector paint_tasks_; Entity* top_entity_ = nullptr; float top_scale_x_ = 1.f; float top_scale_y_ = 1.f; float top_elevation_ = 0.f; float next_elevation_ = 0.f; float alpha_ = 1.f; FML_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext); }; } // namespace flutter #endif // FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_