Skip to content

Commit

Permalink
Integrated obs-browser PR obsproject#453 (Add hardware accel support …
Browse files Browse the repository at this point in the history
…under Linux).
  • Loading branch information
jmickelonis committed Sep 30, 2024
1 parent 7f6b5ef commit a48fd7c
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 5 deletions.
53 changes: 50 additions & 3 deletions browser-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
#include <IOSurface/IOSurface.h>
#endif

#if !defined(_WIN32) && !defined(__APPLE__)
#include <obs-nix-platform.h>

#include "drm-format.hpp"
#endif

inline bool BrowserClient::valid() const
{
return !!bs && !bs->destroying;
Expand Down Expand Up @@ -388,6 +394,42 @@ void BrowserClient::OnAcceleratedPaint(CefRefPtr<CefBrowser>,
return;
}

#if !defined(_WIN32) && !defined(__APPLE__)
if (info.plane_count == 0)
return;

struct obs_cef_video_format format =
obs_cef_format_from_cef_type(info.format);
uint64_t modifier = info.modifier;

if (format.gs_format == GS_UNKNOWN)
return;

uint32_t *strides =
(uint32_t *)alloca(info.plane_count * sizeof(uint32_t));
uint32_t *offsets =
(uint32_t *)alloca(info.plane_count * sizeof(uint32_t));
uint64_t *modifiers =
(uint64_t *)alloca(info.plane_count * sizeof(uint64_t));
int *fds = (int *)alloca(info.plane_count * sizeof(int));

/* NOTE: This a workaround under X11 where the modifier is always
invalid where it can mean "no modifier" in Chromium's code. */
if (obs_get_nix_platform() == OBS_NIX_PLATFORM_X11_EGL &&
modifier == DRM_FORMAT_MOD_INVALID)
modifier = DRM_FORMAT_MOD_LINEAR;

for (size_t i = 0; i < kAcceleratedPaintMaxPlanes; i++) {
auto *plane = &info.planes[i];

strides[i] = plane->stride;
offsets[i] = plane->offset;
fds[i] = plane->fd;

modifiers[i] = modifier;
}
#endif

#if !defined(_WIN32) && CHROME_VERSION_BUILD < 6367
if (shared_handle == bs->last_handle)
return;
Expand Down Expand Up @@ -420,18 +462,23 @@ void BrowserClient::OnAcceleratedPaint(CefRefPtr<CefBrowser>,
//if (bs->texture)
// gs_texture_acquire_sync(bs->texture, 1, INFINITE);

#else
#elif defined(__WIN32)
bs->texture =
gs_texture_open_shared((uint32_t)(uintptr_t)shared_handle);
#else
bs->texture = gs_texture_create_from_dmabuf(
bs->width, bs->height, format.drm_format, format.gs_format,
info.plane_count, fds, strides, offsets,
modifier != DRM_FORMAT_MOD_INVALID ? modifiers : NULL);
#endif
UpdateExtraTexture();
obs_leave_graphics();

#if defined(__APPLE__) && CHROME_VERSION_BUILD >= 6367
bs->last_handle = info.shared_texture_io_surface;
#elif CHROME_VERSION_BUILD >= 6367
#elif defined(_WIN32) && CHROME_VERSION_BUILD >= 6367
bs->last_handle = info.shared_texture_handle;
#else
#elif defined(__APPLE__) && defined(_WIN32)
bs->last_handle = shared_handle;
#endif
}
Expand Down
4 changes: 4 additions & 0 deletions cef-headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
#define ENABLE_WASHIDDEN 0
#endif

#if !defined(_WIN32) && !defined(__APPLE__) && CHROME_VERSION_BUILD > 6337
#define ENABLE_BROWSER_SHARED_TEXTURE 1
#endif

#define SendBrowserProcessMessage(browser, pid, msg) \
CefRefPtr<CefFrame> mainFrame = browser->GetMainFrame(); \
if (mainFrame) { \
Expand Down
5 changes: 4 additions & 1 deletion cmake/legacy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,16 @@ elseif(OS_MACOS)

elseif(OS_POSIX)
find_package(X11 REQUIRED)
find_package(Libdrm REQUIRED)

target_link_libraries(obs-browser PRIVATE CEF::Wrapper CEF::Library X11::X11)
target_link_libraries(obs-browser PRIVATE CEF::Wrapper CEF::Library X11::X11 Libdrm::Libdrm)

get_target_property(_CEF_DIRECTORY CEF::Library INTERFACE_LINK_DIRECTORIES)

set_target_properties(obs-browser PROPERTIES BUILD_RPATH "$ORIGIN/")

target_sources(obs-browser PRIVATE drm-format.cpp drm-format.hpp)

set_target_properties(obs-browser-page PROPERTIES BUILD_RPATH "$ORIGIN/")

set_target_properties(obs-browser PROPERTIES INSTALL_RPATH "$ORIGIN/")
Expand Down
5 changes: 4 additions & 1 deletion cmake/os-linux.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
find_package(X11 REQUIRED)
find_package(Libdrm REQUIRED)

target_link_libraries(obs-browser PRIVATE CEF::Wrapper CEF::Library X11::X11)
target_link_libraries(obs-browser PRIVATE CEF::Wrapper CEF::Library X11::X11 Libdrm::Libdrm)
set_target_properties(obs-browser PROPERTIES BUILD_RPATH "$ORIGIN/" INSTALL_RPATH "$ORIGIN/")

target_sources(obs-browser PRIVATE drm-format.cpp drm-format.hpp)

add_executable(browser-helper)
add_executable(OBS::browser-helper ALIAS browser-helper)

Expand Down
65 changes: 65 additions & 0 deletions drm-format.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "drm-format.hpp"

#include <util/util.hpp>

#if ENABLE_BROWSER_SHARED_TEXTURE

static const struct obs_cef_video_format supported_formats[] = {
{
CEF_COLOR_TYPE_RGBA_8888,
DRM_FORMAT_ABGR8888,
GS_RGBA_UNORM,
"RGBA_8888",
},
{
CEF_COLOR_TYPE_BGRA_8888,
DRM_FORMAT_ARGB8888,
GS_BGRA_UNORM,
"BGRA_8888",
},
};

#define N_SUPPORTED_FORMATS \
(sizeof(supported_formats) / sizeof(supported_formats[0]))

bool obs_cef_all_drm_formats_supported()
{
size_t n_supported = 0;
size_t n_formats = 0;
enum gs_dmabuf_flags dmabuf_flags;
BPtr<uint32_t> drm_formats;

if (!gs_query_dmabuf_capabilities(&dmabuf_flags, &drm_formats,
&n_formats))
return false;

for (size_t i = 0; i < n_formats; i++) {
for (size_t j = 0; j < N_SUPPORTED_FORMATS; j++) {
if (drm_formats[i] != supported_formats[j].drm_format)
continue;

blog(LOG_DEBUG,
"[obs-browser] CEF color type %s supported ",
supported_formats[j].pretty_name);
n_supported++;
}
}

return n_supported == N_SUPPORTED_FORMATS;
}

struct obs_cef_video_format
obs_cef_format_from_cef_type(cef_color_type_t cef_type)
{
for (size_t i = 0; i < N_SUPPORTED_FORMATS; i++) {
if (supported_formats[i].cef_type == cef_type)
return supported_formats[i];
}

blog(LOG_ERROR, "[obs-browser]: Unsupported CEF color format (%d)",
cef_type);

return {cef_type, DRM_FORMAT_INVALID, GS_UNKNOWN, NULL};
}

#endif
22 changes: 22 additions & 0 deletions drm-format.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <graphics/graphics.h>
#include <libdrm/drm_fourcc.h>

#include "cef-headers.hpp"

#if ENABLE_BROWSER_SHARED_TEXTURE

struct obs_cef_video_format {
cef_color_type_t cef_type;
uint32_t drm_format;
enum gs_color_format gs_format;
const char *pretty_name;
};

bool obs_cef_all_drm_formats_supported();

struct obs_cef_video_format
obs_cef_format_from_cef_type(cef_color_type_t cef_type);

#endif
9 changes: 9 additions & 0 deletions obs-browser-plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
#include <QThread>
#endif

#if !defined(_WIN32) && !defined(__APPLE__) && CHROME_VERSION_BUILD > 6337
#include "drm-format.hpp"
#endif

OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("obs-browser", "en-US")
MODULE_EXPORT const char *obs_module_description(void)
Expand Down Expand Up @@ -383,7 +387,12 @@ static void BrowserInit(void)
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
if (hwaccel) {
obs_enter_graphics();
#if defined(__APPLE__) || defined(_WIN32)
hwaccel = tex_sharing_avail = gs_shared_texture_available();
#else
hwaccel = tex_sharing_avail =
obs_cef_all_drm_formats_supported();
#endif
obs_leave_graphics();
}
#endif
Expand Down
8 changes: 8 additions & 0 deletions obs-browser-source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
#include <QThread>
#endif

#if !defined(_WIN32) && !defined(__APPLE__)
#include "drm-format.hpp"
#endif

using namespace std;

extern bool QueueCEFTask(std::function<void()> task);
Expand Down Expand Up @@ -188,7 +192,11 @@ bool BrowserSource::CreateBrowser()
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
if (hwaccel) {
obs_enter_graphics();
#if defined(__APPLE__) || defined(_WIN32)
tex_sharing_avail = gs_shared_texture_available();
#else
tex_sharing_avail = obs_cef_all_drm_formats_supported();
#endif
obs_leave_graphics();
}
#else
Expand Down

0 comments on commit a48fd7c

Please sign in to comment.