1 // Copyright 2017 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 COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_BASE_H_
6 #define COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_BASE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/memory/shared_memory_mapping.h"
13 #include "components/exo/wayland/clients/client_helper.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkRefCnt.h"
16 #include "ui/gfx/geometry/size.h"
17 #include "ui/gl/gl_context.h"
18 #include "ui/gl/gl_surface.h"
19 #include "ui/gl/scoped_make_current.h"
20 
21 #if defined(USE_GBM)
22 #include <gbm.h>
23 #if defined(USE_VULKAN)
24 #include "gpu/vulkan/vulkan_implementation.h"
25 #endif  // defined(USE_VULKAN)
26 #endif  // defined(USE_GBM)
27 
28 namespace base {
29 class CommandLine;
30 }
31 
32 namespace exo {
33 namespace wayland {
34 namespace clients {
35 
36 class ClientBase {
37  public:
38   struct InitParams {
39     InitParams();
40     ~InitParams();
41     InitParams(const InitParams& params);
42 
43     bool FromCommandLine(const base::CommandLine& command_line);
44 
45     std::string title = "Wayland Client";
46     size_t num_buffers = 2;
47     size_t width = 256;
48     size_t height = 256;
49     int scale = 1;
50     int transform = WL_OUTPUT_TRANSFORM_NORMAL;
51     bool has_transform = false;
52     bool fullscreen = false;
53     bool transparent_background = false;
54     bool use_drm = false;
55     std::string use_drm_value;
56     int32_t drm_format = 0;
57     int32_t bo_usage = 0;
58     bool y_invert = false;
59     bool allocate_buffers_with_output_mode = false;
60     bool use_fullscreen_shell = false;
61     bool use_memfd = false;
62     bool use_touch = false;
63     bool use_vulkan = false;
64   };
65 
66   struct Globals {
67     Globals();
68     ~Globals();
69 
70     std::unique_ptr<wl_output> output;
71     std::unique_ptr<wl_compositor> compositor;
72     std::unique_ptr<wl_shm> shm;
73     std::unique_ptr<wp_presentation> presentation;
74     std::unique_ptr<zwp_linux_dmabuf_v1> linux_dmabuf;
75     std::unique_ptr<wl_shell> shell;
76     std::unique_ptr<wl_seat> seat;
77     std::unique_ptr<wl_subcompositor> subcompositor;
78     std::unique_ptr<wl_touch> touch;
79     std::unique_ptr<zaura_shell> aura_shell;
80     std::unique_ptr<zwp_fullscreen_shell_v1> fullscreen_shell;
81     std::unique_ptr<zwp_input_timestamps_manager_v1> input_timestamps_manager;
82     std::unique_ptr<zwp_linux_explicit_synchronization_v1>
83         linux_explicit_synchronization;
84     std::unique_ptr<zcr_vsync_feedback_v1> vsync_feedback;
85     std::unique_ptr<zcr_color_space_v1> color_space;
86   };
87 
88   struct Buffer {
89     Buffer();
90     ~Buffer();
91 
92     std::unique_ptr<wl_buffer> buffer;
93     bool busy = false;
94 #if defined(USE_GBM)
95     std::unique_ptr<gbm_bo> bo;
96     std::unique_ptr<ScopedEglImage> egl_image;
97     std::unique_ptr<ScopedEglSync> egl_sync;
98     std::unique_ptr<ScopedTexture> texture;
99 #if defined(USE_VULKAN)
100     std::unique_ptr<ScopedVkDeviceMemory> vk_memory;
101     std::unique_ptr<ScopedVkImage> vk_image;
102     std::unique_ptr<ScopedVkImageView> vk_image_view;
103     std::unique_ptr<ScopedVkFramebuffer> vk_framebuffer;
104 #endif  // defined(USE_VULKAN)
105 #endif  // defined(USE_GBM)
106     std::unique_ptr<zwp_linux_buffer_params_v1> params;
107     std::unique_ptr<wl_shm_pool> shm_pool;
108     base::SharedMemoryMapping shared_memory_mapping;
109     sk_sp<SkSurface> sk_surface;
110   };
111 
112   bool Init(const InitParams& params);
113 
114  protected:
115   ClientBase();
116   virtual ~ClientBase();
117   std::unique_ptr<Buffer> CreateBuffer(
118       const gfx::Size& size,
119       int32_t drm_format,
120       int32_t bo_usage,
121       wl_buffer_listener* buffer_listener = nullptr,
122       void* data = nullptr);
123   std::unique_ptr<Buffer> CreateDrmBuffer(const gfx::Size& size,
124                                           int32_t drm_format,
125                                           int32_t bo_usage,
126                                           bool y_invert);
127   ClientBase::Buffer* DequeueBuffer();
128 
129   // wl_output_listener
130   virtual void HandleGeometry(void* data,
131                               struct wl_output* wl_output,
132                               int32_t x,
133                               int32_t y,
134                               int32_t physical_width,
135                               int32_t physical_height,
136                               int32_t subpixel,
137                               const char* make,
138                               const char* model,
139                               int32_t transform);
140   virtual void HandleMode(void* data,
141                           struct wl_output* wl_output,
142                           uint32_t flags,
143                           int32_t width,
144                           int32_t height,
145                           int32_t refresh);
146   virtual void HandleDone(void* data, struct wl_output* wl_output);
147   virtual void HandleScale(void* data,
148                            struct wl_output* wl_output,
149                            int32_t factor);
150 
151   // wl_touch_listener
152   virtual void HandleDown(void* data,
153                           struct wl_touch* wl_touch,
154                           uint32_t serial,
155                           uint32_t time,
156                           struct wl_surface* surface,
157                           int32_t id,
158                           wl_fixed_t x,
159                           wl_fixed_t y);
160   virtual void HandleUp(void* data,
161                         struct wl_touch* wl_touch,
162                         uint32_t serial,
163                         uint32_t time,
164                         int32_t id);
165   virtual void HandleMotion(void* data,
166                             struct wl_touch* wl_touch,
167                             uint32_t time,
168                             int32_t id,
169                             wl_fixed_t x,
170                             wl_fixed_t y);
171   virtual void HandleFrame(void* data, struct wl_touch* wl_touch);
172   virtual void HandleCancel(void* data, struct wl_touch* wl_touch);
173   virtual void HandleShape(void* data,
174                            struct wl_touch* wl_touch,
175                            int32_t id,
176                            wl_fixed_t major,
177                            wl_fixed_t minor);
178   virtual void HandleOrientation(void* data,
179                                  struct wl_touch* wl_touch,
180                                  int32_t id,
181                                  wl_fixed_t orientation);
182 
183   gfx::Size size_ = gfx::Size(256, 256);
184   int scale_ = 1;
185   int transform_ = WL_OUTPUT_TRANSFORM_NORMAL;
186   bool has_transform_ = false;
187   gfx::Size surface_size_ = gfx::Size(256, 256);
188   bool fullscreen_ = false;
189   bool use_memfd_ = false;
190   bool transparent_background_ = false;
191   bool y_invert_ = false;
192 
193   std::unique_ptr<wl_display> display_;
194   std::unique_ptr<wl_registry> registry_;
195   std::unique_ptr<wl_surface> surface_;
196   std::unique_ptr<wl_shell_surface> shell_surface_;
197   Globals globals_;
198 #if defined(USE_GBM)
199   base::ScopedFD drm_fd_;
200   std::unique_ptr<gbm_device> device_;
201 #if defined(USE_VULKAN)
202   std::unique_ptr<gpu::VulkanImplementation> vk_implementation_;
203   std::unique_ptr<ScopedVkInstance> vk_instance_;
204   std::unique_ptr<ScopedVkDevice> vk_device_;
205   std::unique_ptr<ScopedVkCommandPool> vk_command_pool_;
206   std::unique_ptr<ScopedVkRenderPass> vk_render_pass_;
207   VkQueue vk_queue_;
208 #endif
209 #endif
210   scoped_refptr<gl::GLSurface> gl_surface_;
211   scoped_refptr<gl::GLContext> gl_context_;
212   std::unique_ptr<ui::ScopedMakeCurrent> make_current_;
213   unsigned egl_sync_type_ = 0;
214   std::vector<std::unique_ptr<Buffer>> buffers_;
215   sk_sp<GrContext> gr_context_;
216 
217  private:
218   DISALLOW_COPY_AND_ASSIGN(ClientBase);
219 };
220 
221 }  // namespace clients
222 }  // namespace wayland
223 }  // namespace exo
224 
225 #endif  // COMPONENTS_EXO_WAYLAND_CLIENTS_CLIENT_BASE_H_
226