Bug 1696071 - Add support for DMABuf to the blocklist. r=rmader

Differential Revision: https://phabricator.services.mozilla.com/D107019
This commit is contained in:
Andrew Osmond 2021-03-16 20:14:51 +00:00
Родитель 8ebccdd08d
Коммит 86da16f9a5
9 изменённых файлов: 90 добавлений и 17 удалений

Просмотреть файл

@ -36,6 +36,7 @@ namespace gfx {
_(OMTP, Feature, "Off Main Thread Painting") \ _(OMTP, Feature, "Off Main Thread Painting") \
_(WEBGPU, Feature, "WebGPU") \ _(WEBGPU, Feature, "WebGPU") \
_(X11_EGL, Feature, "X11 EGL") \ _(X11_EGL, Feature, "X11 EGL") \
_(DMABUF, Feature, "DMABUF") \
/* Add new entries above this comment */ /* Add new entries above this comment */
enum class Feature : uint32_t { enum class Feature : uint32_t {

Просмотреть файл

@ -75,7 +75,8 @@ class gfxVarReceiver;
_(UseAHardwareBufferContent, bool, false) \ _(UseAHardwareBufferContent, bool, false) \
_(UseAHardwareBufferSharedSurface, bool, false) \ _(UseAHardwareBufferSharedSurface, bool, false) \
_(UseEGL, bool, false) \ _(UseEGL, bool, false) \
_(DrmRenderDevice, nsCString, nsCString()) _(DrmRenderDevice, nsCString, nsCString()) \
_(UseDMABuf, bool, false)
/* Add new entries above this line. */ /* Add new entries above this line. */

Просмотреть файл

@ -60,7 +60,7 @@
# include <gdk/gdkwayland.h> # include <gdk/gdkwayland.h>
# include "mozilla/widget/nsWaylandDisplay.h" # include "mozilla/widget/nsWaylandDisplay.h"
# include "mozilla/widget/DMABufLibWrapper.h" # include "mozilla/widget/DMABufLibWrapper.h"
# include "mozilla/StaticPrefs_media.h" # include "mozilla/StaticPrefs_widget.h"
#endif #endif
#define GDK_PIXMAP_SIZE_MAX 32767 #define GDK_PIXMAP_SIZE_MAX 32767
@ -106,14 +106,13 @@ gfxPlatformGtk::gfxPlatformGtk() {
#endif #endif
InitX11EGLConfig(); InitX11EGLConfig();
if (IsWaylandDisplay() || gfxConfig::IsEnabled(Feature::X11_EGL)) { if (IsWaylandDisplay() || gfxConfig::IsEnabled(Feature::X11_EGL)) {
gfxVars::SetUseEGL(true); gfxVars::SetUseEGL(true);
}
nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service(); InitDmabufConfig();
nsAutoCString drmRenderDevice; if (gfxConfig::IsEnabled(Feature::DMABUF)) {
gfxInfo->GetDrmRenderDevice(drmRenderDevice); gfxVars::SetUseDMABuf(true);
gfxVars::SetDrmRenderDevice(drmRenderDevice);
} }
} }
@ -121,7 +120,7 @@ gfxPlatformGtk::gfxPlatformGtk() {
#ifdef MOZ_WAYLAND #ifdef MOZ_WAYLAND
mUseWebGLDmabufBackend = mUseWebGLDmabufBackend =
gfxVars::UseEGL() && GetDMABufDevice()->IsDMABufWebGLEnabled(); gfxVars::UseDMABuf() && GetDMABufDevice()->IsDMABufWebGLEnabled();
#endif #endif
gPlatformFTLibrary = Factory::NewFTLibrary(); gPlatformFTLibrary = Factory::NewFTLibrary();
@ -180,6 +179,49 @@ void gfxPlatformGtk::InitX11EGLConfig() {
#endif #endif
} }
void gfxPlatformGtk::InitDmabufConfig() {
FeatureState& feature = gfxConfig::GetFeature(Feature::DMABUF);
#ifdef MOZ_WAYLAND
feature.EnableByDefault();
if (StaticPrefs::widget_dmabuf_force_enabled_AtStartup()) {
feature.UserForceEnable("Force enabled by pref");
}
nsCString failureId;
int32_t status;
nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
if (NS_FAILED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DMABUF, failureId,
&status))) {
feature.Disable(FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
"FEATURE_FAILURE_NO_GFX_INFO"_ns);
} else if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
feature.Disable(FeatureStatus::Blocklisted, "Blocklisted by gfxInfo",
failureId);
}
if (!gfxVars::UseEGL()) {
feature.ForceDisable(FeatureStatus::Unavailable, "Requires EGL",
"FEATURE_FAILURE_REQUIRES_EGL"_ns);
}
if (feature.IsEnabled()) {
nsAutoCString drmRenderDevice;
gfxInfo->GetDrmRenderDevice(drmRenderDevice);
gfxVars::SetDrmRenderDevice(drmRenderDevice);
if (!GetDMABufDevice()->Configure(failureId)) {
feature.ForceDisable(FeatureStatus::Failed, "Failed to configure",
failureId);
}
}
#else
feature.DisableByDefault(FeatureStatus::Unavailable,
"Wayland support missing",
"FEATURE_FAILURE_NO_WAYLAND"_ns);
#endif
}
void gfxPlatformGtk::FlushContentDrawing() { void gfxPlatformGtk::FlushContentDrawing() {
if (gfxVars::UseXRender()) { if (gfxVars::UseXRender()) {
XFlush(DefaultXDisplay()); XFlush(DefaultXDisplay());

Просмотреть файл

@ -93,6 +93,7 @@ class gfxPlatformGtk final : public gfxPlatform {
protected: protected:
void InitX11EGLConfig(); void InitX11EGLConfig();
void InitDmabufConfig();
void InitPlatformGPUProcessPrefs() override; void InitPlatformGPUProcessPrefs() override;
bool CheckVariationFontSupport() override; bool CheckVariationFontSupport() override;

Просмотреть файл

@ -10823,6 +10823,12 @@
mirror: always mirror: always
#ifdef MOZ_WAYLAND #ifdef MOZ_WAYLAND
# Whether to override the DMABuf blocklist.
- name: widget.dmabuf.force-enabled
type: bool
value: false
mirror: once
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
# Keep those pref hidden on non-nightly builds to avoid people accidentally # Keep those pref hidden on non-nightly builds to avoid people accidentally
# turning it on. # turning it on.

Просмотреть файл

@ -234,6 +234,9 @@ static const char* GetPrefNameForFeature(int32_t aFeature) {
case nsIGfxInfo::FEATURE_X11_EGL: case nsIGfxInfo::FEATURE_X11_EGL:
name = BLOCKLIST_PREF_BRANCH "x11.egl"; name = BLOCKLIST_PREF_BRANCH "x11.egl";
break; break;
case nsIGfxInfo::FEATURE_DMABUF:
name = BLOCKLIST_PREF_BRANCH "dmabuf";
break;
default: default:
MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!"); MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
break; break;
@ -432,6 +435,8 @@ static int32_t BlocklistFeatureToGfxFeature(const nsAString& aFeature) {
return nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE; return nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE;
else if (aFeature.EqualsLiteral("X11_EGL")) else if (aFeature.EqualsLiteral("X11_EGL"))
return nsIGfxInfo::FEATURE_X11_EGL; return nsIGfxInfo::FEATURE_X11_EGL;
else if (aFeature.EqualsLiteral("DMABUF"))
return nsIGfxInfo::FEATURE_DMABUF;
// If we don't recognize the feature, it may be new, and something // If we don't recognize the feature, it may be new, and something
// this version doesn't understand. So, nothing to do. This is // this version doesn't understand. So, nothing to do. This is
@ -1294,6 +1299,7 @@ void GfxInfoBase::EvaluateDownloadedBlocklist(
nsIGfxInfo::FEATURE_GL_SWIZZLE, nsIGfxInfo::FEATURE_GL_SWIZZLE,
nsIGfxInfo::FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS, nsIGfxInfo::FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS,
nsIGfxInfo::FEATURE_X11_EGL, nsIGfxInfo::FEATURE_X11_EGL,
nsIGfxInfo::FEATURE_DMABUF,
0}; 0};
// For every feature we know about, we evaluate whether this blocklist has a // For every feature we know about, we evaluate whether this blocklist has a

Просмотреть файл

@ -168,7 +168,8 @@ nsDMABufDevice::nsDMABufDevice()
: mXRGBFormat({true, false, GBM_FORMAT_XRGB8888, nullptr, 0}), : mXRGBFormat({true, false, GBM_FORMAT_XRGB8888, nullptr, 0}),
mARGBFormat({true, true, GBM_FORMAT_ARGB8888, nullptr, 0}), mARGBFormat({true, true, GBM_FORMAT_ARGB8888, nullptr, 0}),
mGbmDevice(nullptr), mGbmDevice(nullptr),
mGbmFd(-1) { mGbmFd(-1),
mInitialized(false) {
if (GdkIsWaylandDisplay()) { if (GdkIsWaylandDisplay()) {
wl_display* display = WaylandDisplayGetWLDisplay(); wl_display* display = WaylandDisplayGetWLDisplay();
mRegistry = (void*)wl_display_get_registry(display); mRegistry = (void*)wl_display_get_registry(display);
@ -185,9 +186,12 @@ nsDMABufDevice::~nsDMABufDevice() {
} }
} }
bool nsDMABufDevice::Configure() { bool nsDMABufDevice::Configure(nsACString& aFailureId) {
LOGDMABUF(("nsDMABufDevice::Configure()")); LOGDMABUF(("nsDMABufDevice::Configure()"));
MOZ_ASSERT(!mInitialized);
mInitialized = true;
bool isDMABufUsed = ( bool isDMABufUsed = (
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
StaticPrefs::widget_dmabuf_textures_enabled() || StaticPrefs::widget_dmabuf_textures_enabled() ||
@ -199,11 +203,13 @@ bool nsDMABufDevice::Configure() {
if (!isDMABufUsed) { if (!isDMABufUsed) {
// Disabled by user, just quit. // Disabled by user, just quit.
LOGDMABUF(("IsDMABufEnabled(): Disabled by preferences.")); LOGDMABUF(("IsDMABufEnabled(): Disabled by preferences."));
aFailureId = "FEATURE_FAILURE_NO_PREFS_ENABLED";
return false; return false;
} }
if (!nsGbmLib::IsAvailable()) { if (!nsGbmLib::IsAvailable()) {
LOGDMABUF(("nsGbmLib is not available!")); LOGDMABUF(("nsGbmLib is not available!"));
aFailureId = "FEATURE_FAILURE_NO_LIBGBM";
return false; return false;
} }
@ -212,6 +218,7 @@ bool nsDMABufDevice::Configure() {
drm_render_node.Assign(gfx::gfxVars::DrmRenderDevice()); drm_render_node.Assign(gfx::gfxVars::DrmRenderDevice());
if (drm_render_node.IsEmpty()) { if (drm_render_node.IsEmpty()) {
LOGDMABUF(("Failed: We're missing DRM render device!\n")); LOGDMABUF(("Failed: We're missing DRM render device!\n"));
aFailureId = "FEATURE_FAILURE_NO_DRM_RENDER_NODE";
return false; return false;
} }
} }
@ -219,6 +226,7 @@ bool nsDMABufDevice::Configure() {
mGbmFd = open(drm_render_node.get(), O_RDWR); mGbmFd = open(drm_render_node.get(), O_RDWR);
if (mGbmFd < 0) { if (mGbmFd < 0) {
LOGDMABUF(("Failed to open drm render node %s\n", drm_render_node.get())); LOGDMABUF(("Failed to open drm render node %s\n", drm_render_node.get()));
aFailureId = "FEATURE_FAILURE_BAD_DRM_RENDER_NODE";
return false; return false;
} }
@ -226,6 +234,7 @@ bool nsDMABufDevice::Configure() {
if (!mGbmDevice) { if (!mGbmDevice) {
LOGDMABUF( LOGDMABUF(
("Failed to create drm render device %s\n", drm_render_node.get())); ("Failed to create drm render device %s\n", drm_render_node.get()));
aFailureId = "FEATURE_FAILURE_NO_DRM_RENDER_DEVICE";
close(mGbmFd); close(mGbmFd);
mGbmFd = -1; mGbmFd = -1;
return false; return false;
@ -236,13 +245,17 @@ bool nsDMABufDevice::Configure() {
} }
bool nsDMABufDevice::IsDMABufEnabled() { bool nsDMABufDevice::IsDMABufEnabled() {
static bool isDMABufEnabled = Configure(); if (!mInitialized) {
return isDMABufEnabled; MOZ_ASSERT(!XRE_IsParentProcess());
nsCString failureId;
return Configure(failureId);
}
return !!mGbmDevice;
} }
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
bool nsDMABufDevice::IsDMABufTexturesEnabled() { bool nsDMABufDevice::IsDMABufTexturesEnabled() {
return gfx::gfxVars::UseEGL() && IsDMABufEnabled() && return gfx::gfxVars::UseDMABuf() && IsDMABufEnabled() &&
StaticPrefs::widget_dmabuf_textures_enabled(); StaticPrefs::widget_dmabuf_textures_enabled();
} }
#else #else
@ -257,7 +270,7 @@ bool nsDMABufDevice::IsDMABufVAAPIEnabled() {
StaticPrefs::media_ffmpeg_vaapi_enabled(), StaticPrefs::media_ffmpeg_vaapi_enabled(),
gfx::gfxVars::CanUseHardwareVideoDecoding(), !XRE_IsRDDProcess())); gfx::gfxVars::CanUseHardwareVideoDecoding(), !XRE_IsRDDProcess()));
return StaticPrefs::media_ffmpeg_vaapi_enabled() && !XRE_IsRDDProcess() && return StaticPrefs::media_ffmpeg_vaapi_enabled() && !XRE_IsRDDProcess() &&
gfx::gfxVars::UseEGL() && IsDMABufEnabled() && gfx::gfxVars::UseDMABuf() && IsDMABufEnabled() &&
gfx::gfxVars::CanUseHardwareVideoDecoding(); gfx::gfxVars::CanUseHardwareVideoDecoding();
} }
bool nsDMABufDevice::IsDMABufWebGLEnabled() { bool nsDMABufDevice::IsDMABufWebGLEnabled() {
@ -266,7 +279,7 @@ bool nsDMABufDevice::IsDMABufWebGLEnabled() {
"widget_dmabuf_webgl_enabled %d\n", "widget_dmabuf_webgl_enabled %d\n",
gfx::gfxVars::UseEGL(), IsDMABufEnabled(), gfx::gfxVars::UseEGL(), IsDMABufEnabled(),
StaticPrefs::widget_dmabuf_webgl_enabled())); StaticPrefs::widget_dmabuf_webgl_enabled()));
return gfx::gfxVars::UseEGL() && IsDMABufEnabled() && return gfx::gfxVars::UseDMABuf() && IsDMABufEnabled() &&
StaticPrefs::widget_dmabuf_webgl_enabled(); StaticPrefs::widget_dmabuf_webgl_enabled();
} }

Просмотреть файл

@ -150,10 +150,10 @@ class nsDMABufDevice {
void ResetFormatsModifiers(); void ResetFormatsModifiers();
void AddFormatModifier(bool aHasAlpha, int aFormat, uint32_t mModifierHi, void AddFormatModifier(bool aHasAlpha, int aFormat, uint32_t mModifierHi,
uint32_t mModifierLo); uint32_t mModifierLo);
bool Configure(nsACString& aFailureId);
private: private:
bool IsDMABufEnabled(); bool IsDMABufEnabled();
bool Configure();
void* mRegistry; void* mRegistry;
@ -162,6 +162,7 @@ class nsDMABufDevice {
gbm_device* mGbmDevice; gbm_device* mGbmDevice;
int mGbmFd; int mGbmFd;
bool mInitialized;
}; };
nsDMABufDevice* GetDMABufDevice(); nsDMABufDevice* GetDMABufDevice();

Просмотреть файл

@ -175,8 +175,10 @@ interface nsIGfxInfo : nsISupports
const long FEATURE_WEBRENDER_OPTIMIZED_SHADERS = 33; const long FEATURE_WEBRENDER_OPTIMIZED_SHADERS = 33;
/* Whether we prefer EGL over GLX with X11, starting in 88. */ /* Whether we prefer EGL over GLX with X11, starting in 88. */
const long FEATURE_X11_EGL = 34; const long FEATURE_X11_EGL = 34;
/* Whether DMABUF is supported, starting in 88. */
const long FEATURE_DMABUF = 35;
/* the maximum feature value. */ /* the maximum feature value. */
const long FEATURE_MAX_VALUE = FEATURE_X11_EGL; const long FEATURE_MAX_VALUE = FEATURE_DMABUF;
/* /*
* A set of return values from GetFeatureStatus * A set of return values from GetFeatureStatus