diff options
author | Martin Stransky <stransky@redhat.com> | 2022-06-07 11:19:41 +0200 |
---|---|---|
committer | Martin Stransky <stransky@redhat.com> | 2022-06-07 11:19:41 +0200 |
commit | 61879d2c53a0473a24b4a9a69fcedd1af8f74fdf (patch) | |
tree | d12a4530b17d4c7e0cde6ecb74aa5e47e5120477 | |
parent | Updated cbindgen to 0.23.0 (diff) | |
download | librewolf-fedora-ff-61879d2c53a0473a24b4a9a69fcedd1af8f74fdf.tar.gz librewolf-fedora-ff-61879d2c53a0473a24b4a9a69fcedd1af8f74fdf.tar.bz2 librewolf-fedora-ff-61879d2c53a0473a24b4a9a69fcedd1af8f74fdf.zip |
Enabled VA-API by default (+ added VA-API fixes from upstream), Fixed WebGL performance on NVIDIA drivers (mzbz#1735929)
-rw-r--r-- | D144284.diff | 77 | ||||
-rw-r--r-- | D145725.diff | 132 | ||||
-rw-r--r-- | D145871.diff | 140 | ||||
-rw-r--r-- | D145966.diff | 20 | ||||
-rw-r--r-- | D146084.diff | 17 | ||||
-rw-r--r-- | D146085.diff | 205 | ||||
-rw-r--r-- | D146086.diff | 65 | ||||
-rw-r--r-- | D146087.diff | 19 | ||||
-rw-r--r-- | D147420.diff | 179 | ||||
-rw-r--r-- | D147635.diff | 125 | ||||
-rw-r--r-- | D147636.diff | 278 | ||||
-rw-r--r-- | D147637.diff | 113 | ||||
-rw-r--r-- | D147720.diff | 73 | ||||
-rw-r--r-- | D147874.diff | 64 | ||||
-rw-r--r-- | firefox.spec | 44 |
15 files changed, 1550 insertions, 1 deletions
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<GLContext> sSnapshotContext; + static StaticMutex sSnapshotContextMutex MOZ_UNANNOTATED; + + already_AddRefed<gfx::SourceSurface> 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<GLContext> sSnapshotContext; ++static StaticMutex sSnapshotContextMutex MOZ_UNANNOTATED; + static Atomic<int> 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<AVCodecID> mAcceleratedFormats; + #endif + RefPtr<KnowsCompositor> mImageAllocator; + RefPtr<ImageContainer> 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<LIBAV_VER>::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<LIBAV_VER>::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<ImageContainer> 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<LIBAV_VER>::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<LIBAV_VER>::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<DMABufSurfaceYUV> CreateYUVSurface( + int aWidth, int aHeight, void** aPixelData = nullptr, + int* aLineSizes = nullptr); + + static already_AddRefed<DMABufSurfaceYUV> 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> DMABufSurfaceYUV::CreateYUVSurface( +- const VADRMPRIMESurfaceDescriptor& aDesc) { ++ const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) { + RefPtr<DMABufSurfaceYUV> 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<uint32_t, DMABUF_BUFFER_PLANES> width; + AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> height; ++ AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> widthBytes; ++ AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> heightBytes; + AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> format; + AutoTArray<ipc::FileDescriptor, DMABUF_BUFFER_PLANES> fds; + AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> strides; + AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> offsets; + AutoTArray<uint64_t, DMABUF_BUFFER_PLANES> 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<EGLint> 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<VideoFrameSurface<LIBAV_VER>> 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<VideoFrameSurface<LIBAV_VER>> 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<VideoFrameSurface<LIBAV_VER>> + VideoFramePool<LIBAV_VER>::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<VideoFrameSurface<LIBAV_VER>> videoSurface = + GetFreeVideoFrameSurface(); + if (!videoSurface) { + RefPtr<DMABufSurfaceYUV> 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<VideoFrameSurface<LIBAV_VER>> surf = +@@ -142,11 +143,11 @@ + } + videoSurface = surf; + mDMABufSurfaces.AppendElement(std::move(surf)); + } else { + RefPtr<DMABufSurfaceYUV> 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<GLContextEGL> CreateEGLPBufferOffscreenContextImpl( + std::shared_ptr<EglDisplay>, const GLContextCreateDesc&, + const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId); ++ static RefPtr<GLContextEGL> CreateEGLSurfacelessContext( ++ const std::shared_ptr<EglDisplay> 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> GLContextEGL::Creat + } + + /*static*/ ++RefPtr<GLContextEGL> GLContextEGL::CreateEGLSurfacelessContext( ++ const std::shared_ptr<EglDisplay> display, const GLContextCreateDesc& desc, ++ nsACString* const out_failureId) { ++ const EGLConfig config = {}; ++ auto fullDesc = GLContextDesc{desc}; ++ fullDesc.isOffscreen = true; ++ RefPtr<GLContextEGL> 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<GLContext> 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<GLContextEGL> 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<EglDisplay> GetAn + return EglDisplay::Create(egl, display, false, aProofOfLock); + } + ++#ifdef MOZ_WAYLAND ++static std::shared_ptr<EglDisplay> 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<EglDisplay> 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<EglDisplay> 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<EglDisplay> 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<DMABufSurfaceRGBA> CreateDMABufSurface( + int aWidth, int aHeight, int aDMABufSurfaceFlags); + ++ static already_AddRefed<DMABufSurface> 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<EGLint> 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<DMABufSurface> DMABufSurfaceRGBA::CreateDMABufSurface( ++ mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, int aWidth, ++ int aHeight) { ++ RefPtr<DMABufSurfaceRGBA> surf = new DMABufSurfaceRGBA(); ++ if (!surf->Create(aGLContext, aEGLImage, aWidth, aHeight)) { ++ return nullptr; ++ } ++ return surf.forget(); ++} ++ + already_AddRefed<DMABufSurfaceYUV> DMABufSurfaceYUV::CreateYUVSurface( + const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) { + RefPtr<DMABufSurfaceYUV> 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> SharedSurface_DMABUF::Create( + const SharedSurfaceDesc& desc) { +- const auto flags = static_cast<DMABufSurfaceFlags>( +- DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); +- const RefPtr<DMABufSurface> 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<EGLClientBuffer>(fb->ColorTex()); ++ const auto image = ++ egl.fCreateImage(context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); ++ if (!image) return nullptr; ++ ++ const RefPtr<DMABufSurface> 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<SurfaceFactory_DMABUF> Surface + } + + auto dmabufFactory = MakeUnique<SurfaceFactory_DMABUF>(gl); +- if (dmabufFactory->CanCreateSurface()) { ++ if (dmabufFactory->CanCreateSurface(gl)) { + return dmabufFactory; + } + +@@ -71,8 +86,38 @@ UniquePtr<SurfaceFactory_DMABUF> Surface + return nullptr; + } + ++bool SurfaceFactory_DMABUF::CanCreateSurface(GLContext& gl) { ++ UniquePtr<SharedSurface> 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<DMABufSurface> 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<SharedSurface> 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<GfxDriverInfo>& 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 <stransky@redhat.com>- 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 <stransky@redhat.com>- 101.0-1 - Updated to 101.0 |