summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.h
blob: 8a5436649c7de48416874d8594848dba5cb88188 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// Copyright 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_ANDROID_WEBVIEW_SYNCHRONOUS_LAYER_TREE_FRAME_SINK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_ANDROID_WEBVIEW_SYNCHRONOUS_LAYER_TREE_FRAME_SINK_H_

#include <stddef.h>

#include <memory>

#include "base/callback.h"
#include "base/cancelable_callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/managed_memory_policy.h"
#include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_timing_details_map.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/service/display/display_client.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-forward.h"
#include "third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_compositor_registry.h"
#include "ui/gfx/transform.h"

class SkCanvas;

namespace viz {
class BeginFrameSource;
class CompositorFrameSinkSupport;
class ContextProvider;
class Display;
class FrameSinkManagerImpl;
class ParentLocalSurfaceIdAllocator;
}  // namespace viz

namespace blink {

// This class represents the client interface for the frame sink
// created for the synchronous compositor.
class SynchronousLayerTreeFrameSinkClient {
 public:
  virtual void DidActivatePendingTree() = 0;
  virtual void Invalidate(bool needs_draw) = 0;
  virtual void SubmitCompositorFrame(
      uint32_t layer_tree_frame_sink_id,
      base::Optional<viz::CompositorFrame> frame,
      base::Optional<viz::HitTestRegionList> hit_test_region_list) = 0;
  virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
  virtual void SinkDestroyed() = 0;

 protected:
  virtual ~SynchronousLayerTreeFrameSinkClient() {}
};

// Specialization of the output surface that adapts it to implement the
// blink::mojom::SynchronousCompositor public API. This class effects an
// "inversion of control" - enabling drawing to be  orchestrated by the
// embedding layer, instead of driven by the compositor internals - hence it
// holds two 'client' pointers (|client_| in the LayerTreeFrameSink baseclass
// and |delegate_|) which represent the consumers of the two roles in plays.
// This class can be created only on the main thread, but then becomes pinned
// to a fixed thread when BindToClient is called.
class SynchronousLayerTreeFrameSink
    : public cc::LayerTreeFrameSink,
      public viz::mojom::blink::CompositorFrameSinkClient,
      public viz::ExternalBeginFrameSourceClient {
 public:
  SynchronousLayerTreeFrameSink(
      scoped_refptr<viz::ContextProvider> context_provider,
      scoped_refptr<viz::RasterContextProvider> worker_context_provider,
      scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
      uint32_t layer_tree_frame_sink_id,
      std::unique_ptr<viz::BeginFrameSource> begin_frame_source,
      SynchronousCompositorRegistry* registry,
      mojo::PendingRemote<viz::mojom::blink::CompositorFrameSink>
          compositor_frame_sink_remote,
      mojo::PendingReceiver<viz::mojom::blink::CompositorFrameSinkClient>
          client_receiver);
  ~SynchronousLayerTreeFrameSink() override;

  // cc::LayerTreeFrameSink implementation.
  bool BindToClient(cc::LayerTreeFrameSinkClient* sink_client) override;
  void DetachFromClient() override;
  void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
  void SubmitCompositorFrame(viz::CompositorFrame frame,
                             bool hit_test_data_changed,
                             bool show_hit_test_borders) override;
  void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
  void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region,
                               const viz::SharedBitmapId& id) override;
  void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
  void Invalidate(bool needs_draw) override;

  // viz::mojom::CompositorFrameSinkClient implementation.
  void DidReceiveCompositorFrameAck(
      const Vector<viz::ReturnedResource>& resources) override;
  void OnBeginFrame(const viz::BeginFrameArgs& args,
                    const HashMap<uint32_t, viz::FrameTimingDetails>&
                        timing_details) override;
  void ReclaimResources(
      const Vector<viz::ReturnedResource>& resources) override;
  void OnBeginFramePausedChanged(bool paused) override;

  // viz::ExternalBeginFrameSourceClient overrides.
  void OnNeedsBeginFrames(bool needs_begin_frames) override;

  void SetSyncClient(SynchronousLayerTreeFrameSinkClient* compositor);
  void DidPresentCompositorFrame(
      const viz::FrameTimingDetailsMap& timing_details);
  void BeginFrame(const viz::BeginFrameArgs& args);
  void SetBeginFrameSourcePaused(bool paused);
  void SetMemoryPolicy(size_t bytes_limit);
  void ReclaimResources(uint32_t layer_tree_frame_sink_id,
                        const Vector<viz::ReturnedResource>& resources);
  void DemandDrawHw(const gfx::Size& viewport_size,
                    const gfx::Rect& viewport_rect_for_tile_priority,
                    const gfx::Transform& transform_for_tile_priority);
  void DemandDrawSw(SkCanvas* canvas);
  void DemandDrawSwZeroCopy();
  void WillSkipDraw();
  bool UseZeroCopySoftwareDraw();

