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_dmabuf.h"
18 
19 #include <android-base/logging.h>
20 
21 #include <drm_fourcc.h>
22 
23 #include <linux-dmabuf-unstable-v1-server-protocol.h>
24 #include <wayland-server-core.h>
25 #include <wayland-server-protocol.h>
26 
27 namespace wayland {
28 namespace {
29 
buffer_destroy(wl_client *,wl_resource * buffer)30 void buffer_destroy(wl_client*, wl_resource* buffer) {
31   LOG(VERBOSE) << __FUNCTION__
32                << " buffer=" << buffer;
33 
34   wl_resource_destroy(buffer);
35 }
36 
37 const struct wl_buffer_interface buffer_implementation = {
38     .destroy = buffer_destroy
39 };
40 
linux_buffer_params_destroy(wl_client *,wl_resource * params)41 void linux_buffer_params_destroy(wl_client*, wl_resource* params) {
42   LOG(VERBOSE) << __FUNCTION__
43                << " params=" << params;
44 
45   wl_resource_destroy(params);
46 }
47 
params_destroy_resource_callback(struct wl_resource *)48 void params_destroy_resource_callback(struct wl_resource*) {}
49 
linux_buffer_params_add(wl_client *,wl_resource * params,int32_t fd,uint32_t plane,uint32_t offset,uint32_t stride,uint32_t modifier_hi,uint32_t modifier_lo)50 void linux_buffer_params_add(wl_client*,
51                              wl_resource* params,
52                              int32_t fd,
53                              uint32_t plane,
54                              uint32_t offset,
55                              uint32_t stride,
56                              uint32_t modifier_hi,
57                              uint32_t modifier_lo) {
58   LOG(VERBOSE) << __FUNCTION__
59                << " params=" << params
60                << " fd=" << fd
61                << " plane=" << plane
62                << " offset=" << offset
63                << " stride=" << stride
64                << " mod_hi=" << modifier_hi
65                << " mod_lo=" << modifier_lo;
66 }
67 
linux_buffer_params_create(wl_client * client,wl_resource * params,int32_t w,int32_t h,uint32_t format,uint32_t flags)68 void linux_buffer_params_create(wl_client* client,
69                                 wl_resource* params,
70                                 int32_t w,
71                                 int32_t h,
72                                 uint32_t format,
73                                 uint32_t flags) {
74   LOG(VERBOSE) << __FUNCTION__
75                << " params=" << params
76                << " w=" << w
77                << " h=" << h
78                << " format=" << format
79                << " flags=" << flags;
80 
81   wl_resource* buffer_resource =
82       wl_resource_create(client, &wl_buffer_interface, 1, 0);
83 
84   wl_resource_set_implementation(buffer_resource, &buffer_implementation,
85                                  nullptr, params_destroy_resource_callback);
86 }
87 
linux_buffer_params_create_immed(wl_client * client,wl_resource * params,uint32_t id,int32_t w,int32_t h,uint32_t format,uint32_t flags)88 void linux_buffer_params_create_immed(wl_client* client,
89                                       wl_resource* params,
90                                       uint32_t id,
91                                       int32_t w,
92                                       int32_t h,
93                                       uint32_t format,
94                                       uint32_t flags) {
95   LOG(VERBOSE) << __FUNCTION__
96                << " params=" << params
97                << " id=" << id
98                << " w=" << w
99                << " h=" << h
100                << " format=" << format
101                << " flags=" << flags;
102 
103   wl_resource* buffer_resource =
104       wl_resource_create(client, &wl_buffer_interface, 1, id);
105 
106   wl_resource_set_implementation(buffer_resource, &buffer_implementation,
107                                  nullptr, params_destroy_resource_callback);
108 }
109 
110 const struct zwp_linux_buffer_params_v1_interface
111     zwp_linux_buffer_params_implementation = {
112         .destroy = linux_buffer_params_destroy,
113         .add = linux_buffer_params_add,
114         .create = linux_buffer_params_create,
115         .create_immed = linux_buffer_params_create_immed};
116 
linux_dmabuf_destroy(wl_client *,wl_resource * dmabuf)117 void linux_dmabuf_destroy(wl_client*, wl_resource* dmabuf) {
118   LOG(VERBOSE) << __FUNCTION__
119                << " dmabuf=" << dmabuf;
120 
121   wl_resource_destroy(dmabuf);
122 }
123 
linux_dmabuf_create_params(wl_client * client,wl_resource * display,uint32_t id)124 void linux_dmabuf_create_params(wl_client* client,
125                                 wl_resource* display,
126                                 uint32_t id) {
127   LOG(VERBOSE) << __FUNCTION__
128                << " display=" << display
129                << " id=" << id;
130 
131   wl_resource* buffer_params_resource =
132       wl_resource_create(client, &zwp_linux_buffer_params_v1_interface, 1, id);
133 
134   wl_resource_set_implementation(buffer_params_resource,
135                                  &zwp_linux_buffer_params_implementation,
136                                  nullptr, params_destroy_resource_callback);
137 }
138 
139 const struct zwp_linux_dmabuf_v1_interface
140     zwp_linux_dmabuf_v1_implementation = {
141         .destroy = linux_dmabuf_destroy,
142         .create_params = linux_dmabuf_create_params};
143 
144 constexpr uint32_t kLinuxDmabufVersion = 2;
145 
bind_linux_dmabuf(wl_client * client,void * data,uint32_t version,uint32_t id)146 void bind_linux_dmabuf(wl_client* client,
147                        void* data,
148                        uint32_t version,
149                        uint32_t id) {
150   wl_resource* resource =
151       wl_resource_create(client, &zwp_linux_dmabuf_v1_interface,
152                          std::min(version, kLinuxDmabufVersion), id);
153 
154   wl_resource_set_implementation(resource, &zwp_linux_dmabuf_v1_implementation,
155                                  data, nullptr);
156 
157   zwp_linux_dmabuf_v1_send_format(resource, DRM_FORMAT_ARGB8888);
158 }
159 
160 }  // namespace
161 
BindDmabufInterface(wl_display * display)162 void BindDmabufInterface(wl_display* display) {
163   wl_global_create(display, &zwp_linux_dmabuf_v1_interface,
164                    kLinuxDmabufVersion, nullptr, bind_linux_dmabuf);
165 }
166 
167 }  // namespace wayland