1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_CANVAS_RESOURCE_DISPATCHER_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_CANVAS_RESOURCE_DISPATCHER_H_ 7 8 #include <memory> 9 10 #include "base/memory/read_only_shared_memory_region.h" 11 #include "components/viz/common/frame_sinks/begin_frame_args.h" 12 #include "components/viz/common/resources/resource_id.h" 13 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" 14 #include "mojo/public/cpp/bindings/receiver.h" 15 #include "mojo/public/cpp/bindings/remote.h" 16 #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h" 17 #include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h" 18 #include "third_party/blink/renderer/platform/geometry/int_size.h" 19 #include "third_party/blink/renderer/platform/platform_export.h" 20 21 namespace blink { 22 23 class CanvasResource; 24 25 class CanvasResourceDispatcherClient { 26 public: 27 virtual bool BeginFrame() = 0; 28 virtual void SetFilterQualityInResource(SkFilterQuality filter_quality) = 0; 29 }; 30 31 class PLATFORM_EXPORT CanvasResourceDispatcher 32 : public viz::mojom::blink::CompositorFrameSinkClient { 33 public: GetWeakPtr()34 base::WeakPtr<CanvasResourceDispatcher> GetWeakPtr() { 35 return weak_ptr_factory_.GetWeakPtr(); 36 } 37 Client()38 CanvasResourceDispatcherClient* Client() { return client_; } 39 40 enum { 41 kInvalidPlaceholderCanvasId = -1, 42 }; 43 44 CanvasResourceDispatcher(CanvasResourceDispatcherClient*, 45 uint32_t client_id, 46 uint32_t sink_id, 47 int placeholder_canvas_id, 48 const IntSize&); 49 50 ~CanvasResourceDispatcher() override; 51 void SetNeedsBeginFrame(bool); 52 void SetSuspendAnimation(bool); NeedsBeginFrame()53 bool NeedsBeginFrame() const { return needs_begin_frame_; } IsAnimationSuspended()54 bool IsAnimationSuspended() const { return suspend_animation_; } 55 void DispatchFrame(scoped_refptr<CanvasResource>, 56 base::TimeTicks commit_start_time, 57 const SkIRect& damage_rect, 58 bool needs_vertical_flip, 59 bool is_opaque); 60 void ReclaimResource(viz::ResourceId); 61 void DispatchFrameSync(scoped_refptr<CanvasResource>, 62 base::TimeTicks commit_start_time, 63 const SkIRect& damage_rect, 64 bool needs_vertical_flip, 65 bool is_opaque); ReplaceBeginFrameAck(const viz::BeginFrameArgs & args)66 void ReplaceBeginFrameAck(const viz::BeginFrameArgs& args) { 67 current_begin_frame_ack_ = viz::BeginFrameAck(args, true); 68 } 69 bool HasTooManyPendingFrames() const; 70 71 void Reshape(const IntSize&); 72 73 // viz::mojom::blink::CompositorFrameSinkClient implementation. 74 void DidReceiveCompositorFrameAck( 75 const WTF::Vector<viz::ReturnedResource>& resources) final; 76 void OnBeginFrame( 77 const viz::BeginFrameArgs&, 78 WTF::HashMap<uint32_t, ::viz::mojom::blink::FrameTimingDetailsPtr>) final; OnBeginFramePausedChanged(bool paused)79 void OnBeginFramePausedChanged(bool paused) final {} 80 void ReclaimResources( 81 const WTF::Vector<viz::ReturnedResource>& resources) final; 82 83 void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region, 84 ::gpu::mojom::blink::MailboxPtr id); 85 void DidDeleteSharedBitmap(::gpu::mojom::blink::MailboxPtr id); 86 87 void SetFilterQuality(SkFilterQuality filter_quality); 88 void SetPlaceholderCanvasDispatcher(int placeholder_canvas_id); 89 90 private: 91 friend class CanvasResourceDispatcherTest; 92 struct FrameResource; 93 using ResourceMap = HashMap<unsigned, std::unique_ptr<FrameResource>>; 94 95 bool PrepareFrame(scoped_refptr<CanvasResource>, 96 base::TimeTicks commit_start_time, 97 const SkIRect& damage_rect, 98 bool needs_vertical_flip, 99 bool is_opaque, 100 viz::CompositorFrame* frame); 101 102 // Surface-related 103 viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; 104 const viz::FrameSinkId frame_sink_id_; 105 106 IntSize size_; 107 bool change_size_for_next_commit_; 108 bool suspend_animation_ = false; 109 bool needs_begin_frame_ = false; 110 int pending_compositor_frames_ = 0; 111 112 void SetNeedsBeginFrameInternal(); 113 114 bool VerifyImageSize(const IntSize); 115 void PostImageToPlaceholderIfNotBlocked(scoped_refptr<CanvasResource>, 116 viz::ResourceId resource_id); 117 // virtual for testing 118 virtual void PostImageToPlaceholder(scoped_refptr<CanvasResource>, 119 viz::ResourceId resource_id); 120 121 void ReclaimResourceInternal(viz::ResourceId resource_id); 122 void ReclaimResourceInternal(const ResourceMap::iterator&); 123 124 mojo::Remote<viz::mojom::blink::CompositorFrameSink> sink_; 125 mojo::Remote<mojom::blink::SurfaceEmbedder> surface_embedder_; 126 mojo::Receiver<viz::mojom::blink::CompositorFrameSinkClient> receiver_{this}; 127 128 int placeholder_canvas_id_; 129 130 unsigned next_resource_id_ = 0; 131 ResourceMap resources_; 132 133 viz::FrameTokenGenerator next_frame_token_; 134 135 // The latest_unposted_resource_id_ always refers to the Id of the frame 136 // resource used by the latest_unposted_image_. 137 scoped_refptr<CanvasResource> latest_unposted_image_; 138 viz::ResourceId latest_unposted_resource_id_; 139 unsigned num_unreclaimed_frames_posted_; 140 141 viz::BeginFrameAck current_begin_frame_ack_; 142 143 CanvasResourceDispatcherClient* client_; 144 145 base::WeakPtrFactory<CanvasResourceDispatcher> weak_ptr_factory_{this}; 146 }; 147 148 } // namespace blink 149 150 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_H_ 151