 private:
  class SoftwareOutputSurface;

  void InvokeComposite(const gfx::Transform& transform,
                       const gfx::Rect& viewport);
  void DidActivatePendingTree();
  void DeliverMessages();

  const uint32_t layer_tree_frame_sink_id_;
  SynchronousCompositorRegistry* const registry_;  // Not owned.

  // Not owned.
  SynchronousLayerTreeFrameSinkClient* sync_client_ = nullptr;

  // Used to allocate bitmaps in the software Display.
  // TODO(crbug.com/692814): The Display never sends its resources out of
  // process so there is no reason for it to use a SharedBitmapManager.
  viz::ServerSharedBitmapManager shared_bitmap_manager_;

  // Only valid (non-null) during a DemandDrawSw() call.
  SkCanvas* current_sw_canvas_ = nullptr;

  cc::ManagedMemoryPolicy memory_policy_;
  bool in_software_draw_ = false;
  bool did_submit_frame_ = false;

  mojo::PendingRemote<viz::mojom::blink::CompositorFrameSink>
      unbound_compositor_frame_sink_;
  mojo::PendingReceiver<viz::mojom::blink::CompositorFrameSinkClient>
      unbound_client_;
  viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
  mojo::Receiver<viz::mojom::blink::CompositorFrameSinkClient> client_receiver_{
      this};
  viz::LocalSurfaceId local_surface_id_;

  class StubDisplayClient : public viz::DisplayClient {
    void DisplayOutputSurfaceLost() override {}
    void DisplayWillDrawAndSwap(
        bool will_draw_and_swap,
        viz::AggregatedRenderPassList* render_passes) override {}
    void DisplayDidDrawAndSwap() override {}
    void DisplayDidReceiveCALayerParams(
        const gfx::CALayerParams& ca_layer_params) override {}
    void DisplayDidCompleteSwapWithSize(const gfx::Size& pixel_size) override {}
    void SetWideColorEnabled(bool enabled) override {}
    void SetPreferredFrameInterval(base::TimeDelta interval) override {}
    base::TimeDelta GetPreferredFrameIntervalForFrameSinkId(
        const viz::FrameSinkId& id,
        viz::mojom::CompositorFrameSinkType* type) override;
  };

  viz::DebugRendererSettings debug_settings_;

  // TODO(danakj): These don't to be stored in unique_ptrs when OutputSurface
  // is owned/destroyed on the compositor thread.
  std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
  viz::ParentLocalSurfaceIdAllocator root_local_surface_id_allocator_;
  viz::ParentLocalSurfaceIdAllocator child_local_surface_id_allocator_;
  viz::LocalSurfaceId child_local_surface_id_;
  viz::LocalSurfaceId root_local_surface_id_;
  gfx::Size child_size_;
  gfx::Size display_size_;
  float device_scale_factor_ = 0;
  std::unique_ptr<viz::mojom::CompositorFrameSinkClient>
      software_frame_sink_client_;
  // Uses frame_sink_manager_.
  std::unique_ptr<viz::CompositorFrameSinkSupport> root_support_;
  // Uses frame_sink_manager_.
  std::unique_ptr<viz::CompositorFrameSinkSupport> child_support_;
  StubDisplayClient display_client_;
  // Uses frame_sink_manager_.
  std::unique_ptr<viz::Display> display_;
  // Owned by |display_|.
  SoftwareOutputSurface* software_output_surface_ = nullptr;
  std::unique_ptr<viz::BeginFrameSource> synthetic_begin_frame_source_;
  std::unique_ptr<viz::ExternalBeginFrameSource> external_begin_frame_source_;

  gfx::Rect sw_viewport_for_current_draw_;

  THREAD_CHECKER(thread_checker_);

  // Indicates that webview using viz
  const bool viz_frame_submission_enabled_;
  bool begin_frames_paused_ = false;
  bool needs_begin_frames_ = false;
  const bool use_zero_copy_sw_draw_;

  DISALLOW_COPY_AND_ASSIGN(SynchronousLayerTreeFrameSink);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_ANDROID_WEBVIEW_SYNCHRONOUS_LAYER_TREE_FRAME_SINK_H_