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)43WaylandServer::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()54WaylandServer::~WaylandServer() { 55 wl_display_terminate(server_state_->display_); 56 server_thread_.join(); 57 } 58 ServerLoop(int fd)59void 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)97void WaylandServer::OnNextFrame(const Surfaces::FrameCallback& callback) { 98 server_state_->surfaces_.OnNextFrame(callback); 99 } 100 101 } // namespace wayland 102