• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "host/libs/wayland/wayland_server.h"
18 
19 #include <android-base/logging.h>
20 
21 #include <wayland-server-core.h>
22 #include <wayland-server-protocol.h>
23 
24 #include "host/libs/wayland/wayland_compositor.h"
25 #include "host/libs/wayland/wayland_dmabuf.h"
26 #include "host/libs/wayland/wayland_seat.h"
27 #include "host/libs/wayland/wayland_shell.h"
28 #include "host/libs/wayland/wayland_subcompositor.h"
29 #include "host/libs/wayland/wayland_surface.h"
30 #include "host/libs/wayland/wayland_utils.h"
31 
32 namespace wayland {
33 namespace internal {
34 
35 struct WaylandServerState {
36   struct wl_display* display_ = nullptr;
37 
38   Surfaces surfaces_;
39 };
40 
41 }  // namespace internal
42 
WaylandServer(int wayland_socket_fd)43 WaylandServer::WaylandServer(int wayland_socket_fd) {
44   server_thread_ =
45       std::thread(
46           [this, wayland_socket_fd]() {
47             ServerLoop(wayland_socket_fd);
48           });
49 
50   std::unique_lock<std::mutex> lock(server_ready_mutex_);
51   server_ready_cv_.wait(lock, [&]{return server_ready_; });
52 }
53 
~WaylandServer()54 WaylandServer::~WaylandServer() {
55   wl_display_terminate(server_state_->display_);
56   server_thread_.join();
57 }
58 
ServerLoop(int fd)59 void WaylandServer::ServerLoop(int fd) {
60   server_state_.reset(new internal::WaylandServerState());
61 
62   server_state_->display_ = wl_display_create();
63   CHECK(server_state_->display_ != nullptr)
64     << "Failed to start WaylandServer: failed to create display";
65 
66   if (fd < 0) {
67     const char* socket = wl_display_add_socket_auto(server_state_->display_);
68     CHECK(socket != nullptr)
69         << "Failed to start WaylandServer: failed to create socket";
70 
71     LOG(INFO) << "WaylandServer running on socket " << socket;
72   } else {
73     CHECK(wl_display_add_socket_fd(server_state_->display_, fd) == 0)
74         << "Failed to start WaylandServer: failed to use fd " << fd;
75 
76     LOG(INFO) << "WaylandServer running on socket " << fd;
77   }
78 
79   wl_display_init_shm(server_state_->display_);
80 
81   BindCompositorInterface(server_state_->display_, &server_state_->surfaces_);
82   BindDmabufInterface(server_state_->display_);
83   BindSubcompositorInterface(server_state_->display_);
84   BindSeatInterface(server_state_->display_);
85   BindShellInterface(server_state_->display_);
86 
87   {
88     std::lock_guard<std::mutex> lock(server_ready_mutex_);
89     server_ready_ = true;
90   }
91   server_ready_cv_.notify_one();
92 
93   wl_display_run(server_state_->display_);
94   wl_display_destroy(server_state_->display_);
95 }
96 
OnNextFrame(const Surfaces::FrameCallback & callback)97 void WaylandServer::OnNextFrame(const Surfaces::FrameCallback& callback) {
98   server_state_->surfaces_.OnNextFrame(callback);
99 }
100 
101 }  // namespace wayland
102