From 61879d2c53a0473a24b4a9a69fcedd1af8f74fdf Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Tue, 7 Jun 2022 11:19:41 +0200 Subject: Enabled VA-API by default (+ added VA-API fixes from upstream), Fixed WebGL performance on NVIDIA drivers (mzbz#1735929) --- D144284.diff | 77 +++++++++++++++++ D145725.diff | 132 ++++++++++++++++++++++++++++ D145871.diff | 140 ++++++++++++++++++++++++++++++ D145966.diff | 20 +++++ D146084.diff | 17 ++++ D146085.diff | 205 +++++++++++++++++++++++++++++++++++++++++++ D146086.diff | 65 ++++++++++++++ D146087.diff | 19 ++++ D147420.diff | 179 ++++++++++++++++++++++++++++++++++++++ D147635.diff | 125 +++++++++++++++++++++++++++ D147636.diff | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D147637.diff | 113 ++++++++++++++++++++++++ D147720.diff | 73 ++++++++++++++++ D147874.diff | 64 ++++++++++++++ firefox.spec | 44 +++++++++- 15 files changed, 1550 insertions(+), 1 deletion(-) create mode 100644 D144284.diff create mode 100644 D145725.diff create mode 100644 D145871.diff create mode 100644 D145966.diff create mode 100644 D146084.diff create mode 100644 D146085.diff create mode 100644 D146086.diff create mode 100644 D146087.diff create mode 100644 D147420.diff create mode 100644 D147635.diff create mode 100644 D147636.diff create mode 100644 D147637.diff create mode 100644 D147720.diff create mode 100644 D147874.diff diff --git a/D144284.diff b/D144284.diff new file mode 100644 index 0000000..d838254 --- /dev/null +++ b/D144284.diff @@ -0,0 +1,77 @@ +diff --git a/gfx/layers/DMABUFSurfaceImage.cpp b/gfx/layers/DMABUFSurfaceImage.cpp +--- a/gfx/layers/DMABUFSurfaceImage.cpp ++++ b/gfx/layers/DMABUFSurfaceImage.cpp +@@ -39,20 +39,20 @@ + + StaticRefPtr sSnapshotContext; + static StaticMutex sSnapshotContextMutex MOZ_UNANNOTATED; + + already_AddRefed DMABUFSurfaceImage::GetAsSourceSurface() { ++ StaticMutexAutoLock lock(sSnapshotContextMutex); + if (!sSnapshotContext) { + nsCString discardFailureId; + sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId); + if (!sSnapshotContext) { + gfxCriticalError() << "Failed to create snapshot GLContext."; + return nullptr; + } + } + +- StaticMutexAutoLock lock(sSnapshotContextMutex); + sSnapshotContext->MakeCurrent(); + + auto releaseTextures = + mozilla::MakeScopeExit([&] { mSurface->ReleaseTextures(); }); + +diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp +--- a/widget/gtk/DMABufSurface.cpp ++++ b/widget/gtk/DMABufSurface.cpp +@@ -53,24 +53,13 @@ + using namespace mozilla::layers; + + #define BUFFER_FLAGS 0 + + static RefPtr sSnapshotContext; ++static StaticMutex sSnapshotContextMutex MOZ_UNANNOTATED; + static Atomic gNewSurfaceUID(1); + +-bool EnsureSnapshotGLContext() { +- if (!sSnapshotContext) { +- nsCString discardFailureId; +- sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId); +- if (!sSnapshotContext) { +- NS_WARNING("Failed to create snapshot GLContext"); +- return false; +- } +- } +- return true; +-} +- + bool DMABufSurface::IsGlobalRefSet() const { + if (!mGlobalRefCountFd) { + return false; + } + struct pollfd pfd; +@@ -1263,13 +1252,18 @@ + } + + bool DMABufSurfaceYUV::VerifyTextureCreation() { + LOGDMABUF(("DMABufSurfaceYUV::VerifyTextureCreation() UID %d", mUID)); + +- if (!EnsureSnapshotGLContext()) { +- LOGDMABUF((" failed to create GL context!")); +- return false; ++ StaticMutexAutoLock lock(sSnapshotContextMutex); ++ if (!sSnapshotContext) { ++ nsCString discardFailureId; ++ sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId); ++ if (!sSnapshotContext) { ++ NS_WARNING("Failed to create snapshot GLContext"); ++ return false; ++ } + } + + auto release = MakeScopeExit([&] { ReleaseEGLImages(sSnapshotContext); }); + + for (int i = 0; i < mBufferPlaneCount; i++) { + diff --git a/D145725.diff b/D145725.diff new file mode 100644 index 0000000..1c28b10 --- /dev/null +++ b/D145725.diff @@ -0,0 +1,132 @@ +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 +@@ -106,10 +106,11 @@ + bool IsHardwareAccelerated(nsACString& aFailureReason) const override; + bool IsHardwareAccelerated() const { + nsAutoCString dummy; + return IsHardwareAccelerated(dummy); + } ++ void UpdateDecodeTimes(TimeStamp aDecodeStart); + + #if LIBAVCODEC_VERSION_MAJOR >= 57 && LIBAVUTIL_VERSION_MAJOR >= 56 + layers::TextureClient* AllocateTextureClientForImage( + struct AVCodecContext* aCodecContext, layers::PlanarYCbCrImage* aImage); + +@@ -142,10 +143,15 @@ + static nsTArray mAcceleratedFormats; + #endif + RefPtr mImageAllocator; + RefPtr mImageContainer; + VideoInfo mInfo; ++ int mDecodedFrames; ++#if LIBAVCODEC_VERSION_MAJOR >= 58 ++ int mDecodedFramesLate; ++#endif ++ float mAverangeDecodeTime; + + class PtsCorrectionContext { + public: + PtsCorrectionContext(); + int64_t GuessCorrectPts(int64_t aPts, int64_t aDts); +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 +@@ -383,10 +383,15 @@ + mDisplay(nullptr), + #endif + mImageAllocator(aAllocator), + mImageContainer(aImageContainer), + mInfo(aConfig), ++ mDecodedFrames(0), ++#if LIBAVCODEC_VERSION_MAJOR >= 58 ++ mDecodedFramesLate(0), ++#endif ++ mAverangeDecodeTime(0), + mLowLatency(aLowLatency) { + FFMPEG_LOG("FFmpegVideoDecoder::FFmpegVideoDecoder MIME %s Codec ID %d", + aConfig.mMimeType.get(), mCodecID); + // Use a new MediaByteBuffer as the object will be modified during + // initialization. +@@ -769,17 +774,41 @@ + #else + return aFrame->pkt_pts; + #endif + } + ++void FFmpegVideoDecoder::UpdateDecodeTimes(TimeStamp aDecodeStart) { ++ mDecodedFrames++; ++ float decodeTime = (TimeStamp::Now() - aDecodeStart).ToMilliseconds(); ++ mAverangeDecodeTime = ++ (mAverangeDecodeTime * (mDecodedFrames - 1) + decodeTime) / ++ mDecodedFrames; ++ FFMPEG_LOG(" averange frame decode time %.2f ms decoded frames %d\n", ++ mAverangeDecodeTime, mDecodedFrames); ++#if LIBAVCODEC_VERSION_MAJOR >= 58 ++ int frameDuration = mFrame->pkt_duration; ++ if (frameDuration > 0 && frameDuration / 1000.0 < decodeTime) { ++ mDecodedFramesLate++; ++ FFMPEG_LOG( ++ " slow decode: failed to decode in time, frame duration %.2f ms, " ++ "decode time %.2f\n", ++ frameDuration / 1000.0, decodeTime); ++ FFMPEG_LOG(" all decoded frames / late decoded frames %d/%d\n", ++ mDecodedFrames, mDecodedFramesLate); ++ } ++#endif ++} ++ + MediaResult FFmpegVideoDecoder::DoDecode( + MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame, + MediaDataDecoder::DecodedData& aResults) { + MOZ_ASSERT(mTaskQueue->IsOnCurrentThread()); + AVPacket packet; + mLib->av_init_packet(&packet); + ++ TimeStamp decodeStart = TimeStamp::Now(); ++ + packet.data = aData; + packet.size = aSize; + packet.dts = aSample->mTimecode.ToMicroseconds(); + packet.pts = aSample->mTime.ToMicroseconds(); + packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0; +@@ -794,11 +823,10 @@ + // at a time, and we immediately call avcodec_receive_frame right after. + FFMPEG_LOG("avcodec_send_packet error: %d", res); + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("avcodec_send_packet error: %d", res)); + } +- + if (aGotFrame) { + *aGotFrame = false; + } + do { + if (!PrepareFrame()) { +@@ -831,10 +859,13 @@ + FFMPEG_LOG(" avcodec_receive_frame error: %d", res); + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("avcodec_receive_frame error: %d", res)); + } + ++ UpdateDecodeTimes(decodeStart); ++ decodeStart = TimeStamp::Now(); ++ + MediaResult rv; + # ifdef MOZ_WAYLAND_USE_VAAPI + if (IsHardwareAccelerated()) { + rv = CreateImageVAAPI(mFrame->pkt_pos, GetFramePts(mFrame), + mFrame->pkt_duration, aResults); +@@ -898,10 +929,12 @@ + *aGotFrame = false; + } + return NS_OK; + } + ++ UpdateDecodeTimes(decodeStart); ++ + // If we've decoded a frame then we need to output it + int64_t pts = + mPtsContext.GuessCorrectPts(GetFramePts(mFrame), mFrame->pkt_dts); + // Retrieve duration from dts. + // We use the first entry found matching this dts (this is done to + diff --git a/D145871.diff b/D145871.diff new file mode 100644 index 0000000..33a2e61 --- /dev/null +++ b/D145871.diff @@ -0,0 +1,140 @@ +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 +@@ -146,10 +146,15 @@ + RefPtr mImageContainer; + VideoInfo mInfo; + int mDecodedFrames; + #if LIBAVCODEC_VERSION_MAJOR >= 58 + int mDecodedFramesLate; ++ // Tracks when decode time of recent frame and averange decode time of ++ // previous frames is bigger than frame interval, ++ // i.e. we fail to decode in time. ++ // We switch to SW decode when we hit HW_DECODE_LATE_FRAMES treshold. ++ int mMissedDecodeInAverangeTime; + #endif + float mAverangeDecodeTime; + + class PtsCorrectionContext { + public: +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 +@@ -14,10 +14,13 @@ + #include "VPXDecoder.h" + #include "mozilla/layers/KnowsCompositor.h" + #if LIBAVCODEC_VERSION_MAJOR >= 57 + # include "mozilla/layers/TextureClient.h" + #endif ++#if LIBAVCODEC_VERSION_MAJOR >= 58 ++# include "mozilla/ProfilerMarkers.h" ++#endif + #ifdef MOZ_WAYLAND_USE_VAAPI + # include "H264.h" + # include "mozilla/layers/DMABUFSurfaceImage.h" + # include "mozilla/widget/DMABufLibWrapper.h" + # include "FFmpegVideoFramePool.h" +@@ -56,13 +59,14 @@ + typedef int VAStatus; + # define VA_EXPORT_SURFACE_READ_ONLY 0x0001 + # define VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x0004 + # define VA_STATUS_SUCCESS 0x00000000 + #endif +- + // Use some extra HW frames for potential rendering lags. + #define EXTRA_HW_FRAMES 6 ++// Defines number of delayed frames until we switch back to SW decode. ++#define HW_DECODE_LATE_FRAMES 15 + + #if LIBAVCODEC_VERSION_MAJOR >= 57 && LIBAVUTIL_VERSION_MAJOR >= 56 + # define CUSTOMIZED_BUFFER_ALLOCATION 1 + #endif + +@@ -386,10 +390,11 @@ + mImageContainer(aImageContainer), + mInfo(aConfig), + mDecodedFrames(0), + #if LIBAVCODEC_VERSION_MAJOR >= 58 + mDecodedFramesLate(0), ++ mMissedDecodeInAverangeTime(0), + #endif + mAverangeDecodeTime(0), + mLowLatency(aLowLatency) { + FFMPEG_LOG("FFmpegVideoDecoder::FFmpegVideoDecoder MIME %s Codec ID %d", + aConfig.mMimeType.get(), mCodecID); +@@ -781,22 +786,32 @@ + float decodeTime = (TimeStamp::Now() - aDecodeStart).ToMilliseconds(); + mAverangeDecodeTime = + (mAverangeDecodeTime * (mDecodedFrames - 1) + decodeTime) / + mDecodedFrames; + FFMPEG_LOG( +- " decode time %.2f ms averange decode time %.2f ms decoded frames %d\n", ++ "Frame decode finished, time %.2f ms averange decode time %.2f ms " ++ "decoded %d frames\n", + decodeTime, mAverangeDecodeTime, mDecodedFrames); + #if LIBAVCODEC_VERSION_MAJOR >= 58 +- int frameDuration = mFrame->pkt_duration; +- if (frameDuration > 0 && frameDuration / 1000.0 < decodeTime) { +- mDecodedFramesLate++; +- FFMPEG_LOG( +- " slow decode: failed to decode in time, frame duration %.2f ms, " +- "decode time %.2f\n", +- frameDuration / 1000.0, decodeTime); +- FFMPEG_LOG(" all decoded frames / late decoded frames %d/%d\n", +- mDecodedFrames, mDecodedFramesLate); ++ if (mFrame->pkt_duration > 0) { ++ // Switch frame duration to ms ++ float frameDuration = mFrame->pkt_duration / 1000.0f; ++ if (frameDuration < decodeTime) { ++ PROFILER_MARKER_TEXT("FFmpegVideoDecoder::DoDecode", MEDIA_PLAYBACK, {}, ++ "frame decode takes too long"); ++ mDecodedFramesLate++; ++ if (frameDuration < mAverangeDecodeTime) { ++ mMissedDecodeInAverangeTime++; ++ } ++ FFMPEG_LOG( ++ " slow decode: failed to decode in time, frame duration %.2f ms, " ++ "decode time %.2f\n", ++ frameDuration, decodeTime); ++ FFMPEG_LOG(" frames: all decoded %d late decoded %d over averange %d\n", ++ mDecodedFrames, mDecodedFramesLate, ++ mMissedDecodeInAverangeTime); ++ } + } + #endif + } + + MediaResult FFmpegVideoDecoder::DoDecode( +@@ -866,10 +881,18 @@ + decodeStart = TimeStamp::Now(); + + MediaResult rv; + # ifdef MOZ_WAYLAND_USE_VAAPI + if (IsHardwareAccelerated()) { ++ if (mMissedDecodeInAverangeTime > HW_DECODE_LATE_FRAMES) { ++ PROFILER_MARKER_TEXT("FFmpegVideoDecoder::DoDecode", MEDIA_PLAYBACK, {}, ++ "Fallback to SW decode"); ++ FFMPEG_LOG(" HW decoding is slow, switch back to SW decode"); ++ return MediaResult( ++ NS_ERROR_DOM_MEDIA_DECODE_ERR, ++ RESULT_DETAIL("HW decoding is slow, switch back to SW decode")); ++ } + rv = CreateImageVAAPI(mFrame->pkt_pos, GetFramePts(mFrame), + mFrame->pkt_duration, aResults); + // If VA-API playback failed, just quit. Decoder is going to be restarted + // without VA-API. + if (NS_FAILED(rv)) { +@@ -1129,11 +1152,11 @@ + } + + MediaResult FFmpegVideoDecoder::CreateImageVAAPI( + int64_t aOffset, int64_t aPts, int64_t aDuration, + MediaDataDecoder::DecodedData& aResults) { +- FFMPEG_LOG("VA-API Got one frame output with pts=%" PRId64 "dts=%" PRId64 ++ FFMPEG_LOG("VA-API Got one frame output with pts=%" PRId64 " dts=%" PRId64 + " duration=%" PRId64 " opaque=%" PRId64, + aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque); + + VADRMPRIMESurfaceDescriptor vaDesc; + if (!GetVAAPISurfaceDescriptor(&vaDesc)) { + diff --git a/D145966.diff b/D145966.diff new file mode 100644 index 0000000..2ecfaec --- /dev/null +++ b/D145966.diff @@ -0,0 +1,20 @@ +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 +@@ -780,12 +780,13 @@ + mDecodedFrames++; + float decodeTime = (TimeStamp::Now() - aDecodeStart).ToMilliseconds(); + mAverangeDecodeTime = + (mAverangeDecodeTime * (mDecodedFrames - 1) + decodeTime) / + mDecodedFrames; +- FFMPEG_LOG(" averange frame decode time %.2f ms decoded frames %d\n", +- mAverangeDecodeTime, mDecodedFrames); ++ FFMPEG_LOG( ++ " decode time %.2f ms averange decode time %.2f ms decoded frames %d\n", ++ decodeTime, mAverangeDecodeTime, mDecodedFrames); + #if LIBAVCODEC_VERSION_MAJOR >= 58 + int frameDuration = mFrame->pkt_duration; + if (frameDuration > 0 && frameDuration / 1000.0 < decodeTime) { + mDecodedFramesLate++; + FFMPEG_LOG( + diff --git a/D146084.diff b/D146084.diff new file mode 100644 index 0000000..8ed2c28 --- /dev/null +++ b/D146084.diff @@ -0,0 +1,17 @@ +diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh +--- a/gfx/layers/ipc/LayersSurfaces.ipdlh ++++ b/gfx/layers/ipc/LayersSurfaces.ipdlh +@@ -57,10 +57,12 @@ + uint64_t[] modifier; + uint32_t flags; + FileDescriptor[] fds; + uint32_t[] width; + uint32_t[] height; ++ uint32_t[] widthAligned; ++ uint32_t[] heightAligned; + uint32_t[] format; + uint32_t[] strides; + uint32_t[] offsets; + YUVColorSpace yUVColorSpace; + ColorRange colorRange; + diff --git a/D146085.diff b/D146085.diff new file mode 100644 index 0000000..6b037f6 --- /dev/null +++ b/D146085.diff @@ -0,0 +1,205 @@ +diff --git a/widget/gtk/DMABufSurface.h b/widget/gtk/DMABufSurface.h +--- a/widget/gtk/DMABufSurface.h ++++ b/widget/gtk/DMABufSurface.h +@@ -275,11 +275,11 @@ + static already_AddRefed CreateYUVSurface( + int aWidth, int aHeight, void** aPixelData = nullptr, + int* aLineSizes = nullptr); + + static already_AddRefed CreateYUVSurface( +- const VADRMPRIMESurfaceDescriptor& aDesc); ++ const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight); + + bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor); + + DMABufSurfaceYUV* GetAsDMABufSurfaceYUV() { return this; }; + +@@ -304,11 +304,12 @@ + mozilla::gfx::YUVColorSpace GetYUVColorSpace() { return mColorSpace; } + + DMABufSurfaceYUV(); + + bool UpdateYUVData(void** aPixelData, int* aLineSizes); +- bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc); ++ bool UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, ++ int aHeight); + + bool VerifyTextureCreation(); + + private: + ~DMABufSurfaceYUV(); +@@ -329,10 +330,15 @@ + bool CreateEGLImage(mozilla::gl::GLContext* aGLContext, int aPlane); + void ReleaseEGLImages(mozilla::gl::GLContext* aGLContext); + + int mWidth[DMABUF_BUFFER_PLANES]; + int mHeight[DMABUF_BUFFER_PLANES]; ++ // Aligned size of the surface imported from VADRMPRIMESurfaceDescriptor. ++ // It's used only internally to create EGLImage as some GL drivers ++ // needs that (Bug 1724385). ++ int mWidthAligned[DMABUF_BUFFER_PLANES]; ++ int mHeightAligned[DMABUF_BUFFER_PLANES]; + EGLImageKHR mEGLImage[DMABUF_BUFFER_PLANES]; + GLuint mTexture[DMABUF_BUFFER_PLANES]; + mozilla::gfx::YUVColorSpace mColorSpace = + mozilla::gfx::YUVColorSpace::Default; + }; +diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp +--- a/widget/gtk/DMABufSurface.cpp ++++ b/widget/gtk/DMABufSurface.cpp +@@ -479,13 +479,13 @@ + if (mGlobalRefCountFd) { + refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd)); + } + + aOutDescriptor = SurfaceDescriptorDMABuf( +- mSurfaceType, modifiers, mGbmBufferFlags, fds, width, height, format, +- strides, offsets, GetYUVColorSpace(), mColorRange, fenceFDs, mUID, +- refCountFDs); ++ mSurfaceType, modifiers, mGbmBufferFlags, fds, width, height, width, ++ height, format, strides, offsets, GetYUVColorSpace(), mColorRange, ++ fenceFDs, mUID, refCountFDs); + return true; + } + + bool DMABufSurfaceRGBA::CreateTexture(GLContext* aGLContext, int aPlane) { + MOZ_ASSERT(!mEGLImage && !mTexture, "EGLImage is already created!"); +@@ -807,15 +807,15 @@ + } + return surf.forget(); + } + + already_AddRefed DMABufSurfaceYUV::CreateYUVSurface( +- const VADRMPRIMESurfaceDescriptor& aDesc) { ++ const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) { + RefPtr surf = new DMABufSurfaceYUV(); + LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n", + surf->GetUID())); +- if (!surf->UpdateYUVData(aDesc)) { ++ if (!surf->UpdateYUVData(aDesc, aWidth, aHeight)) { + return nullptr; + } + return surf.forget(); + } + +@@ -829,11 +829,16 @@ + } + return surf.forget(); + } + + DMABufSurfaceYUV::DMABufSurfaceYUV() +- : DMABufSurface(SURFACE_NV12), mWidth(), mHeight(), mTexture() { ++ : DMABufSurface(SURFACE_NV12), ++ mWidth(), ++ mHeight(), ++ mWidthAligned(), ++ mHeightAligned(), ++ mTexture() { + for (int i = 0; i < DMABUF_BUFFER_PLANES; i++) { + mEGLImage[i] = LOCAL_EGL_NO_IMAGE; + } + } + +@@ -870,11 +875,12 @@ + close(mDmabufFds[aPlane]); + mDmabufFds[aPlane] = -1; + } + } + +-bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc) { ++bool DMABufSurfaceYUV::UpdateYUVData(const VADRMPRIMESurfaceDescriptor& aDesc, ++ int aWidth, int aHeight) { + if (aDesc.num_layers > DMABUF_BUFFER_PLANES || + aDesc.num_objects > DMABUF_BUFFER_PLANES) { + return false; + } + +@@ -907,12 +913,14 @@ + + mBufferModifiers[i] = aDesc.objects[object].drm_format_modifier; + mDrmFormats[i] = aDesc.layers[i].drm_format; + mOffsets[i] = aDesc.layers[i].offset[0]; + mStrides[i] = aDesc.layers[i].pitch[0]; +- mWidth[i] = aDesc.width >> i; +- mHeight[i] = aDesc.height >> i; ++ mWidthAligned[i] = aDesc.width >> i; ++ 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])); + } + +@@ -1044,10 +1052,12 @@ + strerror(errno))); + return false; + } + mWidth[i] = aDesc.width()[i]; + mHeight[i] = aDesc.height()[i]; ++ mWidthAligned[i] = aDesc.widthAligned()[i]; ++ mHeightAligned[i] = aDesc.heightAligned()[i]; + mDrmFormats[i] = aDesc.format()[i]; + mStrides[i] = aDesc.strides()[i]; + mOffsets[i] = aDesc.offsets()[i]; + mBufferModifiers[i] = aDesc.modifier()[i]; + LOGDMABUF((" plane %d fd %d size %d x %d format %x", i, mDmabufFds[i], +@@ -1072,10 +1082,12 @@ + + bool DMABufSurfaceYUV::Serialize( + mozilla::layers::SurfaceDescriptor& aOutDescriptor) { + AutoTArray width; + AutoTArray height; ++ AutoTArray widthBytes; ++ AutoTArray heightBytes; + AutoTArray format; + AutoTArray fds; + AutoTArray strides; + AutoTArray offsets; + AutoTArray modifiers; +@@ -1090,10 +1102,12 @@ + } + + for (int i = 0; i < mBufferPlaneCount; i++) { + width.AppendElement(mWidth[i]); + height.AppendElement(mHeight[i]); ++ widthBytes.AppendElement(mWidthAligned[i]); ++ heightBytes.AppendElement(mHeightAligned[i]); + format.AppendElement(mDrmFormats[i]); + fds.AppendElement(ipc::FileDescriptor(mDmabufFds[i])); + strides.AppendElement(mStrides[i]); + offsets.AppendElement(mOffsets[i]); + modifiers.AppendElement(mBufferModifiers[i]); +@@ -1108,12 +1122,13 @@ + if (mGlobalRefCountFd) { + refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd)); + } + + aOutDescriptor = SurfaceDescriptorDMABuf( +- mSurfaceType, modifiers, 0, fds, width, height, format, strides, offsets, +- GetYUVColorSpace(), mColorRange, fenceFDs, mUID, refCountFDs); ++ mSurfaceType, modifiers, 0, fds, width, height, widthBytes, heightBytes, ++ format, strides, offsets, GetYUVColorSpace(), mColorRange, fenceFDs, mUID, ++ refCountFDs); + return true; + } + + bool DMABufSurfaceYUV::CreateEGLImage(GLContext* aGLContext, int aPlane) { + LOGDMABUF( +@@ -1131,13 +1146,13 @@ + return false; + } + + nsTArray attribs; + attribs.AppendElement(LOCAL_EGL_WIDTH); +- attribs.AppendElement(mWidth[aPlane]); ++ attribs.AppendElement(mWidthAligned[aPlane]); + attribs.AppendElement(LOCAL_EGL_HEIGHT); +- attribs.AppendElement(mHeight[aPlane]); ++ attribs.AppendElement(mHeightAligned[aPlane]); + attribs.AppendElement(LOCAL_EGL_LINUX_DRM_FOURCC_EXT); + attribs.AppendElement(mDrmFormats[aPlane]); + #define ADD_PLANE_ATTRIBS_NV12(plane_idx) \ + attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_FD_EXT); \ + attribs.AppendElement(mDmabufFds[aPlane]); \ + diff --git a/D146086.diff b/D146086.diff new file mode 100644 index 0000000..c6790ad --- /dev/null +++ b/D146086.diff @@ -0,0 +1,65 @@ +diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h b/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h +--- a/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h ++++ b/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.h +@@ -112,12 +112,13 @@ + public: + VideoFramePool(); + ~VideoFramePool(); + + RefPtr> GetVideoFrameSurface( +- VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext, +- AVFrame* aAVFrame, FFmpegLibWrapper* aLib); ++ VADRMPRIMESurfaceDescriptor& aVaDesc, int aWidth, int aHeight, ++ AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, ++ FFmpegLibWrapper* aLib); + void ReleaseUnusedVAAPIFrames(); + + private: + RefPtr> GetFreeVideoFrameSurface(); + +diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp +--- a/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp ++++ b/dom/media/platforms/ffmpeg/FFmpegVideoFramePool.cpp +@@ -111,12 +111,13 @@ + return nullptr; + } + + RefPtr> + VideoFramePool::GetVideoFrameSurface( +- VADRMPRIMESurfaceDescriptor& aVaDesc, AVCodecContext* aAVCodecContext, +- AVFrame* aAVFrame, FFmpegLibWrapper* aLib) { ++ VADRMPRIMESurfaceDescriptor& aVaDesc, int aWidth, int aHeight, ++ AVCodecContext* aAVCodecContext, AVFrame* aAVFrame, ++ FFmpegLibWrapper* aLib) { + if (aVaDesc.fourcc != VA_FOURCC_NV12 && aVaDesc.fourcc != VA_FOURCC_YV12 && + aVaDesc.fourcc != VA_FOURCC_P010) { + FFMPEG_LOG("Unsupported VA-API surface format %d", aVaDesc.fourcc); + return nullptr; + } +@@ -124,11 +125,11 @@ + MutexAutoLock lock(mSurfaceLock); + RefPtr> videoSurface = + GetFreeVideoFrameSurface(); + if (!videoSurface) { + RefPtr surface = +- DMABufSurfaceYUV::CreateYUVSurface(aVaDesc); ++ DMABufSurfaceYUV::CreateYUVSurface(aVaDesc, aWidth, aHeight); + if (!surface) { + return nullptr; + } + FFMPEG_LOG("Created new VA-API DMABufSurface UID = %d", surface->GetUID()); + RefPtr> surf = +@@ -142,11 +143,11 @@ + } + videoSurface = surf; + mDMABufSurfaces.AppendElement(std::move(surf)); + } else { + RefPtr surface = videoSurface->GetDMABufSurface(); +- if (!surface->UpdateYUVData(aVaDesc)) { ++ if (!surface->UpdateYUVData(aVaDesc, aWidth, aHeight)) { + return nullptr; + } + FFMPEG_LOG("Reusing VA-API DMABufSurface UID = %d", surface->GetUID()); + } + videoSurface->LockVAAPIData(aAVCodecContext, aAVFrame, aLib); + diff --git a/D146087.diff b/D146087.diff new file mode 100644 index 0000000..d5dcf9d --- /dev/null +++ b/D146087.diff @@ -0,0 +1,19 @@ +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 +@@ -1164,12 +1164,12 @@ + NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()")); + } + + MOZ_ASSERT(mTaskQueue->IsOnCurrentThread()); +- auto surface = mVideoFramePool->GetVideoFrameSurface(vaDesc, mCodecContext, +- mFrame, mLib); ++ auto surface = mVideoFramePool->GetVideoFrameSurface( ++ vaDesc, mFrame->width, mFrame->height, mCodecContext, mFrame, mLib); + if (!surface) { + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("VAAPI dmabuf allocation error")); + } + surface->SetYUVColorSpace(GetFrameColorSpace()); + diff --git a/D147420.diff b/D147420.diff new file mode 100644 index 0000000..1ee3af1 --- /dev/null +++ b/D147420.diff @@ -0,0 +1,179 @@ +diff -up firefox-101.0/gfx/gl/GLContextEGL.h.D147420.diff firefox-101.0/gfx/gl/GLContextEGL.h +--- firefox-101.0/gfx/gl/GLContextEGL.h.D147420.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/GLContextEGL.h 2022-06-07 09:01:17.487787806 +0200 +@@ -106,6 +106,9 @@ class GLContextEGL final : public GLCont + static RefPtr CreateEGLPBufferOffscreenContextImpl( + std::shared_ptr, const GLContextCreateDesc&, + const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId); ++ static RefPtr CreateEGLSurfacelessContext( ++ const std::shared_ptr display, ++ const GLContextCreateDesc& desc, nsACString* const out_failureId); + + static EGLSurface CreateEGLSurfaceForCompositorWidget( + widget::CompositorWidget* aCompositorWidget, const EGLConfig aConfig); +diff -up firefox-101.0/gfx/gl/GLContextProviderEGL.cpp.D147420.diff firefox-101.0/gfx/gl/GLContextProviderEGL.cpp +--- firefox-101.0/gfx/gl/GLContextProviderEGL.cpp.D147420.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/GLContextProviderEGL.cpp 2022-06-07 09:01:17.487787806 +0200 +@@ -1190,16 +1190,42 @@ RefPtr GLContextEGL::Creat + } + + /*static*/ ++RefPtr GLContextEGL::CreateEGLSurfacelessContext( ++ const std::shared_ptr display, const GLContextCreateDesc& desc, ++ nsACString* const out_failureId) { ++ const EGLConfig config = {}; ++ auto fullDesc = GLContextDesc{desc}; ++ fullDesc.isOffscreen = true; ++ RefPtr gl = GLContextEGL::CreateGLContext( ++ display, fullDesc, config, EGL_NO_SURFACE, false, out_failureId); ++ if (!gl) { ++ NS_WARNING("Failed to create surfaceless GL context"); ++ return nullptr; ++ } ++ return gl; ++} ++ ++/*static*/ + already_AddRefed GLContextProviderEGL::CreateHeadless( + const GLContextCreateDesc& desc, nsACString* const out_failureId) { + const auto display = DefaultEglDisplay(out_failureId); + if (!display) { + return nullptr; + } +- mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16); +- auto ret = GLContextEGL::CreateEGLPBufferOffscreenContext( +- display, desc, dummySize, out_failureId); +- return ret.forget(); ++ RefPtr gl; ++#ifdef MOZ_WAYLAND ++ if (!gdk_display_get_default() && ++ display->IsExtensionSupported(EGLExtension::MESA_platform_surfaceless)) { ++ gl = ++ GLContextEGL::CreateEGLSurfacelessContext(display, desc, out_failureId); ++ } else ++#endif ++ { ++ mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16); ++ gl = GLContextEGL::CreateEGLPBufferOffscreenContext( ++ display, desc, dummySize, out_failureId); ++ } ++ return gl.forget(); + } + + // Don't want a global context on Android as 1) share groups across 2 threads +diff -up firefox-101.0/gfx/gl/GLDefs.h.D147420.diff firefox-101.0/gfx/gl/GLDefs.h +--- firefox-101.0/gfx/gl/GLDefs.h.D147420.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/GLDefs.h 2022-06-07 09:01:17.487787806 +0200 +@@ -104,6 +104,9 @@ bool CheckContextLost(const GLContext* g + // EGL_ANGLE_image_d3d11_texture + #define LOCAL_EGL_D3D11_TEXTURE_ANGLE 0x3484 + ++// EGL_MESA_platform_surfaceless ++#define LOCAL_EGL_PLATFORM_SURFACELESS_MESA 0x31DD ++ + // clang-format on + + #endif +diff -up firefox-101.0/gfx/gl/GLLibraryEGL.cpp.D147420.diff firefox-101.0/gfx/gl/GLLibraryEGL.cpp +--- firefox-101.0/gfx/gl/GLLibraryEGL.cpp.D147420.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/GLLibraryEGL.cpp 2022-06-07 09:03:04.077349997 +0200 +@@ -82,7 +82,8 @@ static const char* sEGLExtensionNames[] + "EGL_KHR_swap_buffers_with_damage", + "EGL_EXT_buffer_age", + "EGL_KHR_partial_update", +- "EGL_NV_robustness_video_memory_purge"}; ++ "EGL_NV_robustness_video_memory_purge", ++ "EGL_MESA_platform_surfaceless"}; + + PRLibrary* LoadApitraceLibrary() { + const char* path = nullptr; +@@ -151,6 +152,19 @@ static std::shared_ptr GetAn + return EglDisplay::Create(egl, display, false, aProofOfLock); + } + ++#ifdef MOZ_WAYLAND ++static std::shared_ptr GetAndInitSurfacelessDisplay( ++ GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) { ++ const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE}; ++ const EGLDisplay display = egl.fGetPlatformDisplay( ++ LOCAL_EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, attrib_list); ++ if (display == EGL_NO_DISPLAY) { ++ return nullptr; ++ } ++ return EglDisplay::Create(egl, display, true, aProofOfLock); ++} ++#endif ++ + static std::shared_ptr GetAndInitWARPDisplay( + GLLibraryEGL& egl, void* displayType, + const StaticMutexAutoLock& aProofOfLock) { +@@ -629,6 +643,11 @@ bool GLLibraryEGL::Init(nsACString* cons + END_OF_SYMBOLS}; + (void)fnLoadSymbols(symbols); + } ++ { ++ const SymLoadStruct symbols[] = {SYMBOL(GetPlatformDisplay), ++ END_OF_SYMBOLS}; ++ (void)fnLoadSymbols(symbols); ++ } + + return true; + } +@@ -806,7 +825,9 @@ std::shared_ptr GLLibraryEGL + #ifdef MOZ_WAYLAND + // Some drivers doesn't support EGL_DEFAULT_DISPLAY + GdkDisplay* gdkDisplay = gdk_display_get_default(); +- if (widget::GdkIsWaylandDisplay(gdkDisplay)) { ++ if (!gdkDisplay) { ++ ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock); ++ } else if (widget::GdkIsWaylandDisplay(gdkDisplay)) { + nativeDisplay = widget::WaylandDisplayGetWLDisplay(gdkDisplay); + if (!nativeDisplay) { + NS_WARNING("Failed to get wl_display."); +@@ -814,7 +835,9 @@ std::shared_ptr GLLibraryEGL + } + } + #endif +- ret = GetAndInitDisplay(*this, nativeDisplay, aProofOfLock); ++ if (!ret) { ++ ret = GetAndInitDisplay(*this, nativeDisplay, aProofOfLock); ++ } + } + + if (!ret) { +diff -up firefox-101.0/gfx/gl/GLLibraryEGL.h.D147420.diff firefox-101.0/gfx/gl/GLLibraryEGL.h +--- firefox-101.0/gfx/gl/GLLibraryEGL.h.D147420.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/GLLibraryEGL.h 2022-06-07 09:01:17.487787806 +0200 +@@ -107,6 +107,7 @@ enum class EGLExtension { + EXT_buffer_age, + KHR_partial_update, + NV_robustness_video_memory_purge, ++ MESA_platform_surfaceless, + Max + }; + +diff -up firefox-101.0/widget/gtk/DMABufSurface.cpp.D147420.diff firefox-101.0/widget/gtk/DMABufSurface.cpp +--- firefox-101.0/widget/gtk/DMABufSurface.cpp.D147420.diff 2022-06-07 09:01:17.486787773 +0200 ++++ firefox-101.0/widget/gtk/DMABufSurface.cpp 2022-06-07 09:01:17.487787806 +0200 +@@ -1259,7 +1259,7 @@ bool DMABufSurfaceYUV::VerifyTextureCrea + nsCString discardFailureId; + sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId); + if (!sSnapshotContext) { +- NS_WARNING("Failed to create snapshot GLContext"); ++ LOGDMABUF((" failed to create snapshot GLContext")); + return false; + } + } +@@ -1268,10 +1268,12 @@ bool DMABufSurfaceYUV::VerifyTextureCrea + + for (int i = 0; i < mBufferPlaneCount; i++) { + if (!CreateEGLImage(sSnapshotContext, i)) { ++ LOGDMABUF((" failed to create EGL image!")); + return false; + } + } + ++ LOGDMABUF((" success")); + return true; + } + diff --git a/D147635.diff b/D147635.diff new file mode 100644 index 0000000..1d4bb58 --- /dev/null +++ b/D147635.diff @@ -0,0 +1,125 @@ +diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h +--- a/gfx/gl/GLLibraryEGL.h ++++ b/gfx/gl/GLLibraryEGL.h +@@ -106,10 +106,13 @@ + KHR_swap_buffers_with_damage, + EXT_buffer_age, + KHR_partial_update, + NV_robustness_video_memory_purge, + MESA_platform_surfaceless, ++ EXT_image_dma_buf_import, ++ EXT_image_dma_buf_import_modifiers, ++ MESA_image_dma_buf_export, + Max + }; + + // - + +@@ -461,10 +464,23 @@ + // EGL_KHR_partial_update + EGLBoolean fSetDamageRegion(EGLDisplay dpy, EGLSurface surface, + const EGLint* rects, EGLint n_rects) { + WRAP(fSetDamageRegion(dpy, surface, rects, n_rects)); + } ++ // EGL_MESA_image_dma_buf_export ++ EGLBoolean fExportDMABUFImageQuery(EGLDisplay dpy, EGLImage image, ++ int* fourcc, int* num_planes, ++ uint64_t* modifiers) { ++ WRAP( ++ fExportDMABUFImageQueryMESA(dpy, image, fourcc, num_planes, modifiers)); ++ } ++ EGLBoolean fExportDMABUFImage(EGLDisplay dpy, EGLImage image, int* fds, ++ EGLint* strides, EGLint* offsets) { ++ WRAP(fExportDMABUFImageMESA(dpy, image, fds, strides, offsets)); ++ } ++ ++#undef WRAP + + #undef WRAP + #undef PROFILE_CALL + #undef BEFORE_CALL + #undef AFTER_CALL +@@ -593,10 +609,22 @@ + EGLBoolean(GLAPIENTRY* fSetDamageRegion)(EGLDisplay dpy, EGLSurface surface, + const EGLint* rects, + EGLint n_rects); + EGLClientBuffer(GLAPIENTRY* fGetNativeClientBufferANDROID)( + const struct AHardwareBuffer* buffer); ++ ++ // EGL_MESA_image_dma_buf_export ++ EGLBoolean(GLAPIENTRY* fExportDMABUFImageQueryMESA)(EGLDisplay dpy, ++ EGLImage image, ++ int* fourcc, ++ int* num_planes, ++ uint64_t* modifiers); ++ EGLBoolean(GLAPIENTRY* fExportDMABUFImageMESA)(EGLDisplay dpy, ++ EGLImage image, int* fds, ++ EGLint* strides, ++ EGLint* offsets); ++ + } mSymbols = {}; + }; + + class EglDisplay final { + public: +@@ -852,10 +880,23 @@ + EGLBoolean fSetDamageRegion(EGLSurface surface, const EGLint* rects, + EGLint n_rects) { + MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_partial_update)); + return mLib->fSetDamageRegion(mDisplay, surface, rects, n_rects); + } ++ ++ EGLBoolean fExportDMABUFImageQuery(EGLImage image, int* fourcc, ++ int* num_planes, ++ uint64_t* modifiers) const { ++ MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export)); ++ return mLib->fExportDMABUFImageQuery(mDisplay, image, fourcc, num_planes, ++ modifiers); ++ } ++ EGLBoolean fExportDMABUFImage(EGLImage image, int* fds, EGLint* strides, ++ EGLint* offsets) const { ++ MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export)); ++ return mLib->fExportDMABUFImage(mDisplay, image, fds, strides, offsets); ++ } + }; + + } /* namespace gl */ + } /* namespace mozilla */ + +diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp +--- a/gfx/gl/GLLibraryEGL.cpp ++++ b/gfx/gl/GLLibraryEGL.cpp +@@ -82,11 +82,14 @@ + "EGL_EXT_swap_buffers_with_damage", + "EGL_KHR_swap_buffers_with_damage", + "EGL_EXT_buffer_age", + "EGL_KHR_partial_update", + "EGL_NV_robustness_video_memory_purge", +- "EGL_MESA_platform_surfaceless"}; ++ "EGL_MESA_platform_surfaceless", ++ "EGL_EXT_image_dma_buf_import", ++ "EGL_EXT_image_dma_buf_import_modifiers", ++ "EGL_MESA_image_dma_buf_export"}; + + PRLibrary* LoadApitraceLibrary() { + const char* path = nullptr; + + #ifdef ANDROID +@@ -647,10 +650,16 @@ + { + const SymLoadStruct symbols[] = {SYMBOL(GetPlatformDisplay), + END_OF_SYMBOLS}; + (void)fnLoadSymbols(symbols); + } ++ { ++ const SymLoadStruct symbols[] = {SYMBOL(ExportDMABUFImageQueryMESA), ++ SYMBOL(ExportDMABUFImageMESA), ++ END_OF_SYMBOLS}; ++ (void)fnLoadSymbols(symbols); ++ } + + return true; + } + + // - + diff --git a/D147636.diff b/D147636.diff new file mode 100644 index 0000000..52462f2 --- /dev/null +++ b/D147636.diff @@ -0,0 +1,278 @@ +diff --git a/widget/gtk/DMABufSurface.h b/widget/gtk/DMABufSurface.h +--- a/widget/gtk/DMABufSurface.h ++++ b/widget/gtk/DMABufSurface.h +@@ -173,13 +173,13 @@ + SurfaceType mSurfaceType; + uint64_t mBufferModifiers[DMABUF_BUFFER_PLANES]; + + int mBufferPlaneCount; + int mDmabufFds[DMABUF_BUFFER_PLANES]; +- uint32_t mDrmFormats[DMABUF_BUFFER_PLANES]; +- uint32_t mStrides[DMABUF_BUFFER_PLANES]; +- uint32_t mOffsets[DMABUF_BUFFER_PLANES]; ++ int32_t mDrmFormats[DMABUF_BUFFER_PLANES]; ++ int32_t mStrides[DMABUF_BUFFER_PLANES]; ++ int32_t mOffsets[DMABUF_BUFFER_PLANES]; + + struct gbm_bo* mGbmBufferObject[DMABUF_BUFFER_PLANES]; + void* mMappedRegion[DMABUF_BUFFER_PLANES]; + void* mMappedRegionData[DMABUF_BUFFER_PLANES]; + uint32_t mMappedRegionStride[DMABUF_BUFFER_PLANES]; +@@ -198,10 +198,14 @@ + class DMABufSurfaceRGBA : public DMABufSurface { + public: + static already_AddRefed CreateDMABufSurface( + int aWidth, int aHeight, int aDMABufSurfaceFlags); + ++ static already_AddRefed CreateDMABufSurface( ++ mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, ++ int aWidth, int aHeight); ++ + bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor); + + DMABufSurfaceRGBA* GetAsDMABufSurfaceRGBA() { return this; } + + void Clear(); +@@ -247,10 +251,12 @@ + private: + ~DMABufSurfaceRGBA(); + + bool Create(int aWidth, int aHeight, int aDMABufSurfaceFlags); + bool Create(const mozilla::layers::SurfaceDescriptor& aDesc); ++ bool Create(mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, ++ int aWidth, int aHeight); + + bool ImportSurfaceDescriptor(const mozilla::layers::SurfaceDescriptor& aDesc); + + bool OpenFileDescriptorForPlane(const mozilla::MutexAutoLock& aProofOfLock, + int aPlane); +diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp +--- a/widget/gtk/DMABufSurface.cpp ++++ b/widget/gtk/DMABufSurface.cpp +@@ -204,10 +204,12 @@ + } + } + + void DMABufSurface::FenceSet() { + if (!mGL || !mGL->MakeCurrent()) { ++ MOZ_DIAGNOSTIC_ASSERT(mGL, ++ "DMABufSurface::FenceSet(): missing GL context!"); + return; + } + const auto& gle = gl::GLContextEGL::Cast(mGL); + const auto& egl = gle->mEgl; + +@@ -228,21 +230,23 @@ + mGL->fFinish(); + } + + void DMABufSurface::FenceWait() { + if (!mGL || mSyncFd < 0) { ++ MOZ_DIAGNOSTIC_ASSERT(mGL, ++ "DMABufSurface::FenceWait() missing GL context!"); + return; + } + + const auto& gle = gl::GLContextEGL::Cast(mGL); + const auto& egl = gle->mEgl; + + const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, mSyncFd, + LOCAL_EGL_NONE}; + EGLSync sync = egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); + if (!sync) { +- MOZ_ASSERT(false, "Failed to create GLFence!"); ++ MOZ_ASSERT(false, "DMABufSurface::FenceWait(): Failed to create GLFence!"); + // We failed to create GLFence so clear mSyncFd to avoid another try. + close(mSyncFd); + mSyncFd = -1; + return; + } +@@ -338,17 +342,18 @@ + mGmbFormat = GetDMABufDevice()->GetGbmFormat(mSurfaceFlags & DMABUF_ALPHA); + if (!mGmbFormat) { + // Requested DRM format is not supported. + return false; + } ++ mDrmFormats[0] = mGmbFormat->mFormat; + + bool useModifiers = (aDMABufSurfaceFlags & DMABUF_USE_MODIFIERS) && + mGmbFormat->mModifiersCount > 0; + if (useModifiers) { + LOGDMABUF((" Creating with modifiers\n")); + mGbmBufferObject[0] = nsGbmLib::CreateWithModifiers( +- GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mGmbFormat->mFormat, ++ GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mDrmFormats[0], + mGmbFormat->mModifiers, mGmbFormat->mModifiersCount); + if (mGbmBufferObject[0]) { + mBufferModifiers[0] = nsGbmLib::GetModifier(mGbmBufferObject[0]); + } + } +@@ -356,11 +361,11 @@ + if (!mGbmBufferObject[0]) { + LOGDMABUF((" Creating without modifiers\n")); + mGbmBufferFlags = GBM_BO_USE_LINEAR; + mGbmBufferObject[0] = + nsGbmLib::Create(GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, +- mGmbFormat->mFormat, mGbmBufferFlags); ++ mDrmFormats[0], mGbmBufferFlags); + mBufferModifiers[0] = DRM_FORMAT_MOD_INVALID; + } + + if (!mGbmBufferObject[0]) { + LOGDMABUF((" Failed to create GbmBufferObject\n")); +@@ -386,22 +391,51 @@ + + LOGDMABUF((" Success\n")); + return true; + } + ++bool DMABufSurfaceRGBA::Create(mozilla::gl::GLContext* aGLContext, ++ const EGLImageKHR aEGLImage, int aWidth, ++ int aHeight) { ++ LOGDMABUF(("DMABufSurfaceRGBA::Create() from EGLImage UID = %d\n", mUID)); ++ if (!aGLContext) { ++ return false; ++ } ++ const auto& gle = gl::GLContextEGL::Cast(aGLContext); ++ const auto& egl = gle->mEgl; ++ ++ mGL = aGLContext; ++ mWidth = aWidth; ++ mHeight = aHeight; ++ mEGLImage = aEGLImage; ++ if (!egl->fExportDMABUFImageQuery(mEGLImage, mDrmFormats, &mBufferPlaneCount, ++ mBufferModifiers)) { ++ LOGDMABUF((" ExportDMABUFImageQueryMESA failed, quit\n")); ++ return false; ++ } ++ if (mBufferPlaneCount > DMABUF_BUFFER_PLANES) { ++ LOGDMABUF((" wrong plane count %d, quit\n", mBufferPlaneCount)); ++ return false; ++ } ++ if (!egl->fExportDMABUFImage(mEGLImage, mDmabufFds, mStrides, mOffsets)) { ++ LOGDMABUF((" ExportDMABUFImageMESA failed, quit\n")); ++ return false; ++ } ++ ++ LOGDMABUF((" imported size %d x %d format %x planes %d", mWidth, mHeight, ++ mDrmFormats[0], mBufferPlaneCount)); ++ return true; ++} ++ + bool DMABufSurfaceRGBA::ImportSurfaceDescriptor( + const SurfaceDescriptor& aDesc) { + const SurfaceDescriptorDMABuf& desc = aDesc.get_SurfaceDescriptorDMABuf(); + + mWidth = desc.width()[0]; + mHeight = desc.height()[0]; + mBufferModifiers[0] = desc.modifier()[0]; +- if (mBufferModifiers[0] != DRM_FORMAT_MOD_INVALID) { +- mGmbFormat = GetDMABufDevice()->GetExactGbmFormat(desc.format()[0]); +- } else { +- mDrmFormats[0] = desc.format()[0]; +- } ++ mDrmFormats[0] = desc.format()[0]; + mBufferPlaneCount = desc.fds().Length(); + mGbmBufferFlags = desc.flags(); + MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES); + mUID = desc.uid(); + +@@ -431,10 +465,12 @@ + + if (desc.refCount().Length() > 0) { + GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release()); + } + ++ LOGDMABUF((" imported size %d x %d format %x planes %d", mWidth, mHeight, ++ mDrmFormats[0], mBufferPlaneCount)); + return true; + } + + bool DMABufSurfaceRGBA::Create(const SurfaceDescriptor& aDesc) { + return ImportSurfaceDescriptor(aDesc); +@@ -460,11 +496,11 @@ + return false; + } + + width.AppendElement(mWidth); + height.AppendElement(mHeight); +- format.AppendElement(mGmbFormat->mFormat); ++ format.AppendElement(mDrmFormats[0]); + modifiers.AppendElement(mBufferModifiers[0]); + for (int i = 0; i < mBufferPlaneCount; i++) { + fds.AppendElement(ipc::FileDescriptor(mDmabufFds[i])); + strides.AppendElement(mStrides[i]); + offsets.AppendElement(mOffsets[i]); +@@ -486,23 +522,20 @@ + fenceFDs, mUID, refCountFDs); + return true; + } + + bool DMABufSurfaceRGBA::CreateTexture(GLContext* aGLContext, int aPlane) { ++ LOGDMABUF(("DMABufSurfaceRGBA::CreateTexture() UID %d\n", mUID)); + MOZ_ASSERT(!mEGLImage && !mTexture, "EGLImage is already created!"); + + nsTArray attribs; + attribs.AppendElement(LOCAL_EGL_WIDTH); + attribs.AppendElement(mWidth); + attribs.AppendElement(LOCAL_EGL_HEIGHT); + attribs.AppendElement(mHeight); + attribs.AppendElement(LOCAL_EGL_LINUX_DRM_FOURCC_EXT); +- if (mGmbFormat) { +- attribs.AppendElement(mGmbFormat->mFormat); +- } else { +- attribs.AppendElement(mDrmFormats[0]); +- } ++ attribs.AppendElement(mDrmFormats[0]); + #define ADD_PLANE_ATTRIBS(plane_idx) \ + { \ + attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_FD_EXT); \ + attribs.AppendElement(mDmabufFds[plane_idx]); \ + attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_OFFSET_EXT); \ +@@ -560,10 +593,11 @@ + + return true; + } + + void DMABufSurfaceRGBA::ReleaseTextures() { ++ LOGDMABUF(("DMABufSurfaceRGBA::ReleaseTextures() UID %d\n", mUID)); + FenceDelete(); + + if (!mTexture) { + return; + } +@@ -618,11 +652,11 @@ + zwp_linux_buffer_params_v1_add(params, mDmabufFds[0], 0, mOffsets[0], + mStrides[0], mBufferModifiers[0] >> 32, + mBufferModifiers[0] & 0xffffffff); + + mWlBuffer = zwp_linux_buffer_params_v1_create_immed( +- params, GetWidth(), GetHeight(), mGmbFormat->mFormat, 0); ++ params, GetWidth(), GetHeight(), mDrmFormats[0], 0); + + CloseFileDescriptors(lockFD); + + return mWlBuffer != nullptr; + } +@@ -806,10 +840,20 @@ + return nullptr; + } + return surf.forget(); + } + ++already_AddRefed DMABufSurfaceRGBA::CreateDMABufSurface( ++ mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, int aWidth, ++ int aHeight) { ++ RefPtr surf = new DMABufSurfaceRGBA(); ++ if (!surf->Create(aGLContext, aEGLImage, aWidth, aHeight)) { ++ return nullptr; ++ } ++ return surf.forget(); ++} ++ + already_AddRefed DMABufSurfaceYUV::CreateYUVSurface( + const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) { + RefPtr surf = new DMABufSurfaceYUV(); + LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n", + surf->GetUID())); + diff --git a/D147637.diff b/D147637.diff new file mode 100644 index 0000000..0a84b25 --- /dev/null +++ b/D147637.diff @@ -0,0 +1,113 @@ +diff -up firefox-101.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff firefox-101.0/gfx/gl/SharedSurfaceDMABUF.cpp +--- firefox-101.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/gl/SharedSurfaceDMABUF.cpp 2022-06-07 09:37:29.361992695 +0200 +@@ -12,22 +12,37 @@ + + namespace mozilla::gl { + ++static bool HasDmaBufExtensions(const GLContextEGL* gl) { ++ const auto& egl = *(gl->mEgl); ++ return egl.IsExtensionSupported(EGLExtension::EXT_image_dma_buf_import) && ++ egl.IsExtensionSupported( ++ EGLExtension::EXT_image_dma_buf_import_modifiers) && ++ egl.IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export); ++} ++ + /*static*/ + UniquePtr SharedSurface_DMABUF::Create( + const SharedSurfaceDesc& desc) { +- const auto flags = static_cast( +- DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); +- const RefPtr surface = DMABufSurfaceRGBA::CreateDMABufSurface( +- desc.size.width, desc.size.height, flags); +- if (!surface || !surface->CreateTexture(desc.gl)) { ++ const auto& gle = GLContextEGL::Cast(desc.gl); ++ const auto& context = gle->mContext; ++ const auto& egl = *(gle->mEgl); ++ ++ if (!HasDmaBufExtensions(gle)) { + return nullptr; + } + +- const auto tex = surface->GetTexture(); +- auto fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false, +- LOCAL_GL_TEXTURE_2D, tex); ++ auto fb = MozFramebuffer::Create(desc.gl, desc.size, 0, false); + if (!fb) return nullptr; + ++ const auto buffer = reinterpret_cast(fb->ColorTex()); ++ const auto image = ++ egl.fCreateImage(context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); ++ if (!image) return nullptr; ++ ++ const RefPtr surface = DMABufSurfaceRGBA::CreateDMABufSurface( ++ desc.gl, image, desc.size.width, desc.size.height); ++ if (!surface) return nullptr; ++ + return AsUnique(new SharedSurface_DMABUF(desc, std::move(fb), surface)); + } + +@@ -61,7 +76,7 @@ UniquePtr Surface + } + + auto dmabufFactory = MakeUnique(gl); +- if (dmabufFactory->CanCreateSurface()) { ++ if (dmabufFactory->CanCreateSurface(gl)) { + return dmabufFactory; + } + +@@ -71,8 +86,38 @@ UniquePtr Surface + return nullptr; + } + ++bool SurfaceFactory_DMABUF::CanCreateSurface(GLContext& gl) { ++ UniquePtr test = ++ CreateShared(gfx::IntSize(1, 1)); ++ if (!test) { ++ LOGDMABUF(( ++ "SurfaceFactory_DMABUF::CanCreateSurface() failed to create surface.")); ++ return false; ++ } ++ auto desc = test->ToSurfaceDescriptor(); ++ if (!desc) { ++ LOGDMABUF( ++ ("SurfaceFactory_DMABUF::CanCreateSurface() failed to serialize " ++ "surface.")); ++ return false; ++ } ++ RefPtr importedSurface = ++ DMABufSurface::CreateDMABufSurface(*desc); ++ if (!importedSurface) { ++ LOGDMABUF(( ++ "SurfaceFactory_DMABUF::CanCreateSurface() failed to import surface.")); ++ return false; ++ } ++ if (!importedSurface->CreateTexture(&gl)) { ++ LOGDMABUF( ++ ("SurfaceFactory_DMABUF::CanCreateSurface() failed to create texture " ++ "over surface.")); ++ return false; ++ } ++ return true; ++} ++ + SurfaceFactory_DMABUF::SurfaceFactory_DMABUF(GLContext& gl) + : SurfaceFactory({&gl, SharedSurfaceType::EGLSurfaceDMABUF, + layers::TextureType::DMABUF, true}) {} +- + } // namespace mozilla::gl +diff -up firefox-101.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff firefox-101.0/gfx/gl/SharedSurfaceDMABUF.h +--- firefox-101.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff 2022-06-07 09:31:23.678228010 +0200 ++++ firefox-101.0/gfx/gl/SharedSurfaceDMABUF.h 2022-06-07 09:36:39.691512555 +0200 +@@ -59,10 +59,7 @@ class SurfaceFactory_DMABUF : public Sur + return SharedSurface_DMABUF::Create(desc); + } + +- bool CanCreateSurface() { +- UniquePtr test = CreateShared(gfx::IntSize(1, 1)); +- return test != nullptr; +- } ++ bool CanCreateSurface(GLContext& gl); + }; + + } // namespace gl diff --git a/D147720.diff b/D147720.diff new file mode 100644 index 0000000..9287f44 --- /dev/null +++ b/D147720.diff @@ -0,0 +1,73 @@ +diff --git a/widget/gtk/DMABufSurface.h b/widget/gtk/DMABufSurface.h +--- a/widget/gtk/DMABufSurface.h ++++ b/widget/gtk/DMABufSurface.h +@@ -146,11 +146,16 @@ + DMABufSurface(SurfaceType aSurfaceType); + + protected: + virtual bool Create(const mozilla::layers::SurfaceDescriptor& aDesc) = 0; + ++ // Import global ref count from IPC by file descriptor. + void GlobalRefCountImport(int aFd); ++ // Export global ref count by file descriptor. This adds global ref count ++ // reference to the surface. ++ // It's used when dmabuf surface is shared with another process via. IPC. ++ int GlobalRefCountExport(); + void GlobalRefCountDelete(); + + void ReleaseDMABuf(); + + void* MapInternal(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight, +diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp +--- a/widget/gtk/DMABufSurface.cpp ++++ b/widget/gtk/DMABufSurface.cpp +@@ -105,11 +105,21 @@ + } + + void DMABufSurface::GlobalRefCountImport(int aFd) { + MOZ_ASSERT(!mGlobalRefCountFd); + mGlobalRefCountFd = aFd; +- GlobalRefAdd(); ++ MOZ_DIAGNOSTIC_ASSERT(IsGlobalRefSet(), ++ "We're importing unreferenced surface!"); ++} ++ ++int DMABufSurface::GlobalRefCountExport() { ++ if (mGlobalRefCountFd) { ++ MOZ_DIAGNOSTIC_ASSERT(IsGlobalRefSet(), ++ "We're exporting unreferenced surface!"); ++ GlobalRefAdd(); ++ } ++ return mGlobalRefCountFd; + } + + void DMABufSurface::GlobalRefCountDelete() { + if (mGlobalRefCountFd) { + GlobalRefRelease(); +@@ -475,11 +485,11 @@ + if (mSync) { + fenceFDs.AppendElement(ipc::FileDescriptor(mSyncFd)); + } + + if (mGlobalRefCountFd) { +- refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd)); ++ refCountFDs.AppendElement(ipc::FileDescriptor(GlobalRefCountExport())); + } + + aOutDescriptor = SurfaceDescriptorDMABuf( + mSurfaceType, modifiers, mGbmBufferFlags, fds, width, height, width, + height, format, strides, offsets, GetYUVColorSpace(), mColorRange, +@@ -1118,11 +1128,11 @@ + if (mSync) { + fenceFDs.AppendElement(ipc::FileDescriptor(mSyncFd)); + } + + if (mGlobalRefCountFd) { +- refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd)); ++ refCountFDs.AppendElement(ipc::FileDescriptor(GlobalRefCountExport())); + } + + aOutDescriptor = SurfaceDescriptorDMABuf( + mSurfaceType, modifiers, 0, fds, width, height, widthBytes, heightBytes, + format, strides, offsets, GetYUVColorSpace(), mColorRange, fenceFDs, mUID, + diff --git a/D147874.diff b/D147874.diff new file mode 100644 index 0000000..f0c57dd --- /dev/null +++ b/D147874.diff @@ -0,0 +1,64 @@ +diff -up firefox-101.0/gfx/thebes/gfxPlatformGtk.cpp.D147874.diff firefox-101.0/gfx/thebes/gfxPlatformGtk.cpp +--- firefox-101.0/gfx/thebes/gfxPlatformGtk.cpp.D147874.diff 2022-05-27 01:16:54.000000000 +0200 ++++ firefox-101.0/gfx/thebes/gfxPlatformGtk.cpp 2022-06-07 11:16:03.791419558 +0200 +@@ -233,13 +233,7 @@ void gfxPlatformGtk::InitDmabufConfig() + void gfxPlatformGtk::InitVAAPIConfig() { + FeatureState& feature = gfxConfig::GetFeature(Feature::VAAPI); + #ifdef MOZ_WAYLAND +- feature.DisableByDefault(FeatureStatus::Disabled, +- "VAAPI is disabled by default", +- "FEATURE_VAAPI_DISABLED"_ns); +- +- if (StaticPrefs::media_ffmpeg_vaapi_enabled()) { +- feature.UserForceEnable("Force enabled by pref"); +- } ++ feature.EnableByDefault(); + + nsCString failureId; + int32_t status; +@@ -253,6 +247,10 @@ void gfxPlatformGtk::InitVAAPIConfig() { + failureId); + } + ++ if (StaticPrefs::media_ffmpeg_vaapi_enabled()) { ++ feature.UserForceEnable("Force enabled by pref"); ++ } ++ + if (!gfxVars::UseEGL()) { + feature.ForceDisable(FeatureStatus::Unavailable, "Requires EGL", + "FEATURE_FAILURE_REQUIRES_EGL"_ns); +diff -up firefox-101.0/widget/gtk/GfxInfo.cpp.D147874.diff firefox-101.0/widget/gtk/GfxInfo.cpp +--- firefox-101.0/widget/gtk/GfxInfo.cpp.D147874.diff 2022-05-27 01:17:06.000000000 +0200 ++++ firefox-101.0/widget/gtk/GfxInfo.cpp 2022-06-07 09:52:54.416701418 +0200 +@@ -843,6 +843,31 @@ const nsTArray& GfxInfo:: + V(495, 44, 0, 0), "FEATURE_FAILURE_NO_GBM", "495.44.0"); + + //////////////////////////////////// ++ // FEATURE_VAAPI ++ APPEND_TO_DRIVER_BLOCKLIST_EXT( ++ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, ++ DesktopEnvironment::All, WindowProtocol::All, DriverVendor::MesaAll, ++ DeviceFamily::All, nsIGfxInfo::FEATURE_VAAPI, ++ nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN, ++ V(21, 0, 0, 0), "FEATURE_ROLLOUT_VAAPI_MESA", "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_VAAPI, ++ nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED, ++ V(0, 0, 0, 0), "FEATURE_FAILURE_VAAPI_NO_LINUX_NVIDIA", ""); ++ ++ // Disable on all AMD devices not using Mesa. ++ APPEND_TO_DRIVER_BLOCKLIST_EXT( ++ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, ++ DesktopEnvironment::All, WindowProtocol::All, DriverVendor::NonMesaAll, ++ DeviceFamily::AtiAll, nsIGfxInfo::FEATURE_VAAPI, ++ nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED, ++ V(0, 0, 0, 0), "FEATURE_FAILURE_VAAPI_NO_LINUX_AMD", ""); ++ ++ //////////////////////////////////// + // FEATURE_WEBRENDER_PARTIAL_PRESENT + APPEND_TO_DRIVER_BLOCKLIST_EXT( + OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, diff --git a/firefox.spec b/firefox.spec index 3206448..4d49292 100644 --- a/firefox.spec +++ b/firefox.spec @@ -163,7 +163,7 @@ ExcludeArch: aarch64 Summary: Mozilla Firefox Web browser Name: firefox Version: 101.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 @@ -244,6 +244,24 @@ Patch408: mozilla-1663844.patch Patch415: mozilla-1670333.patch Patch418: mozilla-1767946-profilemanagersize.patch +# VA-API fixes +Patch420: D144284.diff +Patch421: D147420.diff +Patch422: D147720.diff +Patch423: D147874.diff +Patch424: D146084.diff +Patch425: D146085.diff +Patch426: D146086.diff +Patch427: D146087.diff +Patch428: D145725.diff +Patch429: D145966.diff +Patch430: D145871.diff + +# NVIDIA mzbz#1735929 +Patch440: D147635.diff +Patch441: D147636.diff +Patch442: D147637.diff + # PGO/LTO patches Patch600: pgo.patch Patch602: mozilla-1516803.patch @@ -485,6 +503,26 @@ This package contains results of tests executed during build. %patch415 -p1 -b .1670333 %patch418 -p1 -b .mozilla-1767946-profilemanagersize +# VA-API fixes +%patch420 -p1 -b .D144284.diff +%patch421 -p1 -b .D147420.diff +%patch423 -p1 -b .D147874.diff +%patch424 -p1 -b .D146084.diff +%patch425 -p1 -b .D146085.diff +%patch426 -p1 -b .D146086.diff +%patch427 -p1 -b .D146087.diff +%patch428 -p1 -b .D145725.diff +%patch429 -p1 -b .D145966.diff +%patch430 -p1 -b .D145871.diff + +# NVIDIA mzbz#1735929 +%patch440 -p1 -b .D147635.diff +%patch441 -p1 -b .D147636.diff +%patch442 -p1 -b .D147637.diff + +# More VA-API fixes +%patch422 -p1 -b .D147720.diff + # PGO patches %if %{build_with_pgo} %if !%{build_with_clang} @@ -1057,6 +1095,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Tue Jun 7 2022 Martin Stransky - 101.0-2 +- Enabled VA-API by default (+ added VA-API fixes from upstream) +- Fixed WebGL performance on NVIDIA drivers (mzbz#1735929) + * Mon May 30 2022 Martin Stransky - 101.0-1 - Updated to 101.0 -- cgit