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