Skip to content

Commit 32e744a

Browse files
committed
Add hardware accel support under Linux
1 parent 16ff0fa commit 32e744a

File tree

7 files changed

+142
-3
lines changed

7 files changed

+142
-3
lines changed

browser-client.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <IOSurface/IOSurface.h>
3131
#endif
3232

33+
#if !defined(_WIN32) && !defined(__APPLE__)
34+
#include "drm-format.hpp"
35+
#endif
36+
3337
inline bool BrowserClient::valid() const
3438
{
3539
return !!bs && !bs->destroying;
@@ -360,6 +364,31 @@ void BrowserClient::OnAcceleratedPaint(CefRefPtr<CefBrowser>, PaintElementType t
360364
return;
361365
}
362366

367+
#if !defined(_WIN32) && !defined(__APPLE__)
368+
if (info.plane_count == 0)
369+
return;
370+
371+
struct obs_cef_video_format format = obs_cef_format_from_cef_type(info.format);
372+
373+
if (format.gs_format == GS_UNKNOWN)
374+
return;
375+
376+
uint32_t *strides = (uint32_t *)alloca(info.plane_count * sizeof(uint32_t));
377+
uint32_t *offsets = (uint32_t *)alloca(info.plane_count * sizeof(uint32_t));
378+
uint64_t *modifiers = (uint64_t *)alloca(info.plane_count * sizeof(uint64_t));
379+
int *fds = (int *)alloca(info.plane_count * sizeof(int));
380+
381+
for (size_t i = 0; i < kAcceleratedPaintMaxPlanes; i++) {
382+
auto *plane = &info.planes[i];
383+
384+
strides[i] = plane->stride;
385+
offsets[i] = plane->offset;
386+
fds[i] = plane->fd;
387+
388+
modifiers[i] = info.modifier;
389+
}
390+
#endif
391+
363392
#if !defined(_WIN32) && CHROME_VERSION_BUILD < 6367
364393
if (shared_handle == bs->last_handle)
365394
return;
@@ -389,17 +418,21 @@ void BrowserClient::OnAcceleratedPaint(CefRefPtr<CefBrowser>, PaintElementType t
389418
//if (bs->texture)
390419
// gs_texture_acquire_sync(bs->texture, 1, INFINITE);
391420

392-
#else
421+
#elif defined(_WIN32)
393422
bs->texture = gs_texture_open_shared((uint32_t)(uintptr_t)shared_handle);
423+
#else
424+
bs->texture = gs_texture_create_from_dmabuf(bs->width, bs->height, format.drm_format, format.gs_format,
425+
info.plane_count, fds, strides, offsets,
426+
info.modifier != DRM_FORMAT_MOD_INVALID ? modifiers : NULL);
394427
#endif
395428
UpdateExtraTexture();
396429
obs_leave_graphics();
397430

398431
#if defined(__APPLE__) && CHROME_VERSION_BUILD >= 6367
399432
bs->last_handle = info.shared_texture_io_surface;
400-
#elif CHROME_VERSION_BUILD >= 6367
433+
#elif defined(_WIN32) && CHROME_VERSION_BUILD >= 6367
401434
bs->last_handle = info.shared_texture_handle;
402-
#else
435+
#elif defined(__APPLE__) || defined(_WIN32)
403436
bs->last_handle = shared_handle;
404437
#endif
405438
}

cef-headers.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
#define ENABLE_WASHIDDEN 0
4848
#endif
4949

50+
#if !defined(_WIN32) && !defined(__APPLE__) && CHROME_VERSION_BUILD > 6337
51+
#define ENABLE_BROWSER_SHARED_TEXTURE
52+
#endif
53+
5054
#define SendBrowserProcessMessage(browser, pid, msg) \
5155
CefRefPtr<CefFrame> mainFrame = browser->GetMainFrame(); \
5256
if (mainFrame) { \

cmake/os-linux.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
find_package(X11 REQUIRED)
2+
find_package(Libdrm REQUIRED)
3+
get_target_property(libdrm_include_directories Libdrm::Libdrm INTERFACE_INCLUDE_DIRECTORIES)
4+
5+
target_include_directories(obs-browser PRIVATE ${libdrm_include_directories})
26

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

10+
target_sources(obs-browser PRIVATE drm-format.cpp drm-format.hpp)
11+
612
add_executable(browser-helper)
713
add_executable(OBS::browser-helper ALIAS browser-helper)
814

drm-format.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "drm-format.hpp"
2+
3+
#include <util/util.hpp>
4+
5+
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
6+
7+
static const struct obs_cef_video_format supported_formats[] = {
8+
{
9+
CEF_COLOR_TYPE_RGBA_8888,
10+
DRM_FORMAT_ABGR8888,
11+
GS_RGBA_UNORM,
12+
"RGBA_8888",
13+
},
14+
{
15+
CEF_COLOR_TYPE_BGRA_8888,
16+
DRM_FORMAT_ARGB8888,
17+
GS_BGRA_UNORM,
18+
"BGRA_8888",
19+
},
20+
};
21+
22+
constexpr size_t N_SUPPORTED_FORMATS = sizeof(supported_formats) / sizeof(supported_formats[0]);
23+
24+
bool obs_cef_all_drm_formats_supported(void)
25+
{
26+
size_t n_supported = 0;
27+
size_t n_formats = 0;
28+
enum gs_dmabuf_flags dmabuf_flags;
29+
BPtr<uint32_t> drm_formats;
30+
31+
if (!gs_query_dmabuf_capabilities(&dmabuf_flags, &drm_formats, &n_formats))
32+
return false;
33+
34+
for (size_t i = 0; i < n_formats; i++) {
35+
for (size_t j = 0; j < N_SUPPORTED_FORMATS; j++) {
36+
if (drm_formats[i] != supported_formats[j].drm_format)
37+
continue;
38+
39+
blog(LOG_DEBUG, "[obs-browser]: CEF color type %s supported", supported_formats[j].pretty_name);
40+
n_supported++;
41+
}
42+
}
43+
44+
return n_supported == N_SUPPORTED_FORMATS;
45+
}
46+
47+
struct obs_cef_video_format obs_cef_format_from_cef_type(cef_color_type_t cef_type)
48+
{
49+
for (size_t i = 0; i < N_SUPPORTED_FORMATS; i++) {
50+
if (supported_formats[i].cef_type == cef_type)
51+
return supported_formats[i];
52+
}
53+
54+
blog(LOG_ERROR, "[obs-browser]: Unsupported CEF color format (%d)", cef_type);
55+
56+
return {cef_type, DRM_FORMAT_INVALID, GS_UNKNOWN, NULL};
57+
}
58+
59+
#endif

drm-format.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <graphics/graphics.h>
4+
#include <libdrm/drm_fourcc.h>
5+
6+
#include "cef-headers.hpp"
7+
8+
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
9+
10+
struct obs_cef_video_format {
11+
cef_color_type_t cef_type;
12+
uint32_t drm_format;
13+
enum gs_color_format gs_format;
14+
const char *pretty_name;
15+
};
16+
17+
bool obs_cef_all_drm_formats_supported(void);
18+
19+
struct obs_cef_video_format obs_cef_format_from_cef_type(cef_color_type_t cef_type);
20+
21+
#endif

obs-browser-plugin.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
#include <QThread>
5656
#endif
5757

58+
#if !defined(_WIN32) && !defined(__APPLE__)
59+
#include "drm-format.hpp"
60+
#endif
61+
5862
OBS_DECLARE_MODULE()
5963
OBS_MODULE_USE_DEFAULT_LOCALE("obs-browser", "en-US")
6064
MODULE_EXPORT const char *obs_module_description(void)
@@ -350,7 +354,11 @@ static void BrowserInit(void)
350354
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
351355
if (hwaccel) {
352356
obs_enter_graphics();
357+
#if defined(__APPLE__) || defined(_WIN32)
353358
hwaccel = tex_sharing_avail = gs_shared_texture_available();
359+
#else
360+
hwaccel = tex_sharing_avail = obs_cef_all_drm_formats_supported();
361+
#endif
354362
obs_leave_graphics();
355363
}
356364
#endif

obs-browser-source.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
#include <QThread>
3838
#endif
3939

40+
#if !defined(_WIN32) && !defined(__APPLE__)
41+
#include "drm-format.hpp"
42+
#endif
43+
4044
using namespace std;
4145

4246
extern bool QueueCEFTask(std::function<void()> task);
@@ -181,7 +185,11 @@ bool BrowserSource::CreateBrowser()
181185
#ifdef ENABLE_BROWSER_SHARED_TEXTURE
182186
if (hwaccel) {
183187
obs_enter_graphics();
188+
#if defined(__APPLE__) || defined(_WIN32)
184189
tex_sharing_avail = gs_shared_texture_available();
190+
#else
191+
tex_sharing_avail = obs_cef_all_drm_formats_supported();
192+
#endif
185193
obs_leave_graphics();
186194
}
187195
#else

0 commit comments

Comments
 (0)