Skip to content

Commit

Permalink
Bug 1829063 - Split video overlay feature of software decoded video f…
Browse files Browse the repository at this point in the history
…rom nsIGfxInfo::FEATURE_VIDEO_OVERLAY r=gfx-reviewers,lsalzman

Current gecko enables "software decoded video overlay" only when "hardware decoded video overlay" is enabled. On current release, "hardware decoded video overlay" is not enabled yet with non-Intel GPU, then "software decoded video overlay" is not yet enabled on release. It is not good. We want to enable "software decoded video overlay" independently from "hardware decoded video overlay". Then settings of video overlay is split between "hardware decoded video overlay" and "software decoded video overlay". Then "software decoded video overlay" could be enabled/disabled independently from status of "hardware decoded video overlay".

* settings of hardware decoded video overlay
- nsIGfxInfo::FEATURE_VIDEO_OVERLAY:
- gfx.webrender.dcomp-video-hw-overlay-win
- gfx.webrender.dcomp-video-hw-overlay-win-force-enabled
- gfxVars::UseWebRenderDCompVideoHwOverlayWin()

* settings of software decoded video overlay
- nsIGfxInfo::FEATURE_VIDEO_SOFTWARE_OVERLAY
- gfx.webrender.dcomp-video-sw-overlay-win
- gfx.webrender.dcomp-video-sw-overlay-win-force-enabled
- gfxVars::UseWebRenderDCompVideoSwOverlayWin()

Differential Revision: https://phabricator.services.mozilla.com/D175993
  • Loading branch information
