File: demo_client.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (137 lines) | stat: -rw-r--r-- 5,979 bytes parent folder | download | duplicates (5)
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
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_
#define COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_

#include <map>
#include <vector>

#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "components/viz/common/frame_timing_details_map.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.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 "mojo/public/cpp/bindings/remote.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"

namespace viz {
class CompositorFrame;
}

namespace demo {

// DemoClient is responsible for communicating with the display-compositor. It
// sends messages to the service over the mojom.CompositorFrameSink interface,
// and receives messages through the mojom.CompositorFrameSinkClient interface.
//
// The client needs to have an identifier, FrameSinkId, which doesn't change
// during the lifetime of the client. The embedder of the client needs to know
// about this FrameSinkId. The 'host', when it itself is not the embedder, also
// needs to know about this FrameSinkId, so that it can set up the
// frame-hierarchy correctly in the service.
//
// The client also needs to have a LocalSurfaceId, which represents an embedding
// of the client in a particular state. If, for example, the size of the client
// changes (or other attributes, like device scale factor), then a new
// LocalSurfaceId needs to be allocated. The LocalSurfaceId is used to submit
// the CompositorFrame. Both the embedder and the embedded clients need to know
// the LocalSurfaceId. It is possible for both the embedder and the embedded
// client to generate new LocalSurfaceId (typically using a
// ParentLocalSurfaceIdAllocator and ChildLocalSurfaceIdAllocator respectively).
// In this demo, only the embedder allocates the LocalSurfaceId.
class DemoClient : public viz::mojom::CompositorFrameSinkClient {
 public:
  DemoClient(const viz::FrameSinkId& frame_sink_id,
             const viz::LocalSurfaceId& local_surface_id,
             const gfx::Rect& bounds);

  DemoClient(const DemoClient&) = delete;
  DemoClient& operator=(const DemoClient&) = delete;

  ~DemoClient() override;

  const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }

  // Initializes the mojo connection to the service.
  void Initialize(
      mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient> receiver,
      mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink>
          sink_remote);
  void Initialize(
      mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient> receiver,
      mojo::PendingRemote<viz::mojom::CompositorFrameSink> sink_remote);

  // This prepares for this client to embed another client (i.e. this client
  // acts as the embedder). Since this client is the embedder, it allocates the
  // LocalSurfaceId, and returns that. The client that should be embedded (i.e.
  // the client represented by |frame_sink_id|) should use the returned
  // LocalSurfaceId to submit visual content (CompositorFrame).
  viz::LocalSurfaceId Embed(const viz::FrameSinkId& frame_sink_id,
                            const gfx::Rect& bounds);

  // When this client is resized, it is important that it also receives a new
  // LocalSurfaceId with the new size.
  void Resize(const gfx::Size& size,
              const viz::LocalSurfaceId& local_surface_id);

 private:
  struct EmbedInfo {
    viz::LocalSurfaceId lsid;
    gfx::Rect bounds;
    float degrees = 0.f;
  };

  viz::CompositorFrame CreateFrame(const viz::BeginFrameArgs& args)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);
  viz::mojom::CompositorFrameSink* GetPtr();

  void InitializeOnThread(
      mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient> receiver,
      mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink>
          associated_sink_remote,
      mojo::PendingRemote<viz::mojom::CompositorFrameSink> sink_remote);

  // viz::mojom::CompositorFrameSinkClient:
  void DidReceiveCompositorFrameAck(
      std::vector<viz::ReturnedResource> resources) override;
  void OnBeginFrame(const viz::BeginFrameArgs& args,
                    const viz::FrameTimingDetailsMap& timing_details,
                    std::vector<viz::ReturnedResource> resources) override;
  void OnBeginFramePausedChanged(bool paused) override;
  void ReclaimResources(std::vector<viz::ReturnedResource> resources) override;
  void OnCompositorFrameTransitionDirectiveProcessed(
      uint32_t sequence_id) override {}
  void OnSurfaceEvicted(const viz::LocalSurfaceId& local_surface_id) override {}

  // This thread is created solely to demonstrate that the client can live in
  // its own thread (or even in its own process). A viz client does not need to
  // have its own thread.
  base::Thread thread_;

  const viz::FrameSinkId frame_sink_id_;
  viz::LocalSurfaceId local_surface_id_ GUARDED_BY(lock_);
  gfx::Rect bounds_ GUARDED_BY(lock_);

  mojo::Receiver<viz::mojom::CompositorFrameSinkClient> receiver_{this};
  mojo::AssociatedRemote<viz::mojom::CompositorFrameSink> associated_sink_;
  mojo::Remote<viz::mojom::CompositorFrameSink> sink_;
  viz::FrameTokenGenerator next_frame_token_;
  uint32_t frame_count_ = 0;

  base::Lock lock_;
  // The |allocator_| is used only when this client acts as an embedder, and
  // embeds other clients.
  viz::ParentLocalSurfaceIdAllocator allocator_;
  std::map<viz::FrameSinkId, EmbedInfo> embeds_ GUARDED_BY(lock_);
};

}  // namespace demo

#endif  // COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_