// Copyright (c) 2013 The Chromium 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 ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_ #define ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_ #include #include #include #include "android_webview/browser/gfx/begin_frame_source_webview.h" #include "android_webview/browser/gfx/child_frame.h" #include "android_webview/browser/gfx/compositor_frame_producer.h" #include "android_webview/browser/gfx/parent_compositor_draw_constraints.h" #include "android_webview/browser/gfx/root_frame_sink_proxy.h" #include "base/callback.h" #include "base/cancelable_callback.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/trace_event/trace_event.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor_client.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size_f.h" #include "ui/gfx/geometry/vector2d_f.h" class SkCanvas; class SkPicture; namespace content { class WebContents; } namespace android_webview { class BrowserViewRendererClient; class ChildFrame; class CompositorFrameConsumer; class RootFrameSinkProxy; // Interface for all the WebView-specific content rendering operations. // Provides software and hardware rendering and the Capture Picture API. class BrowserViewRenderer : public content::SynchronousCompositorClient, public CompositorFrameProducer, public RootFrameSinkProxyClient { public: static void CalculateTileMemoryPolicy(); static BrowserViewRenderer* FromWebContents( content::WebContents* web_contents); BrowserViewRenderer( BrowserViewRendererClient* client, const scoped_refptr& ui_task_runner); BrowserViewRenderer(const BrowserViewRenderer&) = delete; BrowserViewRenderer& operator=(const BrowserViewRenderer&) = delete; ~BrowserViewRenderer() override; void RegisterWithWebContents(content::WebContents* web_contents); // The BrowserViewRenderer client is responsible for ensuring that // the current compositor frame consumer has been set correctly via // this method. The consumer is added to the set of registered // consumers if it is not already registered. void SetCurrentCompositorFrameConsumer( CompositorFrameConsumer* compositor_frame_consumer); // Called before either OnDrawHardware or OnDrawSoftware to set the view // state of this frame. |scroll| is the view's current scroll offset. // |global_visible_rect| is the intersection of the view size and the window // in window coordinates. void PrepareToDraw(const gfx::Point& scroll, const gfx::Rect& global_visible_rect); // Main handlers for view drawing. A false return value indicates no new // frame is produced. bool OnDrawHardware(); bool OnDrawSoftware(SkCanvas* canvas); bool NeedToDrawBackgroundColor(); // CapturePicture API methods. sk_sp CapturePicture(int width, int height); void EnableOnNewPicture(bool enabled); void ClearView(); void SetOffscreenPreRaster(bool enabled); // View update notifications. void SetIsPaused(bool paused); void SetViewVisibility(bool visible); void SetWindowVisibility(bool visible); void OnSizeChanged(int width, int height); void OnAttachedToWindow(int width, int height); void OnDetachedFromWindow(); void ZoomBy(float delta); void OnComputeScroll(base::TimeTicks animation_time); // Sets the scale for logical<->physical pixel conversions. void SetDipScale(float dip_scale); float dip_scale() const { return dip_scale_; } float page_scale_factor() const { return page_scale_factor_; } // Set the root layer scroll offset to |new_value|. The |new_value| here is in // physical pixel. void ScrollTo(const gfx::Point& new_value); // Set root layer scroll offset on the next scroll state update. void RestoreScrollAfterTransition(const gfx::Point& new_value); // Android views hierarchy gluing. bool IsVisible() const; gfx::Rect GetScreenRect() const; bool view_visible() const { return view_visible_; } bool window_visible() const { return window_visible_; } bool attached_to_window() const { return attached_to_window_; } bool was_attached() const { return was_attached_; } gfx::Size size() const { return size_; } bool IsClientVisible() const; void TrimMemory(); // SynchronousCompositorClient overrides. void DidInitializeCompositor(content::SynchronousCompositor* compositor, const viz::FrameSinkId& frame_sink_id) override; void DidDestroyCompositor(content::SynchronousCompositor* compositor, const viz::FrameSinkId& frame_sink_id) override; void PostInvalidate(content::SynchronousCompositor* compositor) override; void DidUpdateContent(content::SynchronousCompositor* compositor) override; void OnInputEvent(); // |total_scroll_offset|, |total_max_scroll_offset|, and |scrollable_size| are // in DIP scale when --use-zoom-for-dsf is disabled. Otherwise, they are in // physical pixel scale. void UpdateRootLayerState(content::SynchronousCompositor* compositor, const gfx::PointF& total_scroll_offset, const gfx::PointF& total_max_scroll_offset, const gfx::SizeF& scrollable_size, float page_scale_factor, float min_page_scale_factor, float max_page_scale_factor) override; void DidOverscroll(content::SynchronousCompositor* compositor, const gfx::Vector2dF& accumulated_overscroll, const gfx::Vector2dF& latest_overscroll_delta, const gfx::Vector2dF& current_fling_velocity) override; ui::TouchHandleDrawable* CreateDrawable() override; void CopyOutput( content::SynchronousCompositor* compositor, std::unique_ptr copy_request) override; void AddBeginFrameCompletionCallback(base::OnceClosure callback) override; // CompositorFrameProducer overrides base::WeakPtr GetWeakPtr() override; void RemoveCompositorFrameConsumer( CompositorFrameConsumer* consumer) override; void ReturnUsedResources(std::vector resources, const viz::FrameSinkId& frame_sink_id, uint32_t layer_tree_frame_sink_id) override; void OnParentDrawDataUpdated( CompositorFrameConsumer* compositor_frame_consumer) override; void OnViewTreeForceDarkStateChanged( bool view_tree_force_dark_state) override; void ChildSurfaceWasEvicted() override; void SetActiveFrameSinkId(const viz::FrameSinkId& frame_sink_id); // RootFrameSinkProxy overrides void Invalidate() override; void ReturnResourcesFromViz( viz::FrameSinkId frame_sink_id, uint32_t layer_tree_frame_sink_id, std::vector resources) override; void OnCompositorFrameTransitionDirectiveProcessed( viz::FrameSinkId frame_sink_id, uint32_t layer_tree_frame_sink_id, uint32_t sequence_id) override; // Visible for testing. content::SynchronousCompositor* GetActiveCompositorForTesting() const { return compositor_; } bool window_visible_for_tests() const { return window_visible_; } private: void SetActiveCompositor(content::SynchronousCompositor* compositor); void SetTotalRootLayerScrollOffset(const gfx::PointF& new_value_dip); bool CanOnDraw(); bool CompositeSW(SkCanvas* canvas, bool software_canvas); std::unique_ptr RootLayerStateAsValue(const gfx::PointF& total_scroll_offset_dip, const gfx::SizeF& scrollable_size_dip); void ReturnUncommittedFrames(ChildFrameQueue frame); void ReturnUnusedResource(std::unique_ptr frame); void ReturnResourceFromParent( CompositorFrameConsumer* compositor_frame_consumer); void ReleaseHardware(); bool DoUpdateParentDrawData(); void UpdateBeginFrameSource(); gfx::Point max_scroll_offset() const; // Return the tile rect in view space. gfx::Rect ComputeTileRectAndUpdateMemoryPolicy(); content::SynchronousCompositor* FindCompositor( const viz::FrameSinkId& frame_sink_id) const; // For debug tracing or logging. Return the string representation of this // view renderer's state. std::string ToString() const; const raw_ptr client_; const scoped_refptr ui_task_runner_; raw_ptr current_compositor_frame_consumer_; std::unique_ptr root_frame_sink_proxy_; // The current compositor that's owned by the current RVH. raw_ptr compositor_; // The id of the most recent RVH according to RVHChanged. viz::FrameSinkId frame_sink_id_; // A map from compositor's per-WebView unique ID to the compositor's raw // pointer. A raw pointer here is fine because the entry will be erased when // a compositor is destroyed. std::map compositor_map_; bool is_paused_; bool view_visible_; bool window_visible_; // Only applicable if |attached_to_window_| is true. bool attached_to_window_; bool was_attached_; // Whether the view was attached to window at least once. bool hardware_enabled_; float dip_scale_; float page_scale_factor_; float min_page_scale_factor_; float max_page_scale_factor_; bool on_new_picture_enable_; bool clear_view_; // Used for metrics, indicates if we called invalidate since last draw. bool did_invalidate_since_last_draw_ = false; // Approximates whether render thread functor has a frame to draw. It is safe // for Java side to stop blitting the background color once this is true. bool has_rendered_frame_ = false; bool offscreen_pre_raster_; CopyOutputRequestQueue copy_requests_; gfx::Point last_on_draw_scroll_offset_; gfx::Rect last_on_draw_global_visible_rect_; gfx::Size size_; gfx::SizeF scrollable_size_dip_; // When zoom-for-dsf enabled |max_scroll_offset_unscaled_| and // |scroll_offset_unscaled_| is in physical pixel; otherwise, they are in dip gfx::PointF scroll_offset_unscaled_; gfx::PointF max_scroll_offset_unscaled_; // Used to prevent rounding errors from accumulating enough to generate // visible skew (especially noticeable when scrolling up and down in the same // spot over a period of time). gfx::Vector2dF overscroll_rounding_error_; // The scroll to apply after the next scroll state update. absl::optional scroll_on_scroll_state_update_; ParentCompositorDrawConstraints external_draw_constraints_; std::unique_ptr begin_frame_source_; base::WeakPtrFactory weak_ptr_factory_{this}; }; } // namespace android_webview #endif // ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_