Added VA-API fixes mozbz#1809162, mozbz#1801576

This commit is contained in:
Martin Stransky 2023-01-17 14:28:43 +01:00
parent 54310019ec
commit b2b36e851e
3 changed files with 587 additions and 1 deletions

75
D166324.diff Normal file
View File

@ -0,0 +1,75 @@
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -175,11 +175,10 @@
PtsCorrectionContext mPtsContext;
DurationMap mDurationMap;
const bool mLowLatency;
- AVDiscard mFrameDrop = AVDISCARD_DEFAULT;
const Maybe<TrackingId> mTrackingId;
PerformanceRecorderMulti<DecodeStage> mPerformanceRecorder;
// True if we're allocating shmem for ffmpeg decode buffer.
Maybe<Atomic<bool>> mIsUsingShmemBufferForDecode;
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -850,17 +850,10 @@
packet.dts = aSample->mTimecode.ToMicroseconds();
packet.pts = aSample->mTime.ToMicroseconds();
packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
packet.pos = aSample->mOffset;
- mCodecContext->skip_frame = mFrameDrop;
-#if MOZ_LOGGING
- if (mFrameDrop == AVDISCARD_NONREF) {
- FFMPEG_LOG("Frame skip AVDISCARD_NONREF");
- }
-#endif
-
mTrackingId.apply([&](const auto& aId) {
MediaInfoFlag flag = MediaInfoFlag::None;
flag |= (aSample->mKeyframe ? MediaInfoFlag::KeyFrame
: MediaInfoFlag::NonKeyFrame);
flag |= (IsHardwareAccelerated() ? MediaInfoFlag::HardwareDecoding
@@ -943,22 +936,10 @@
return MediaResult(
NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("avcodec_receive_frame error: %s", errStr));
}
- if (mFrameDrop == AVDISCARD_NONREF) {
- FFMPEG_LOG("Requested pts %" PRId64 " decoded frame pts %" PRId64,
- packet.pts, GetFramePts(mFrame) + mFrame->pkt_duration);
- // Switch back to default frame skip policy if we hit correct
- // decode times. 5 ms treshold is taken from mpv project which
- // use similar approach after seek (feed_packet() at f_decoder_wrapper.c).
- if (packet.pts - 5000 <= GetFramePts(mFrame) + mFrame->pkt_duration) {
- FFMPEG_LOG("Set frame drop to AVDISCARD_DEFAULT.");
- mFrameDrop = AVDISCARD_DEFAULT;
- }
- }
-
UpdateDecodeTimes(decodeStart);
decodeStart = TimeStamp::Now();
MediaResult rv;
# ifdef MOZ_WAYLAND_USE_VAAPI
@@ -1366,14 +1347,10 @@
FFMPEG_LOG("ProcessFlush()");
MOZ_ASSERT(mTaskQueue->IsOnCurrentThread());
mPtsContext.Reset();
mDurationMap.Clear();
mPerformanceRecorder.Record(std::numeric_limits<int64_t>::max());
- // Discard non-ref frames on HW accelerated backend to avoid decode artifacts.
- if (IsHardwareAccelerated()) {
- mFrameDrop = AVDISCARD_NONREF;
- }
return FFmpegDataDecoder::ProcessFlush();
}
AVCodecID FFmpegVideoDecoder<LIBAV_VER>::GetCodecId(
const nsACString& aMimeType) {

View File

@ -173,7 +173,7 @@ ExcludeArch: i686
Summary: Mozilla Firefox Web browser
Name: firefox
Version: 109.0
Release: 1%{?pre_tag}%{?dist}
Release: 2%{?pre_tag}%{?dist}
URL: https://www.mozilla.org/firefox/
License: MPLv1.1 or GPLv2+ or LGPLv2+
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
@ -250,6 +250,8 @@ Patch407: mozilla-1667096.patch
Patch408: mozilla-1663844.patch
Patch415: mozilla-1670333.patch
Patch416: D164651.diff
Patch417: D166324.diff
Patch418: mozilla-1809162.patch
# PGO/LTO patches
Patch600: pgo.patch
@ -525,6 +527,8 @@ This package contains results of tests executed during build.
%patch408 -p1 -b .1663844
%patch415 -p1 -b .1670333
%patch416 -p1 -b .D164651
%patch417 -p1 -b .D166324
%patch418 -p1 -b .1809162
# PGO patches
%if %{build_with_pgo}
@ -1078,6 +1082,9 @@ fi
#---------------------------------------------------------------------
%changelog
* Tue Jan 17 2023 Martin Stransky <stransky@redhat.com>- 109.0-2
- Added VA-API fixes mozbz#1809162, mozbz#1801576
* Mon Jan 16 2023 Martin Stransky <stransky@redhat.com>- 109.0-1
- Update to 109.0

504
mozilla-1809162.patch Normal file
View File

@ -0,0 +1,504 @@
diff -up firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.1809162 firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp
--- firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp.1809162 2023-01-12 21:02:00.000000000 +0100
+++ firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp 2023-01-17 14:23:30.004040571 +0100
@@ -9,6 +9,7 @@
#include "FFmpegLog.h"
#include "mozilla/widget/DMABufLibWrapper.h"
#include "libavutil/pixfmt.h"
+#include "mozilla/gfx/gfxVars.h"
#ifdef MOZ_LOGGING
# undef DMABUF_LOG
@@ -87,7 +88,10 @@ VideoFrameSurface<LIBAV_VER>::~VideoFram
}
VideoFramePool<LIBAV_VER>::VideoFramePool()
- : mSurfaceLock("VideoFramePoolSurfaceLock") {}
+ : mSurfaceLock("VideoFramePoolSurfaceLock"),
+ mSurfaceCopy(!gfx::gfxVars::HwDecodedVideoZeroCopy()) {
+ DMABUF_LOG("VideoFramePool::VideoFramePool() surface copy %d", mSurfaceCopy);
+}
VideoFramePool<LIBAV_VER>::~VideoFramePool() {
MutexAutoLock lock(mSurfaceLock);
@@ -129,32 +133,31 @@ VideoFramePool<LIBAV_VER>::GetVideoFrame
MutexAutoLock lock(mSurfaceLock);
RefPtr<VideoFrameSurface<LIBAV_VER>> videoSurface =
GetFreeVideoFrameSurface();
+ RefPtr<DMABufSurfaceYUV> surface =
+ videoSurface ? videoSurface->GetDMABufSurface() : new DMABufSurfaceYUV();
if (!videoSurface) {
- RefPtr<DMABufSurfaceYUV> surface =
- DMABufSurfaceYUV::CreateYUVSurface(aVaDesc, aWidth, aHeight);
- if (!surface) {
- return nullptr;
- }
DMABUF_LOG("Created new VA-API DMABufSurface UID %d", surface->GetUID());
- RefPtr<VideoFrameSurface<LIBAV_VER>> surf =
- new VideoFrameSurface<LIBAV_VER>(surface);
- if (!mTextureCreationWorks) {
- mTextureCreationWorks = Some(surface->VerifyTextureCreation());
- }
- if (!*mTextureCreationWorks) {
- DMABUF_LOG(" failed to create texture over DMABuf memory!");
- return nullptr;
- }
- videoSurface = surf;
- mDMABufSurfaces.AppendElement(std::move(surf));
+ videoSurface = new VideoFrameSurface<LIBAV_VER>(surface);
+ mDMABufSurfaces.AppendElement(videoSurface);
} else {
- RefPtr<DMABufSurfaceYUV> surface = videoSurface->GetDMABufSurface();
DMABUF_LOG("Reusing VA-API DMABufSurface UID %d", surface->GetUID());
- if (!surface->UpdateYUVData(aVaDesc, aWidth, aHeight)) {
+ }
+
+ if (!surface->UpdateYUVData(aVaDesc, aWidth, aHeight, mSurfaceCopy)) {
+ return nullptr;
+ }
+
+ if (MOZ_UNLIKELY(!mTextureCreationWorks)) {
+ mTextureCreationWorks = Some(surface->VerifyTextureCreation());
+ if (!*mTextureCreationWorks) {
+ DMABUF_LOG(" failed to create texture over DMABuf memory!");
return nullptr;
}
}
- videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib);
+
+ if (!mSurfaceCopy) {
+ videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib);
+ }
videoSurface->MarkAsUsed();
return videoSurface;
}
diff -up firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.1809162 firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h
--- firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h.1809162 2023-01-12 21:02:00.000000000 +0100
+++ firefox-109.0/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h 2023-01-17 14:23:30.004040571 +0100
@@ -129,6 +129,8 @@ class VideoFramePool<LIBAV_VER> {
// We may fail to create texture over DMABuf memory due to driver bugs so
// check that before we export first DMABuf video frame.
Maybe<bool> mTextureCreationWorks;
+ // Copy decoded dmabuf surfaces so we can return them to ffmpeg immediately.
+ const bool mSurfaceCopy;
};
} // namespace mozilla
diff -up firefox-109.0/gfx/thebes/gfxPlatformGtk.cpp.1809162 firefox-109.0/gfx/thebes/gfxPlatformGtk.cpp
--- firefox-109.0/gfx/thebes/gfxPlatformGtk.cpp.1809162 2023-01-12 21:02:01.000000000 +0100
+++ firefox-109.0/gfx/thebes/gfxPlatformGtk.cpp 2023-01-17 14:23:30.004040571 +0100
@@ -253,6 +253,34 @@ bool gfxPlatformGtk::InitVAAPIConfig(boo
feature.ForceDisable(FeatureStatus::Unavailable, "Requires EGL",
"FEATURE_FAILURE_REQUIRES_EGL"_ns);
}
+
+ if (feature.IsEnabled()) {
+ FeatureState& featureZeroCopyDecode =
+ gfxConfig::GetFeature(Feature::HW_DECODED_VIDEO_ZERO_COPY);
+ featureZeroCopyDecode.EnableByDefault();
+
+ if (!StaticPrefs::media_ffmpeg_vaapi_zero_copy_enabled_AtStartup()) {
+ featureZeroCopyDecode.UserDisable("Disabled by pref",
+ "FEATURE_FAILURE_USER_DISABLED"_ns);
+ } else {
+ if (NS_FAILED(gfxInfo->GetFeatureStatus(
+ nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY, failureId,
+ &status))) {
+ featureZeroCopyDecode.DisableByDefault(
+ FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
+ "FEATURE_FAILURE_WR_NO_GFX_INFO"_ns);
+ } else if (status != nsIGfxInfo::FEATURE_ALLOW_ALWAYS) {
+ featureZeroCopyDecode.DisableByDefault(
+ FeatureStatus::Blocked, "Blocklisted by gfxInfo", failureId);
+ }
+ if (StaticPrefs::media_ffmpeg_vaapi_zero_copy_force_enabled_AtStartup()) {
+ featureZeroCopyDecode.UserForceEnable("Force enabled by pref");
+ }
+ if (featureZeroCopyDecode.IsEnabled()) {
+ gfxVars::SetHwDecodedVideoZeroCopy(true);
+ }
+ }
+ }
#else
feature.DisableByDefault(FeatureStatus::Unavailable,
"Wayland support missing",
diff -up firefox-109.0/modules/libpref/init/StaticPrefList.yaml.1809162 firefox-109.0/modules/libpref/init/StaticPrefList.yaml
--- firefox-109.0/modules/libpref/init/StaticPrefList.yaml.1809162 2023-01-12 21:02:07.000000000 +0100
+++ firefox-109.0/modules/libpref/init/StaticPrefList.yaml 2023-01-17 14:23:30.005040605 +0100
@@ -9836,6 +9836,14 @@
type: RelaxedAtomicBool
value: false
mirror: always
+- name: media.ffmpeg.vaapi.zero-copy.enabled
+ type: bool
+ value: true
+ mirror: once
+- name: media.ffmpeg.vaapi.zero-copy.force-enabled
+ type: bool
+ value: false
+ mirror: once
#endif # MOZ_WIDGET_GTK
#endif # MOZ_FFMPEG
diff -up firefox-109.0/widget/gtk/DMABufLibWrapper.cpp.1809162 firefox-109.0/widget/gtk/DMABufLibWrapper.cpp
--- firefox-109.0/widget/gtk/DMABufLibWrapper.cpp.1809162 2023-01-12 21:02:18.000000000 +0100
+++ firefox-109.0/widget/gtk/DMABufLibWrapper.cpp 2023-01-17 14:23:30.005040605 +0100
@@ -12,12 +12,17 @@
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/gfx/gfxVars.h"
#include "WidgetUtilsGtk.h"
+#include "gfxConfig.h"
+#include "nsIGfxInfo.h"
+#include "mozilla/Components.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace widget {
@@ -224,24 +229,13 @@ nsDMABufDevice::~nsDMABufDevice() {
int nsDMABufDevice::GetDRMFd() { return mDRMFd; }
bool nsDMABufDevice::Configure(nsACString& aFailureId) {
- LOGDMABUF(("nsDMABufDevice::Configure()"));
+ if (mInitialized) {
+ return true;
+ }
- MOZ_ASSERT(!mInitialized);
+ LOGDMABUF(("nsDMABufDevice::Configure()"));
mInitialized = true;
- bool isDMABufUsed = (
-#ifdef NIGHTLY_BUILD
- StaticPrefs::widget_dmabuf_textures_enabled() ||
-#endif
- StaticPrefs::widget_dmabuf_webgl_enabled());
-
- if (!isDMABufUsed) {
- // Disabled by user, just quit.
- LOGDMABUF(("IsDMABufEnabled(): Disabled by preferences."));
- aFailureId = "FEATURE_FAILURE_NO_PREFS_ENABLED";
- return false;
- }
-
if (!nsGbmLib::IsAvailable()) {
LOGDMABUF(("nsGbmLib is not available!"));
aFailureId = "FEATURE_FAILURE_NO_LIBGBM";
@@ -327,5 +321,13 @@ nsDMABufDevice* GetDMABufDevice() {
return &dmaBufDevice;
}
+nsDMABufDevice* GetAndConfigureDMABufDevice() {
+ nsCString failureId;
+ if (GetDMABufDevice()->Configure(failureId)) {
+ return GetDMABufDevice();
+ }
+ return nullptr;
+}
+
} // namespace widget
} // namespace mozilla
diff -up firefox-109.0/widget/gtk/DMABufLibWrapper.h.1809162 firefox-109.0/widget/gtk/DMABufLibWrapper.h
--- firefox-109.0/widget/gtk/DMABufLibWrapper.h.1809162 2023-01-12 21:02:18.000000000 +0100
+++ firefox-109.0/widget/gtk/DMABufLibWrapper.h 2023-01-17 14:23:30.005040605 +0100
@@ -215,6 +215,7 @@ class nsDMABufDevice {
};
nsDMABufDevice* GetDMABufDevice();
+nsDMABufDevice* GetAndConfigureDMABufDevice();
} // namespace widget
} // namespace mozilla
diff -up firefox-109.0/widget/gtk/DMABufSurface.cpp.1809162 firefox-109.0/widget/gtk/DMABufSurface.cpp
--- firefox-109.0/widget/gtk/DMABufSurface.cpp.1809162 2023-01-12 21:02:18.000000000 +0100
+++ firefox-109.0/widget/gtk/DMABufSurface.cpp 2023-01-17 14:23:30.006040639 +0100
@@ -67,13 +67,14 @@ RefPtr<GLContext> ClaimSnapshotGLContext
nsCString discardFailureId;
sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId);
if (!sSnapshotContext) {
- LOGDMABUF(("GetAsSourceSurface: Failed to create snapshot GLContext."));
+ LOGDMABUF(
+ ("ClaimSnapshotGLContext: Failed to create snapshot GLContext."));
return nullptr;
}
sSnapshotContext->mOwningThreadId = Nothing(); // No singular owner.
}
if (!sSnapshotContext->MakeCurrent()) {
- LOGDMABUF(("GetAsSourceSurface: Failed to make GLContext current."));
+ LOGDMABUF(("ClaimSnapshotGLContext: Failed to make GLContext current."));
return nullptr;
}
return sSnapshotContext;
@@ -84,6 +85,7 @@ void ReturnSnapshotGLContext(RefPtr<GLCo
// it's not used.
MOZ_ASSERT(!aGLContext->mUseTLSIsCurrent);
if (!aGLContext->IsCurrent()) {
+ LOGDMABUF(("ReturnSnapshotGLContext() failed, is not current!"));
return;
}
const auto& gle = gl::GLContextEGL::Cast(aGLContext);
@@ -911,7 +913,7 @@ already_AddRefed<DMABufSurfaceYUV> DMABu
RefPtr<DMABufSurfaceYUV> surf = new DMABufSurfaceYUV();
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n",
surf->GetUID()));
- if (!surf->UpdateYUVData(aDesc, aWidth, aHeight)) {
+ if (!surf->UpdateYUVData(aDesc, aWidth, aHeight, false)) {
return nullptr;
}
return surf.forget();
@@ -975,16 +977,16 @@ void DMABufSurfaceYUV::CloseFileDescript
}
}
-bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc,
- int aWidth, int aHeight) {
+bool DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor(
+ const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) {
+ LOGDMABUF(("DMABufSurfaceYUV::ImportPRIMESurfaceDescriptor() UID %d", mUID));
+ // Already exists?
+ MOZ_DIAGNOSTIC_ASSERT(mDmabufFds[0] < 0);
+
if (aDesc.num_layers > DMABUF_BUFFER_PLANES ||
aDesc.num_objects > DMABUF_BUFFER_PLANES) {
- return false;
- }
-
- LOGDMABUF(("DMABufSurfaceYUV::UpdateYUVData() UID %d", mUID));
- if (mDmabufFds[0] >= 0) {
- LOGDMABUF((" Already created!"));
+ LOGDMABUF((" Can't import, wrong layers/objects number (%d, %d)",
+ aDesc.num_layers, aDesc.num_objects));
return false;
}
if (aDesc.fourcc == VA_FOURCC_NV12) {
@@ -994,8 +996,7 @@ bool DMABufSurfaceYUV::UpdateYUVData(con
} else if (aDesc.fourcc == VA_FOURCC_YV12) {
mSurfaceType = SURFACE_YUV420;
} else {
- LOGDMABUF(("UpdateYUVData(): Can't import surface data of 0x%x format",
- aDesc.fourcc));
+ LOGDMABUF((" Can't import surface data of 0x%x format", aDesc.fourcc));
return false;
}
@@ -1003,12 +1004,6 @@ bool DMABufSurfaceYUV::UpdateYUVData(con
for (unsigned int i = 0; i < aDesc.num_layers; i++) {
unsigned int object = aDesc.layers[i].object_index[0];
- // Intel exports VA-API surfaces in one object,planes have the same FD.
- // AMD exports surfaces in two objects with different FDs.
- int fd = aDesc.objects[object].fd;
- bool dupFD = (object != i);
- mDmabufFds[i] = dupFD ? dup(fd) : fd;
-
mBufferModifiers[i] = aDesc.objects[object].drm_format_modifier;
mDrmFormats[i] = aDesc.layers[i].drm_format;
mOffsets[i] = aDesc.layers[i].offset[0];
@@ -1017,18 +1012,104 @@ bool DMABufSurfaceYUV::UpdateYUVData(con
mHeightAligned[i] = aDesc.height >> i;
mWidth[i] = aWidth >> i;
mHeight[i] = aHeight >> i;
-
LOGDMABUF((" plane %d size %d x %d format %x", i, mWidth[i], mHeight[i],
mDrmFormats[i]));
}
+ return true;
+}
+bool DMABufSurfaceYUV::MoveYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc,
+ int aWidth, int aHeight) {
+ if (!ImportPRIMESurfaceDescriptor(aDesc, aWidth, aHeight)) {
+ return false;
+ }
+ for (unsigned int i = 0; i < aDesc.num_layers; i++) {
+ unsigned int object = aDesc.layers[i].object_index[0];
+ // Intel exports VA-API surfaces in one object,planes have the same FD.
+ // AMD exports surfaces in two objects with different FDs.
+ int fd = aDesc.objects[object].fd;
+ bool dupFD = (object != i);
+ mDmabufFds[i] = dupFD ? dup(fd) : fd;
+ }
return true;
}
-bool DMABufSurfaceYUV::CreateYUVPlane(int aPlane, int aWidth, int aHeight,
- int aDrmFormat) {
+bool DMABufSurfaceYUV::CreateYUVPlane(int aPlane) {
LOGDMABUF(("DMABufSurfaceYUV::CreateYUVPlane() UID %d size %d x %d", mUID,
- aWidth, aHeight));
+ mWidth[aPlane], mHeight[aPlane]));
+
+ if (!GetAndConfigureDMABufDevice()->GetGbmDevice()) {
+ LOGDMABUF((" Missing GbmDevice!"));
+ return false;
+ }
+
+ bool useModifiers = (mBufferModifiers[aPlane] != DRM_FORMAT_MOD_INVALID);
+ if (useModifiers) {
+ mGbmBufferObject[aPlane] = nsGbmLib::CreateWithModifiers(
+ GetDMABufDevice()->GetGbmDevice(), mWidth[aPlane], mHeight[aPlane],
+ mDrmFormats[aPlane], mBufferModifiers + aPlane, 1);
+ } else {
+ mGbmBufferObject[aPlane] = nsGbmLib::Create(
+ GetDMABufDevice()->GetGbmDevice(), mWidth[aPlane], mHeight[aPlane],
+ mDrmFormats[aPlane], GBM_BO_USE_RENDERING);
+ }
+ if (!mGbmBufferObject[aPlane]) {
+ LOGDMABUF((" Failed to create GbmBufferObject: %s", strerror(errno)));
+ return false;
+ }
+
+ mStrides[aPlane] = nsGbmLib::GetStride(mGbmBufferObject[aPlane]);
+ mOffsets[aPlane] = nsGbmLib::GetOffset(mGbmBufferObject[aPlane], 0);
+ mWidthAligned[aPlane] = mWidth[aPlane];
+ mHeightAligned[aPlane] = mHeight[aPlane];
+ return true;
+}
+
+bool DMABufSurfaceYUV::CopyYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc,
+ int aWidth, int aHeight) {
+ RefPtr<DMABufSurfaceYUV> tmpSurf = CreateYUVSurface(aDesc, aWidth, aHeight);
+ if (!tmpSurf) {
+ return false;
+ }
+
+ if (!ImportPRIMESurfaceDescriptor(aDesc, aWidth, aHeight)) {
+ return false;
+ }
+
+ StaticMutexAutoLock lock(sSnapshotContextMutex);
+ RefPtr<GLContext> context = ClaimSnapshotGLContext();
+ auto releaseTextures = MakeScopeExit([&] {
+ tmpSurf->ReleaseTextures();
+ ReleaseTextures();
+ ReturnSnapshotGLContext(context);
+ });
+
+ for (int i = 0; i < mBufferPlaneCount; i++) {
+ if (!tmpSurf->CreateTexture(context, i)) {
+ return false;
+ }
+ if (!CreateYUVPlane(i) || !CreateTexture(context, i)) {
+ return false;
+ }
+ gfx::IntSize size(GetWidth(i), GetHeight(i));
+ context->BlitHelper()->BlitTextureToTexture(
+ tmpSurf->GetTexture(i), GetTexture(i), size, size, LOCAL_GL_TEXTURE_2D,
+ LOCAL_GL_TEXTURE_2D);
+ }
+ return true;
+}
+
+bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc,
+ int aWidth, int aHeight, bool aCopy) {
+ LOGDMABUF(("DMABufSurfaceYUV::UpdateYUVData() UID %d copy %d", mUID, aCopy));
+ return aCopy ? CopyYUVDataImpl(aDesc, aWidth, aHeight)
+ : MoveYUVDataImpl(aDesc, aWidth, aHeight);
+}
+
+bool DMABufSurfaceYUV::CreateLinearYUVPlane(int aPlane, int aWidth, int aHeight,
+ int aDrmFormat) {
+ LOGDMABUF(("DMABufSurfaceYUV::CreateLinearYUVPlane() UID %d size %d x %d",
+ mUID, aWidth, aHeight));
if (!GetDMABufDevice()->GetGbmDevice()) {
LOGDMABUF((" Missing GbmDevice!"));
@@ -1118,13 +1199,13 @@ bool DMABufSurfaceYUV::Create(int aWidth
mSurfaceType = SURFACE_YUV420;
mBufferPlaneCount = 3;
- if (!CreateYUVPlane(0, aWidth, aHeight, GBM_FORMAT_R8)) {
+ if (!CreateLinearYUVPlane(0, aWidth, aHeight, GBM_FORMAT_R8)) {
return false;
}
- if (!CreateYUVPlane(1, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
+ if (!CreateLinearYUVPlane(1, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
return false;
}
- if (!CreateYUVPlane(2, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
+ if (!CreateLinearYUVPlane(2, aWidth >> 1, aHeight >> 1, GBM_FORMAT_R8)) {
return false;
}
if (!aPixelData || !aLineSizes) {
diff -up firefox-109.0/widget/gtk/DMABufSurface.h.1809162 firefox-109.0/widget/gtk/DMABufSurface.h
--- firefox-109.0/widget/gtk/DMABufSurface.h.1809162 2023-01-12 21:02:18.000000000 +0100
+++ firefox-109.0/widget/gtk/DMABufSurface.h 2023-01-17 14:23:30.006040639 +0100
@@ -323,7 +323,7 @@ class DMABufSurfaceYUV : public DMABufSu
bool UpdateYUVData(void** aPixelData, int* aLineSizes);
bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
- int aHeight);
+ int aHeight, bool aCopy);
bool VerifyTextureCreation();
@@ -332,9 +332,18 @@ class DMABufSurfaceYUV : public DMABufSu
bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
bool Create(int aWidth, int aHeight, void** aPixelData, int* aLineSizes);
- bool CreateYUVPlane(int aPlane, int aWidth, int aHeight, int aDrmFormat);
+ bool CreateYUVPlane(int aPlane);
+ bool CreateLinearYUVPlane(int aPlane, int aWidth, int aHeight,
+ int aDrmFormat);
void UpdateYUVPlane(int aPlane, void* aPixelData, int aLineSize);
+ bool MoveYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
+ int aHeight);
+ bool CopyYUVDataImpl(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth,
+ int aHeight);
+
+ bool ImportPRIMESurfaceDescriptor(const VADRMPRIMESurfaceDescriptor& aDesc,
+ int aWidth, int aHeight);
bool ImportSurfaceDescriptor(
const mozilla::layers::SurfaceDescriptorDMABuf& aDesc);
diff -up firefox-109.0/widget/gtk/GfxInfo.cpp.1809162 firefox-109.0/widget/gtk/GfxInfo.cpp
--- firefox-109.0/widget/gtk/GfxInfo.cpp.1809162 2023-01-17 14:23:30.006040639 +0100
+++ firefox-109.0/widget/gtk/GfxInfo.cpp 2023-01-17 14:24:42.116475502 +0100
@@ -887,6 +887,40 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
V(0, 0, 0, 0), "FEATURE_HARDWARE_VIDEO_DECODING_NO_LINUX_AMD", "");
////////////////////////////////////
+ // FEATURE_HW_DECODED_VIDEO_ZERO_COPY
+ APPEND_TO_DRIVER_BLOCKLIST_EXT(
+ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
+ DesktopEnvironment::All, WindowProtocol::All, DriverVendor::MesaAll,
+ DeviceFamily::All, nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
+ nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN,
+ V(21, 0, 0, 0), "FEATURE_HW_DECODED_VIDEO_ZERO_COPY", "Mesa 21.0.0.0");
+
+ // Disable on all NVIDIA hardware
+ APPEND_TO_DRIVER_BLOCKLIST_EXT(
+ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
+ DesktopEnvironment::All, WindowProtocol::All, DriverVendor::All,
+ DeviceFamily::NvidiaAll, nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
+ nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
+ V(0, 0, 0, 0), "FEATURE_HW_DECODED_VIDEO_ZERO_COPY_NO_LINUX_NVIDIA",
+ "");
+
+ // Disable on all AMD devices (Bug 1802844)
+ APPEND_TO_DRIVER_BLOCKLIST_EXT(
+ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
+ DesktopEnvironment::All, WindowProtocol::All, DriverVendor::All,
+ DeviceFamily::AtiAll, nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
+ nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
+ V(0, 0, 0, 0), "FEATURE_HW_DECODED_VIDEO_ZERO_COPY_NO_LINUX_AMD", "");
+
+ // As FEATURE_HW_DECODED_VIDEO_ZERO_COPY is allow listed feature
+ // we need to explicitly enable it on all Intel hardware.
+ APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Linux, DeviceFamily::IntelAll,
+ nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
+ nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
+ DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0),
+ "FEATURE_ROLLOUT_ALL");
+
+ ////////////////////////////////////
// FEATURE_WEBRENDER_PARTIAL_PRESENT
APPEND_TO_DRIVER_BLOCKLIST_EXT(
OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,