sotaro committed Jun 22, 2023
1 parent 5f95fef commit 3ece048
Show file tree
Hide file tree
Showing 17 changed files with 160 additions and 45 deletions.
2 changes: 1 addition & 1 deletion dom/media/MediaData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ bool VideoData::UseUseNV12ForSoftwareDecodedVideoIfPossible(

if (StaticPrefs::gfx_video_convert_i420_to_nv12_force_enabled_AtStartup() ||
(gfx::DeviceManagerDx::Get()->CanUseNV12() &&
gfx::gfxVars::UseWebRenderDCompSwVideoOverlayWin() &&
gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin() &&
aAllocator->GetCompositorUseDComp())) {
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion gfx/config/gfxFeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ namespace gfx {
_(DMABUF, Feature, "DMABUF") \
_(WINDOW_OCCLUSION, Feature, "WINDOW_OCCLUSION") \
_(HARDWARE_VIDEO_DECODING, Feature, "Hardware video decoding") \
_(VIDEO_OVERLAY, Feature, "video overlay") \
_(VIDEO_HARDWARE_OVERLAY, Feature, "hardware decoded video overlay") \
_(VIDEO_SOFTWARE_OVERLAY, Feature, "software decoded video overlay") \
_(HW_DECODED_VIDEO_ZERO_COPY, Feature, "Hardware decoded video zero copy") \
_(VP8_HW_DECODE, Feature, "VP8 hardware decoding") \
_(VP9_HW_DECODE, Feature, "VP9 hardware decoding") \
Expand Down
4 changes: 2 additions & 2 deletions gfx/config/gfxVars.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class gfxVarReceiver;
_(UseWebRenderANGLE, bool, false) \
_(UseWebRenderFlipSequentialWin, bool, false) \
_(UseWebRenderDCompWin, bool, false) \
_(UseWebRenderDCompVideoOverlayWin, bool, false) \
_(UseWebRenderDCompVideoHwOverlayWin, bool, false) \
_(UseWebRenderDCompVideoSwOverlayWin, bool, false) \
_(UseWebRenderTripleBufferingWin, bool, false) \
_(UseWebRenderCompositor, bool, false) \
_(UseWebRenderProgramBinaryDisk, bool, false) \
Expand Down Expand Up @@ -98,7 +99,6 @@ class gfxVarReceiver;
_(AllowBackdropFilter, bool, true) \
_(WebglOopAsyncPresentForceSync, bool, true) \
_(UseAcceleratedCanvas2D, bool, false) \
_(UseWebRenderDCompSwVideoOverlayWin, bool, false) \
_(AllowSoftwareWebRenderOGL, bool, false)

/* Add new entries above this line. */
Expand Down
24 changes: 20 additions & 4 deletions gfx/ipc/GPUProcessManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,8 @@ bool GPUProcessManager::DisableWebRenderConfig(wr::WebRenderError aError,

// Disable WebRender
bool wantRestart = FallbackFromAcceleration(aError, aMsg);
gfx::gfxVars::SetUseWebRenderDCompVideoOverlayWin(false);
gfxVars::SetUseWebRenderDCompVideoHwOverlayWin(false);
gfxVars::SetUseWebRenderDCompVideoSwOverlayWin(false);

// If we still have the GPU process, and we fallback to a new configuration
// that prefers to have the GPU process, reset the counter. Because we
Expand Down Expand Up @@ -682,14 +683,29 @@ void GPUProcessManager::DisableWebRender(wr::WebRenderError aError,

void GPUProcessManager::NotifyWebRenderError(wr::WebRenderError aError) {
gfxCriticalNote << "Handling webrender error " << (unsigned int)aError;
if (aError == wr::WebRenderError::VIDEO_OVERLAY) {
#ifdef XP_WIN
gfxVars::SetUseWebRenderDCompVideoOverlayWin(false);
if (aError == wr::WebRenderError::VIDEO_OVERLAY) {
gfxVars::SetUseWebRenderDCompVideoHwOverlayWin(false);
gfxVars::SetUseWebRenderDCompVideoSwOverlayWin(false);
return;
}
if (aError == wr::WebRenderError::VIDEO_HW_OVERLAY) {
gfxVars::SetUseWebRenderDCompVideoHwOverlayWin(false);
return;
}
if (aError == wr::WebRenderError::VIDEO_SW_OVERLAY) {
gfxVars::SetUseWebRenderDCompVideoSwOverlayWin(false);
return;
}
#else
if (aError == wr::WebRenderError::VIDEO_OVERLAY ||
aError == wr::WebRenderError::VIDEO_HW_OVERLAY ||
aError == wr::WebRenderError::VIDEO_SW_OVERLAY) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
#endif
return;
}
#endif

DisableWebRender(aError, nsCString());
}

Expand Down
2 changes: 2 additions & 0 deletions gfx/layers/CompositorTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ enum class TextureFlags : uint32_t {
DRM_SOURCE = 1 << 21,
// The texture is dummy texture
DUMMY_TEXTURE = 1 << 22,
// Software decoded video
SOFTWARE_DECODED_VIDEO = 1 << 22,

// OR union of all valid bits
ALL_BITS = (1 << 23) - 1,
Expand Down
2 changes: 2 additions & 0 deletions gfx/layers/D3D11ShareHandleImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ D3D11ShareHandleImage::MaybeCreateNV12ImageAndSetData(
return nullptr;
}

client->AddFlags(TextureFlags::SOFTWARE_DECODED_VIDEO);

// The texture does not have keyed mutex. When keyed mutex exists, the texture
// could not be used for video overlay. Then it needs manual synchronization
RefPtr<ID3D11Texture2D> texture = image->GetTexture();
Expand Down
17 changes: 13 additions & 4 deletions gfx/layers/d3d11/TextureD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,9 +951,12 @@ void DXGITextureHostD3D11::UnlockInternal() {

void DXGITextureHostD3D11::CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) {
RefPtr<wr::RenderTextureHost> texture =
RefPtr<wr::RenderDXGITextureHost> texture =
new wr::RenderDXGITextureHost(mHandle, mGpuProcessTextureId, mArrayIndex,
mFormat, mColorSpace, mColorRange, mSize);
if (mFlags & TextureFlags::SOFTWARE_DECODED_VIDEO) {
texture->SetIsSoftwareDecodedVideo();
}
wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
texture.forget());
}
Expand Down Expand Up @@ -1097,9 +1100,15 @@ bool DXGITextureHostD3D11::SupportsExternalCompositing(
return true;
}
// XXX Add P010 and P016 support.
if (GetFormat() == gfx::SurfaceFormat::NV12 &&
gfx::gfxVars::UseWebRenderDCompVideoOverlayWin()) {
return true;
if (GetFormat() == gfx::SurfaceFormat::NV12) {
if ((mFlags & TextureFlags::SOFTWARE_DECODED_VIDEO) &&
(gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin())) {
return true;
}
if (!(mFlags & TextureFlags::SOFTWARE_DECODED_VIDEO) &&
(gfx::gfxVars::UseWebRenderDCompVideoHwOverlayWin())) {
return true;
}
}
return false;
}
Expand Down
22 changes: 15 additions & 7 deletions gfx/layers/wr/AsyncImagePipelineManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ AsyncImagePipelineManager::AsyncImagePipelineManager(
mWillGenerateFrame(false),
mDestroyed(false),
#ifdef XP_WIN
mUseWebRenderDCompVideoOverlayWin(
gfx::gfxVars::UseWebRenderDCompVideoOverlayWin()),
mUseWebRenderDCompVideoHwOverlayWin(
gfx::gfxVars::UseWebRenderDCompVideoHwOverlayWin()),
mUseWebRenderDCompVideoSwOverlayWin(
gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin()),
#endif
mRenderSubmittedUpdatesLock("SubmittedUpdatesLock"),
mLastCompletedFrameId(0) {
Expand Down Expand Up @@ -342,14 +344,20 @@ void AsyncImagePipelineManager::ApplyAsyncImagesOfImageBridge(
}

#ifdef XP_WIN
// UseWebRenderDCompVideoOverlayWin() could be changed from true to false,
// UseWebRenderDCompVideoHwOverlayWin() and
// UseWebRenderDCompVideoSwOverlayWin() could be changed from true to false,
// when DCompVideoOverlay task is failed. In this case, DisplayItems need to
// be re-pushed to WebRender for disabling video overlay.
bool isChanged = mUseWebRenderDCompVideoOverlayWin !=
gfx::gfxVars::UseWebRenderDCompVideoOverlayWin();
bool isChanged = (mUseWebRenderDCompVideoHwOverlayWin !=
gfx::gfxVars::UseWebRenderDCompVideoHwOverlayWin()) ||
(mUseWebRenderDCompVideoSwOverlayWin !=
gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin());

if (isChanged) {
mUseWebRenderDCompVideoOverlayWin =
gfx::gfxVars::UseWebRenderDCompVideoOverlayWin();
mUseWebRenderDCompVideoHwOverlayWin =
gfx::gfxVars::UseWebRenderDCompVideoHwOverlayWin();
mUseWebRenderDCompVideoSwOverlayWin =
gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin();
}
#endif

Expand Down
3 changes: 2 additions & 1 deletion gfx/layers/wr/AsyncImagePipelineManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ class AsyncImagePipelineManager final {
bool mDestroyed;

#ifdef XP_WIN
bool mUseWebRenderDCompVideoOverlayWin;
bool mUseWebRenderDCompVideoHwOverlayWin;
bool mUseWebRenderDCompVideoSwOverlayWin;
#endif

// Render time for the current composition.
Expand Down
73 changes: 58 additions & 15 deletions gfx/thebes/gfxPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2704,49 +2704,92 @@ void gfxPlatform::InitWebRenderConfig() {
MOZ_ASSERT_IF(overlaySupported,
gfxConfig::IsEnabled(Feature::WEBRENDER_DCOMP_PRESENT));

bool useVideoOverlay = false;
if (StaticPrefs::gfx_webrender_dcomp_video_overlay_win_AtStartup()) {
bool useVideoHwOverlay = false;
if (StaticPrefs::gfx_webrender_dcomp_video_hw_overlay_win_AtStartup()) {
if (overlaySupported) {
useVideoOverlay = true;
useVideoHwOverlay = true;
}

if (useVideoOverlay &&
if (useVideoHwOverlay &&
!StaticPrefs::
gfx_webrender_dcomp_video_overlay_win_force_enabled_AtStartup()) {
gfx_webrender_dcomp_video_hw_overlay_win_force_enabled_AtStartup()) {
nsCString failureId;
int32_t status;
const nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
if (NS_FAILED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_VIDEO_OVERLAY,
failureId, &status))) {
FeatureState& feature = gfxConfig::GetFeature(Feature::VIDEO_OVERLAY);
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_HARDWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::BlockedNoGfxInfo,
"gfxInfo is broken",
"FEATURE_FAILURE_WR_NO_GFX_INFO"_ns);
useVideoOverlay = false;
useVideoHwOverlay = false;
} else {
if (status != nsIGfxInfo::FEATURE_ALLOW_ALWAYS) {
FeatureState& feature = gfxConfig::GetFeature(Feature::VIDEO_OVERLAY);
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_HARDWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::Blocked,
"Blocklisted by gfxInfo", failureId);
useVideoOverlay = false;
useVideoHwOverlay = false;
}
}
}
} else if (overlaySupported) {
FeatureState& feature = gfxConfig::GetFeature(Feature::VIDEO_OVERLAY);
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_HARDWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::Blocked, "Disabled by pref",
"FEATURE_FAILURE_DISABLED_BY_PREF"_ns);
}

if (useVideoOverlay) {
FeatureState& feature = gfxConfig::GetFeature(Feature::VIDEO_OVERLAY);
if (useVideoHwOverlay) {
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_HARDWARE_OVERLAY);
feature.EnableByDefault();
gfxVars::SetUseWebRenderDCompVideoOverlayWin(true);
gfxVars::SetUseWebRenderDCompVideoHwOverlayWin(true);
}

if (useVideoOverlay &&
bool useVideoSwOverlay = false;
if (overlaySupported &&
StaticPrefs::gfx_webrender_dcomp_video_sw_overlay_win_AtStartup()) {
gfxVars::SetUseWebRenderDCompSwVideoOverlayWin(true);
useVideoSwOverlay = true;

if (useVideoSwOverlay &&
!StaticPrefs::
gfx_webrender_dcomp_video_sw_overlay_win_force_enabled_AtStartup()) {
nsCString failureId;
int32_t status;
const nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
if (NS_FAILED(gfxInfo->GetFeatureStatus(
nsIGfxInfo::FEATURE_VIDEO_SOFTWARE_OVERLAY, failureId,
&status))) {
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_SOFTWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::BlockedNoGfxInfo,
"gfxInfo is broken",
"FEATURE_FAILURE_WR_NO_GFX_INFO"_ns);
useVideoSwOverlay = false;
} else {
if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_SOFTWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::Blocked,
"Blocklisted by gfxInfo", failureId);
useVideoSwOverlay = false;
}
}
}
} else if (overlaySupported) {
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_SOFTWARE_OVERLAY);
feature.DisableByDefault(FeatureStatus::Blocked, "Disabled by pref",
"FEATURE_FAILURE_DISABLED_BY_PREF"_ns);
}

if (useVideoSwOverlay) {
FeatureState& feature =
gfxConfig::GetFeature(Feature::VIDEO_SOFTWARE_OVERLAY);
feature.EnableByDefault();
gfxVars::SetUseWebRenderDCompVideoSwOverlayWin(true);
}

bool useHwVideoZeroCopy = false;
Expand Down
14 changes: 11 additions & 3 deletions gfx/webrender_bindings/DCLayerTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ bool DCLayerTree::Initialize(HWND aHwnd, nsACString& aError) {
return false;
}

if (gfx::gfxVars::UseWebRenderDCompVideoOverlayWin()) {
if (gfx::gfxVars::UseWebRenderDCompVideoHwOverlayWin() ||
gfx::gfxVars::UseWebRenderDCompVideoSwOverlayWin()) {
if (!InitializeVideoOverlaySupport()) {
RenderThread::Get()->HandleWebRenderError(WebRenderError::VIDEO_OVERLAY);
}
Expand Down Expand Up @@ -1247,8 +1248,15 @@ void DCSurfaceVideo::PresentVideo() {
}

if (mSlowPresentCount > maxSlowPresentCount) {
gfxCriticalNoteOnce << "Video swapchain present is slow";
RenderThread::Get()->HandleWebRenderError(WebRenderError::VIDEO_OVERLAY);
if (mRenderTextureHost->IsSoftwareDecodedVideo()) {
gfxCriticalNoteOnce << "Sw video swapchain present is slow";
RenderThread::Get()->NotifyWebRenderError(
wr::WebRenderError::VIDEO_SW_OVERLAY);
} else {
gfxCriticalNoteOnce << "Hw video swapchain present is slow";
RenderThread::Get()->NotifyWebRenderError(
wr::WebRenderError::VIDEO_HW_OVERLAY);
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions gfx/webrender_bindings/RenderD3D11TextureHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class RenderDXGITextureHost final : public RenderTextureHostSWGL {

uint32_t ArrayIndex() const { return mArrayIndex; }

void SetIsSoftwareDecodedVideo() override { mIsSoftwareDecodedVideo = true; }
bool IsSoftwareDecodedVideo() override { return mIsSoftwareDecodedVideo; }

private:
virtual ~RenderDXGITextureHost();

Expand Down Expand Up @@ -109,6 +112,8 @@ class RenderDXGITextureHost final : public RenderTextureHostSWGL {
// handles for Y and CbCr data.
GLuint mTextureHandle[2];

bool mIsSoftwareDecodedVideo = false;

public:
const gfx::SurfaceFormat mFormat;
const gfx::ColorSpace2 mColorSpace;
Expand Down
8 changes: 8 additions & 0 deletions gfx/webrender_bindings/RenderTextureHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ class RenderTextureHost {

virtual void Destroy();

virtual void SetIsSoftwareDecodedVideo() {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
}
virtual bool IsSoftwareDecodedVideo() {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return false;
}

protected:
virtual ~RenderTextureHost();

Expand Down
2 changes: 2 additions & 0 deletions gfx/webrender_bindings/WebRenderTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,8 @@ enum class WebRenderError : int8_t {
NEW_SURFACE,
BEGIN_DRAW,
VIDEO_OVERLAY,
VIDEO_HW_OVERLAY,
VIDEO_SW_OVERLAY,
EXCESSIVE_RESETS,

Sentinel /* this must be last for serialization purposes. */
Expand Down
15 changes: 10 additions & 5 deletions modules/libpref/init/StaticPrefList.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6564,13 +6564,13 @@
mirror: once

#ifdef XP_WIN
# Whether to use a video overlay layers with DirectComposition
- name: gfx.webrender.dcomp-video-overlay-win
# Whether to use an overlay of hardware decoded video with DirectComposition
- name: gfx.webrender.dcomp-video-hw-overlay-win
type: bool
value: true
mirror: once
# Enable video overlay even when it is blocked.
- name: gfx.webrender.dcomp-video-overlay-win-force-enabled
# Enable hardware decoded video overlay even when it is blocked.
- name: gfx.webrender.dcomp-video-hw-overlay-win-force-enabled
type: bool
value: false
mirror: once
Expand All @@ -6588,11 +6588,16 @@
type: bool
value: true
mirror: once
# Whether to use a video overlay layers for sw decoded video with DirectComposition
# Whether to use an overlay of software decoded video with DirectComposition
- name: gfx.webrender.dcomp-video-sw-overlay-win
type: bool
value: true
mirror: once
# Enable software decoded video overlay even when it is blocked.
- name: gfx.webrender.dcomp-video-sw-overlay-win-force-enabled
type: bool
value: false
mirror: once
- name: gfx.webrender.dcomp-video-check-slow-present
type: RelaxedAtomicBool
value: true
Expand Down
Loading

0 comments on commit 3ece048

Please sign in to comment.