File: delegated_ink_point_renderer_gpu.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (191 lines) | stat: -rw-r--r-- 7,819 bytes parent folder | download | duplicates (4)
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
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GL_DELEGATED_INK_POINT_RENDERER_GPU_H_
#define UI_GL_DELEGATED_INK_POINT_RENDERER_GPU_H_

#include <dcomp.h>
#include <wrl/client.h>

#include <optional>
#include <vector>

#include "base/check_is_test.h"
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "ui/gfx/delegated_ink_metadata.h"
#include "ui/gfx/delegated_ink_point.h"
#include "ui/gfx/geometry/transform_util.h"
#include "ui/gfx/mojom/delegated_ink_point_renderer.mojom.h"
#include "ui/gl/dc_layer_overlay_params.h"
#include "ui/gl/gl_export.h"

namespace gl {

// On construction, this class will create a new visual for the visual tree with
// an IDCompositionDelegatedInk object as the contents. This will be added as
// a child of the root surface visual in the tree, and the trail will be drawn
// to it. It is a child of the root surface visual because this visual contains
// the swapchain, and there will be no transforms applied to the delegated ink
// visual this way.
// For more information about the design of this class and using the OS APIs,
// view the design doc here: https://aka.ms/GPUBackedDesignDoc
class GL_EXPORT DelegatedInkPointRendererGpu
    : public gfx::mojom::DelegatedInkPointRenderer {
 public:
  DelegatedInkPointRendererGpu();
  ~DelegatedInkPointRendererGpu() override;

  struct DelegatedInkPointCompare {
    bool operator()(const gfx::DelegatedInkPoint& lhs,
                    const gfx::DelegatedInkPoint& rhs) const {
      return lhs.timestamp() < rhs.timestamp();
    }
  };
  using DelegatedInkPointTokenMap = base::flat_map<gfx::DelegatedInkPoint,
                                                   std::optional<unsigned int>,
                                                   DelegatedInkPointCompare>;

  void InitMessagePipeline(
      mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer>
          pending_receiver);

  bool DelegatedInkIsSupported(
      const Microsoft::WRL::ComPtr<IDCompositionDevice2>& dcomp_device) const;

  void SetDelegatedInkTrailStartPoint(
      std::unique_ptr<gfx::DelegatedInkMetadata> metadata);

  void StoreDelegatedInkPoint(const gfx::DelegatedInkPoint& point) override;

  void ResetPrediction() override;

  gfx::DelegatedInkMetadata* MetadataForTesting() const {
    CHECK_IS_TEST();
    return metadata_.get();
  }

  // Creates an overlay for the current frame's Delegated Ink Metadata.
  // If the Delegated Ink Renderer can not be initialized, it returns a
  // nullptr. The ink trail will synchronize its updates with |root_swap_chain|
  // if present, otherwise it will synchronize with DComp commit.
  std::optional<DCLayerOverlayParams> MakeDelegatedInkOverlay(
      IDCompositionDevice2* dcomp_device2,
      IDXGISwapChain1* root_swap_chain,
      std::unique_ptr<gfx::DelegatedInkMetadata> metadata);

  uint64_t InkTrailTokenCountForTesting() const;

  uint64_t DelegatedInkPointPointerIdCountForTesting() const {
    CHECK_IS_TEST();
    return delegated_ink_points_.size();
  }

  bool CheckForPointerIdForTesting(int32_t pointer_id) const;

  const DelegatedInkPointTokenMap& DelegatedInkPointsForTesting(
      int32_t pointer_id) {
    CHECK_IS_TEST();
    DCHECK(delegated_ink_points_.find(pointer_id) !=
           delegated_ink_points_.end());
    return delegated_ink_points_[pointer_id];
  }

  bool WaitForNewTrailToDrawForTesting() const {
    CHECK_IS_TEST();
    return wait_for_new_trail_to_draw_;
  }

  std::vector<gfx::DelegatedInkPoint> PointstoBeDrawnForTesting() const {
    CHECK_IS_TEST();
    return points_to_be_drawn_;
  }

  uint64_t GetMaximumNumberOfPointerIdsForTesting() const;

  void InitializeForTesting(IDCompositionDevice2* dcomp_device2);

  // This function is called after Delegated Ink's points are submitted to be
  // drawn on screen, and fires a histogram with the time between points' event
  // creation and the points' draw submission to the OS.
  void ReportPointsDrawn();

 private:
  bool Initialize(IDCompositionDevice2* dcomp_device2,
                  IDXGISwapChain1* root_swap_chain);

  void EraseExcessPointerIds();

  std::optional<int32_t> GetPointerIdForMetadata();

  void DrawSavedTrailPoints();

  bool DrawDelegatedInkPoint(const gfx::DelegatedInkPoint& point);

  // The delegated ink trail object that the ink trail is drawn on. This is the
  // content of the ink visual.
  Microsoft::WRL::ComPtr<IDCompositionDelegatedInkTrail> delegated_ink_trail_;

  // The swap chain whose updates |delegated_ink_trail_| is synchronized with.
  // If null, |delegated_ink_trail_| is synchronized with DComp commit.
  raw_ptr<IDXGISwapChain1> swap_chain_ = nullptr;

  Microsoft::WRL::ComPtr<IDCompositionInkTrailDevice> ink_trail_device_;

  // The most recent metadata received. The metadata marks the last point of
  // the app rendered stroke, which corresponds to the first point of the
  // delegated ink trail that will be drawn.
  std::unique_ptr<gfx::DelegatedInkMetadata> metadata_;

  // A base::flat_map of all the points that have arrived in
  // StoreDelegatedInkPoint() with a timestamp greater than or equal to that of
  // |metadata_|, where the key is the DelegatedInkPoint that was received, and
  // the value is an optional token. The value will be null until the
  // DelegatedInkPoint is added to the trail, at which point the value is the
  // token that was returned by AddTrailPoints. The elements of the flat_map are
  // sorted by the timestamp of the DelegatedInkPoint. All points are stored in
  // here until we receive a |metadata_|, then any DelegatedInkPoints that have
  // a timestamp earlier than |metadata_|'s are removed, and any new
  // DelegatedInkPoints that may arrive with an earlier timestamp are ignored.
  // Then as each new |metadata| arrives in SetDelegatedInkTrailStartPoint(),
  // we remove any old elements with earlier timestamps, up to and including the
  // element that matches the DelegatedInkMetadata.
  base::flat_map<int32_t, DelegatedInkPointTokenMap> delegated_ink_points_;

  // Cached pointer id of the most recently drawn trail.
  std::optional<int32_t> pointer_id_;

  // Flag to know if new DelegatedInkPoints that arrive should be drawn
  // immediately or if they should wait for a new trail to be started. Set to
  // true when ResetPrediction is called, as this tells us that something about
  // the pointerevents in the browser process changed. When that happens, we
  // should continue to remove points for any metadata that arrive with
  // timestamps that match DelegatedInkPoints that arrived before the
  // ResetPrediction call. However, once a metadata arrives with a timestamp
  // after the ResetPrediction, then we know that inking should continue, so a
  // new trail is started and we try to draw everything in
  // |delegated_ink_points_|.
  bool wait_for_new_trail_to_draw_ = true;

  // Set to true when DelegatedInkPointRendererGPU has been (re)initialized.
  // This can happen due to the first metadata being received, or change in
  // root surface swap chain or DirectCompositionDevice.
  bool force_new_ink_trail_ = false;

  mojo::Receiver<gfx::mojom::DelegatedInkPointRenderer> receiver_{this};

  // Holds the timestamp of points added to the Delegated Ink's Trail to measure
  // the time between point creation and draw operation called.
  std::vector<gfx::DelegatedInkPoint> points_to_be_drawn_;

  // The timestamp in which a Delegated Ink point that matches the metadata was
  // first painted.
  std::optional<base::TimeTicks> metadata_paint_time_;
};

}  // namespace gl

#endif  // UI_GL_DELEGATED_INK_POINT_RENDERER_GPU_H_