1 /* 2 * Copyright (C) 2018 Igalia S.L. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 16 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 17 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #pragma once 27 28 #include "ipc.h" 29 #include "ws.h" 30 31 #include <gio/gio.h> 32 #include <wpe/wpe.h> 33 #include <vector> 34 35 class ViewBackend; 36 37 class ClientBundle { 38 public: ClientBundle(void * _data,ViewBackend * _viewBackend,uint32_t _initialWidth,uint32_t _initialHeight)39 ClientBundle(void* _data, ViewBackend* _viewBackend, uint32_t _initialWidth, uint32_t _initialHeight) 40 : data(_data) 41 , viewBackend(_viewBackend) 42 , initialWidth(_initialWidth) 43 , initialHeight(_initialHeight) 44 { 45 } 46 47 virtual ~ClientBundle() = default; 48 49 virtual void exportBuffer(struct wl_resource *bufferResource) = 0; 50 virtual void exportBuffer(const struct linux_dmabuf_buffer *dmabuf_buffer) = 0; 51 virtual void exportBuffer(struct wl_resource* bufferResource, struct wl_shm_buffer* shmBuffer) = 0; 52 virtual void exportEGLStreamProducer(struct wl_resource *bufferResource) = 0; 53 54 virtual struct wpe_dmabuf_pool_entry* createDmabufPoolEntry() = 0; 55 virtual void commitDmabufPoolEntry(struct wpe_dmabuf_pool_entry*) = 0; 56 57 void* data; 58 ViewBackend* viewBackend; 59 uint32_t initialWidth; 60 uint32_t initialHeight; 61 }; 62 63 class ViewBackend final : public WS::APIClient, public FdoIPC::MessageReceiver { 64 public: 65 ViewBackend(ClientBundle* clientBundle, struct wpe_view_backend* backend); 66 ~ViewBackend(); 67 68 void initialize(); 69 int clientFd(); 70 void exportBufferResource(struct wl_resource* bufferResource) override; 71 void exportLinuxDmabuf(const struct linux_dmabuf_buffer *dmabuf_buffer) override; 72 void exportShmBuffer(struct wl_resource* bufferResource, struct wl_shm_buffer* shmBuffer) override; 73 void exportEGLStreamProducer(struct wl_resource*) override; 74 75 struct wpe_dmabuf_pool_entry* createDmabufPoolEntry() override; 76 void commitDmabufPoolEntry(struct wpe_dmabuf_pool_entry*) override; 77 bridgeConnectionLost(uint32_t id)78 void bridgeConnectionLost(uint32_t id) override 79 { 80 unregisterSurface(id); 81 } 82 83 void dispatchFrameCallbacks(); 84 void releaseBuffer(struct wl_resource* buffer_resource); 85 86 private: 87 void didReceiveMessage(uint32_t messageId, uint32_t messageBody) override; 88 89 void registerSurface(uint32_t); 90 void unregisterSurface(uint32_t); 91 92 static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer); 93 94 std::vector<uint32_t> m_bridgeIds; 95 96 ClientBundle* m_clientBundle; 97 struct wpe_view_backend* m_backend; 98 99 std::unique_ptr<FdoIPC::Connection> m_socket; 100 int m_clientFd { -1 }; 101 }; 102 103 struct wpe_view_backend_private { wpe_view_backend_privatewpe_view_backend_private104 wpe_view_backend_private(std::unique_ptr<ClientBundle>&& clientBundle, struct wpe_view_backend* backend) 105 : clientBundle(std::move(clientBundle)) 106 , backend(backend) 107 { 108 } 109 ~wpe_view_backend_privatewpe_view_backend_private110 ~wpe_view_backend_private() 111 { 112 wpe_view_backend_destroy(backend); 113 } 114 115 std::unique_ptr<ClientBundle> clientBundle; 116 struct wpe_view_backend* backend { nullptr }; 117 }; 118 119 struct wpe_view_backend_exportable_fdo : wpe_view_backend_private { wpe_view_backend_exportable_fdowpe_view_backend_exportable_fdo120 wpe_view_backend_exportable_fdo(std::unique_ptr<ClientBundle>&& clientBundle, struct wpe_view_backend* backend) 121 : wpe_view_backend_private(std::move(clientBundle), backend) 122 { 123 } 124 }; 125 126 struct wpe_view_backend_dmabuf_pool_fdo : wpe_view_backend_private { wpe_view_backend_dmabuf_pool_fdowpe_view_backend_dmabuf_pool_fdo127 wpe_view_backend_dmabuf_pool_fdo(std::unique_ptr<ClientBundle>&& clientBundle, struct wpe_view_backend* backend) 128 : wpe_view_backend_private(std::move(clientBundle), backend) 129 { 130 } 131 }; 132 133 static struct wpe_view_backend_interface view_backend_private_interface = { 134 // create 135 [](void* data, struct wpe_view_backend* backend) -> void* 136 { 137 auto* clientBundle = reinterpret_cast<ClientBundle*>(data); 138 return new ViewBackend(clientBundle, backend); 139 }, 140 // destroy 141 [](void* data) 142 { 143 auto* backend = reinterpret_cast<ViewBackend*>(data); 144 delete backend; 145 }, 146 // initialize 147 [](void* data) 148 { 149 auto& backend = *reinterpret_cast<ViewBackend*>(data); 150 backend.initialize(); 151 }, 152 // get_renderer_host_fd 153 [](void* data) -> int 154 { 155 auto& backend = *reinterpret_cast<ViewBackend*>(data); 156 return backend.clientFd(); 157 } 158 }; 159