Drop unused patches
This commit is contained in:
		
							parent
							
								
									1ad3bd1b24
								
							
						
					
					
						commit
						594959d6f8
					
				
							
								
								
									
										140
									
								
								D145871.diff
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								D145871.diff
									
									
									
									
									
								
							| @ -1,140 +0,0 @@ | |||||||
| 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)) { |  | ||||||
| 
 |  | ||||||
							
								
								
									
										20
									
								
								D145966.diff
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								D145966.diff
									
									
									
									
									
								
							| @ -1,20 +0,0 @@ | |||||||
| 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( |  | ||||||
| 
 |  | ||||||
							
								
								
									
										94
									
								
								D146271.diff
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								D146271.diff
									
									
									
									
									
								
							| @ -1,94 +0,0 @@ | |||||||
| diff -up firefox-101.0/security/sandbox/linux/SandboxFilter.cpp.D146271.diff firefox-101.0/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| --- firefox-101.0/security/sandbox/linux/SandboxFilter.cpp.D146271.diff	2022-05-27 01:16:59.000000000 +0200
 |  | ||||||
| +++ firefox-101.0/security/sandbox/linux/SandboxFilter.cpp	2022-06-09 09:59:35.569235176 +0200
 |  | ||||||
| @@ -125,28 +125,12 @@ namespace mozilla {
 |  | ||||||
|  // denied if no broker client is provided by the concrete class. |  | ||||||
|  class SandboxPolicyCommon : public SandboxPolicyBase { |  | ||||||
|   protected: |  | ||||||
| -  enum class ShmemUsage : uint8_t {
 |  | ||||||
| -    MAY_CREATE,
 |  | ||||||
| -    ONLY_USE,
 |  | ||||||
| -  };
 |  | ||||||
| -
 |  | ||||||
| -  enum class AllowUnsafeSocketPair : uint8_t {
 |  | ||||||
| -    NO,
 |  | ||||||
| -    YES,
 |  | ||||||
| -  };
 |  | ||||||
| -
 |  | ||||||
| +  // Subclasses can assign these in their constructors to loosen the
 |  | ||||||
| +  // default settings.
 |  | ||||||
|    SandboxBrokerClient* mBroker = nullptr; |  | ||||||
|    bool mMayCreateShmem = false; |  | ||||||
|    bool mAllowUnsafeSocketPair = false; |  | ||||||
|   |  | ||||||
| -  explicit SandboxPolicyCommon(SandboxBrokerClient* aBroker,
 |  | ||||||
| -                               ShmemUsage aShmemUsage,
 |  | ||||||
| -                               AllowUnsafeSocketPair aAllowUnsafeSocketPair)
 |  | ||||||
| -      : mBroker(aBroker),
 |  | ||||||
| -        mMayCreateShmem(aShmemUsage == ShmemUsage::MAY_CREATE),
 |  | ||||||
| -        mAllowUnsafeSocketPair(aAllowUnsafeSocketPair ==
 |  | ||||||
| -                               AllowUnsafeSocketPair::YES) {}
 |  | ||||||
| -
 |  | ||||||
|    SandboxPolicyCommon() = default; |  | ||||||
|   |  | ||||||
|    typedef const sandbox::arch_seccomp_data& ArgsRef; |  | ||||||
| @@ -1228,11 +1212,13 @@ class ContentSandboxPolicy : public Sand
 |  | ||||||
|   public: |  | ||||||
|    ContentSandboxPolicy(SandboxBrokerClient* aBroker, |  | ||||||
|                         ContentProcessSandboxParams&& aParams) |  | ||||||
| -      : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
 |  | ||||||
| -                            AllowUnsafeSocketPair::YES),
 |  | ||||||
| -        mParams(std::move(aParams)),
 |  | ||||||
| +      : mParams(std::move(aParams)),
 |  | ||||||
|          mAllowSysV(PR_GetEnv("MOZ_SANDBOX_ALLOW_SYSV") != nullptr), |  | ||||||
| -        mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) {}
 |  | ||||||
| +        mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) {
 |  | ||||||
| +    mBroker = aBroker;
 |  | ||||||
| +    mMayCreateShmem = true;
 |  | ||||||
| +    mAllowUnsafeSocketPair = true;
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    ~ContentSandboxPolicy() override = default; |  | ||||||
|   |  | ||||||
| @@ -1762,9 +1748,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetM
 |  | ||||||
|  // segments, so it may need file brokering. |  | ||||||
|  class RDDSandboxPolicy final : public SandboxPolicyCommon { |  | ||||||
|   public: |  | ||||||
| -  explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker)
 |  | ||||||
| -      : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
 |  | ||||||
| -                            AllowUnsafeSocketPair::NO) {}
 |  | ||||||
| +  explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker) {
 |  | ||||||
| +    mBroker = aBroker;
 |  | ||||||
| +    mMayCreateShmem = true;
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|  #ifndef ANDROID |  | ||||||
|    Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const override { |  | ||||||
| @@ -1875,9 +1862,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetD
 |  | ||||||
|  // the SocketProcess sandbox looks like. |  | ||||||
|  class SocketProcessSandboxPolicy final : public SandboxPolicyCommon { |  | ||||||
|   public: |  | ||||||
| -  explicit SocketProcessSandboxPolicy(SandboxBrokerClient* aBroker)
 |  | ||||||
| -      : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
 |  | ||||||
| -                            AllowUnsafeSocketPair::NO) {}
 |  | ||||||
| +  explicit SocketProcessSandboxPolicy(SandboxBrokerClient* aBroker) {
 |  | ||||||
| +    mBroker = aBroker;
 |  | ||||||
| +    mMayCreateShmem = true;
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    static intptr_t FcntlTrap(const sandbox::arch_seccomp_data& aArgs, |  | ||||||
|                              void* aux) { |  | ||||||
| @@ -2013,9 +2001,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetS
 |  | ||||||
|   |  | ||||||
|  class UtilitySandboxPolicy : public SandboxPolicyCommon { |  | ||||||
|   public: |  | ||||||
| -  explicit UtilitySandboxPolicy(SandboxBrokerClient* aBroker)
 |  | ||||||
| -      : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
 |  | ||||||
| -                            AllowUnsafeSocketPair::NO) {}
 |  | ||||||
| +  explicit UtilitySandboxPolicy(SandboxBrokerClient* aBroker) {
 |  | ||||||
| +    mBroker = aBroker;
 |  | ||||||
| +    mMayCreateShmem = true;
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    ResultExpr PrctlPolicy() const override { |  | ||||||
|      Arg<int> op(0); |  | ||||||
							
								
								
									
										373
									
								
								D146272.diff
									
									
									
									
									
								
							
							
						
						
									
										373
									
								
								D146272.diff
									
									
									
									
									
								
							| @ -1,373 +0,0 @@ | |||||||
| diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| --- a/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| +++ b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| @@ -128,10 +128,11 @@
 |  | ||||||
|    // Subclasses can assign these in their constructors to loosen the |  | ||||||
|    // default settings. |  | ||||||
|    SandboxBrokerClient* mBroker = nullptr; |  | ||||||
|    bool mMayCreateShmem = false; |  | ||||||
|    bool mAllowUnsafeSocketPair = false; |  | ||||||
| +  bool mBrokeredConnect = false;  // Can connect() be brokered?
 |  | ||||||
|   |  | ||||||
|    SandboxPolicyCommon() = default; |  | ||||||
|   |  | ||||||
|    typedef const sandbox::arch_seccomp_data& ArgsRef; |  | ||||||
|   |  | ||||||
| @@ -533,10 +534,124 @@
 |  | ||||||
|      MOZ_CRASH("unreachable?"); |  | ||||||
|      return -ENOSYS; |  | ||||||
|  #endif |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| +  // This just needs to return something to stand in for the
 |  | ||||||
| +  // unconnected socket until ConnectTrap, below, and keep track of
 |  | ||||||
| +  // the socket type somehow.  Half a socketpair *is* a socket, so it
 |  | ||||||
| +  // should result in minimal confusion in the caller.
 |  | ||||||
| +  static intptr_t FakeSocketTrapCommon(int domain, int type, int protocol) {
 |  | ||||||
| +    int fds[2];
 |  | ||||||
| +    // X11 client libs will still try to getaddrinfo() even for a
 |  | ||||||
| +    // local connection.  Also, WebRTC still has vestigial network
 |  | ||||||
| +    // code trying to do things in the content process.  Politely tell
 |  | ||||||
| +    // them no.
 |  | ||||||
| +    if (domain != AF_UNIX) {
 |  | ||||||
| +      return -EAFNOSUPPORT;
 |  | ||||||
| +    }
 |  | ||||||
| +    if (socketpair(domain, type, protocol, fds) != 0) {
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    close(fds[1]);
 |  | ||||||
| +    return fds[0];
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  static intptr_t FakeSocketTrap(ArgsRef aArgs, void* aux) {
 |  | ||||||
| +    return FakeSocketTrapCommon(static_cast<int>(aArgs.args[0]),
 |  | ||||||
| +                                static_cast<int>(aArgs.args[1]),
 |  | ||||||
| +                                static_cast<int>(aArgs.args[2]));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  static intptr_t FakeSocketTrapLegacy(ArgsRef aArgs, void* aux) {
 |  | ||||||
| +    const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
 |  | ||||||
| +
 |  | ||||||
| +    return FakeSocketTrapCommon(static_cast<int>(innerArgs[0]),
 |  | ||||||
| +                                static_cast<int>(innerArgs[1]),
 |  | ||||||
| +                                static_cast<int>(innerArgs[2]));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  static Maybe<int> DoGetSockOpt(int fd, int optname) {
 |  | ||||||
| +    int optval;
 |  | ||||||
| +    socklen_t optlen = sizeof(optval);
 |  | ||||||
| +
 |  | ||||||
| +    if (getsockopt(fd, SOL_SOCKET, optname, &optval, &optlen) != 0) {
 |  | ||||||
| +      return Nothing();
 |  | ||||||
| +    }
 |  | ||||||
| +    MOZ_RELEASE_ASSERT(static_cast<size_t>(optlen) == sizeof(optval));
 |  | ||||||
| +    return Some(optval);
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  // Substitute the newly connected socket from the broker for the
 |  | ||||||
| +  // original socket.  This is meant to be used on a fd from
 |  | ||||||
| +  // FakeSocketTrap, above, but it should also work to simulate
 |  | ||||||
| +  // re-connect()ing a real connected socket.
 |  | ||||||
| +  //
 |  | ||||||
| +  // Warning: This isn't quite right if the socket is dup()ed, because
 |  | ||||||
| +  // other duplicates will still be the original socket, but hopefully
 |  | ||||||
| +  // nothing we're dealing with does that.
 |  | ||||||
| +  static intptr_t ConnectTrapCommon(SandboxBrokerClient* aBroker, int aFd,
 |  | ||||||
| +                                    const struct sockaddr_un* aAddr,
 |  | ||||||
| +                                    socklen_t aLen) {
 |  | ||||||
| +    if (aFd < 0) {
 |  | ||||||
| +      return -EBADF;
 |  | ||||||
| +    }
 |  | ||||||
| +    const auto maybeDomain = DoGetSockOpt(aFd, SO_DOMAIN);
 |  | ||||||
| +    if (!maybeDomain) {
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    if (*maybeDomain != AF_UNIX) {
 |  | ||||||
| +      return -EAFNOSUPPORT;
 |  | ||||||
| +    }
 |  | ||||||
| +    const auto maybeType = DoGetSockOpt(aFd, SO_TYPE);
 |  | ||||||
| +    if (!maybeType) {
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    const int oldFlags = fcntl(aFd, F_GETFL);
 |  | ||||||
| +    if (oldFlags == -1) {
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    const int newFd = aBroker->Connect(aAddr, aLen, *maybeType);
 |  | ||||||
| +    if (newFd < 0) {
 |  | ||||||
| +      return newFd;
 |  | ||||||
| +    }
 |  | ||||||
| +    // Copy over the nonblocking flag.  The connect() won't be
 |  | ||||||
| +    // nonblocking in that case, but that shouldn't matter for
 |  | ||||||
| +    // AF_UNIX.  The other fcntl-settable flags are either irrelevant
 |  | ||||||
| +    // for sockets (e.g., O_APPEND) or would be blocked by this
 |  | ||||||
| +    // seccomp-bpf policy, so they're ignored.
 |  | ||||||
| +    if (fcntl(newFd, F_SETFL, oldFlags & O_NONBLOCK) != 0) {
 |  | ||||||
| +      close(newFd);
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    if (dup2(newFd, aFd) < 0) {
 |  | ||||||
| +      close(newFd);
 |  | ||||||
| +      return -errno;
 |  | ||||||
| +    }
 |  | ||||||
| +    close(newFd);
 |  | ||||||
| +    return 0;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  static intptr_t ConnectTrap(ArgsRef aArgs, void* aux) {
 |  | ||||||
| +    typedef const struct sockaddr_un* AddrPtr;
 |  | ||||||
| +
 |  | ||||||
| +    return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
 |  | ||||||
| +                             static_cast<int>(aArgs.args[0]),
 |  | ||||||
| +                             reinterpret_cast<AddrPtr>(aArgs.args[1]),
 |  | ||||||
| +                             static_cast<socklen_t>(aArgs.args[2]));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  static intptr_t ConnectTrapLegacy(ArgsRef aArgs, void* aux) {
 |  | ||||||
| +    const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
 |  | ||||||
| +    typedef const struct sockaddr_un* AddrPtr;
 |  | ||||||
| +
 |  | ||||||
| +    return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
 |  | ||||||
| +                             static_cast<int>(innerArgs[0]),
 |  | ||||||
| +                             reinterpret_cast<AddrPtr>(innerArgs[1]),
 |  | ||||||
| +                             static_cast<socklen_t>(innerArgs[2]));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
|   public: |  | ||||||
|    ResultExpr InvalidSyscall() const override { |  | ||||||
|      return Trap(BlockedSyscallTrap, nullptr); |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| @@ -630,15 +745,37 @@
 |  | ||||||
|            return Some(Allow()); |  | ||||||
|          } |  | ||||||
|          Arg<int> level(1), optname(2); |  | ||||||
|          // SO_SNDBUF is used by IPC to avoid constructing |  | ||||||
|          // unnecessarily large gather arrays for `sendmsg`. |  | ||||||
| -        return Some(
 |  | ||||||
| -            If(AllOf(level == SOL_SOCKET, optname == SO_SNDBUF), Allow())
 |  | ||||||
| -                .Else(InvalidSyscall()));
 |  | ||||||
| +        //
 |  | ||||||
| +        // SO_DOMAIN and SO_TYPE are needed for connect() brokering,
 |  | ||||||
| +        // but they're harmless even when it's not enabled.
 |  | ||||||
| +        return Some(If(AllOf(level == SOL_SOCKET,
 |  | ||||||
| +                             AnyOf(optname == SO_SNDBUF, optname == SO_DOMAIN,
 |  | ||||||
| +                                   optname == SO_TYPE)),
 |  | ||||||
| +                       Allow())
 |  | ||||||
| +                        .Else(InvalidSyscall()));
 |  | ||||||
|        } |  | ||||||
|   |  | ||||||
| +        // These two cases are for connect() brokering, if enabled.
 |  | ||||||
| +      case SYS_SOCKET:
 |  | ||||||
| +        if (mBrokeredConnect) {
 |  | ||||||
| +          const auto trapFn = aHasArgs ? FakeSocketTrap : FakeSocketTrapLegacy;
 |  | ||||||
| +          MOZ_ASSERT(mBroker);
 |  | ||||||
| +          return Some(Trap(trapFn, mBroker));
 |  | ||||||
| +        }
 |  | ||||||
| +        return Nothing();
 |  | ||||||
| +
 |  | ||||||
| +      case SYS_CONNECT:
 |  | ||||||
| +        if (mBrokeredConnect) {
 |  | ||||||
| +          const auto trapFn = aHasArgs ? ConnectTrap : ConnectTrapLegacy;
 |  | ||||||
| +          MOZ_ASSERT(mBroker);
 |  | ||||||
| +          return Some(Trap(trapFn, mBroker));
 |  | ||||||
| +        }
 |  | ||||||
| +        return Nothing();
 |  | ||||||
| +
 |  | ||||||
|        default: |  | ||||||
|          return Nothing(); |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| @@ -1006,10 +1143,16 @@
 |  | ||||||
|          return If(AnyOf(request == TCGETS, request == TIOCGWINSZ), |  | ||||||
|                    Error(ENOTTY)) |  | ||||||
|              .Else(SandboxPolicyBase::EvaluateSyscall(sysno)); |  | ||||||
|        } |  | ||||||
|   |  | ||||||
| +      CASES_FOR_dup2:  // See ConnectTrapCommon
 |  | ||||||
| +        if (mBrokeredConnect) {
 |  | ||||||
| +          return Allow();
 |  | ||||||
| +        }
 |  | ||||||
| +        return SandboxPolicyBase::EvaluateSyscall(sysno);
 |  | ||||||
| +
 |  | ||||||
|  #ifdef MOZ_ASAN |  | ||||||
|          // ASAN's error reporter wants to know if stderr is a tty. |  | ||||||
|        case __NR_ioctl: { |  | ||||||
|          Arg<int> fd(0); |  | ||||||
|          return If(fd == STDERR_FILENO, Error(ENOTTY)).Else(InvalidSyscall()); |  | ||||||
| @@ -1093,133 +1236,20 @@
 |  | ||||||
|   |  | ||||||
|      close(fd); |  | ||||||
|      return rv; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  // This just needs to return something to stand in for the
 |  | ||||||
| -  // unconnected socket until ConnectTrap, below, and keep track of
 |  | ||||||
| -  // the socket type somehow.  Half a socketpair *is* a socket, so it
 |  | ||||||
| -  // should result in minimal confusion in the caller.
 |  | ||||||
| -  static intptr_t FakeSocketTrapCommon(int domain, int type, int protocol) {
 |  | ||||||
| -    int fds[2];
 |  | ||||||
| -    // X11 client libs will still try to getaddrinfo() even for a
 |  | ||||||
| -    // local connection.  Also, WebRTC still has vestigial network
 |  | ||||||
| -    // code trying to do things in the content process.  Politely tell
 |  | ||||||
| -    // them no.
 |  | ||||||
| -    if (domain != AF_UNIX) {
 |  | ||||||
| -      return -EAFNOSUPPORT;
 |  | ||||||
| -    }
 |  | ||||||
| -    if (socketpair(domain, type, protocol, fds) != 0) {
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    close(fds[1]);
 |  | ||||||
| -    return fds[0];
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  static intptr_t FakeSocketTrap(ArgsRef aArgs, void* aux) {
 |  | ||||||
| -    return FakeSocketTrapCommon(static_cast<int>(aArgs.args[0]),
 |  | ||||||
| -                                static_cast<int>(aArgs.args[1]),
 |  | ||||||
| -                                static_cast<int>(aArgs.args[2]));
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  static intptr_t FakeSocketTrapLegacy(ArgsRef aArgs, void* aux) {
 |  | ||||||
| -    const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
 |  | ||||||
| -
 |  | ||||||
| -    return FakeSocketTrapCommon(static_cast<int>(innerArgs[0]),
 |  | ||||||
| -                                static_cast<int>(innerArgs[1]),
 |  | ||||||
| -                                static_cast<int>(innerArgs[2]));
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  static Maybe<int> DoGetSockOpt(int fd, int optname) {
 |  | ||||||
| -    int optval;
 |  | ||||||
| -    socklen_t optlen = sizeof(optval);
 |  | ||||||
| -
 |  | ||||||
| -    if (getsockopt(fd, SOL_SOCKET, optname, &optval, &optlen) != 0) {
 |  | ||||||
| -      return Nothing();
 |  | ||||||
| -    }
 |  | ||||||
| -    MOZ_RELEASE_ASSERT(static_cast<size_t>(optlen) == sizeof(optval));
 |  | ||||||
| -    return Some(optval);
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  // Substitute the newly connected socket from the broker for the
 |  | ||||||
| -  // original socket.  This is meant to be used on a fd from
 |  | ||||||
| -  // FakeSocketTrap, above, but it should also work to simulate
 |  | ||||||
| -  // re-connect()ing a real connected socket.
 |  | ||||||
| -  //
 |  | ||||||
| -  // Warning: This isn't quite right if the socket is dup()ed, because
 |  | ||||||
| -  // other duplicates will still be the original socket, but hopefully
 |  | ||||||
| -  // nothing we're dealing with does that.
 |  | ||||||
| -  static intptr_t ConnectTrapCommon(SandboxBrokerClient* aBroker, int aFd,
 |  | ||||||
| -                                    const struct sockaddr_un* aAddr,
 |  | ||||||
| -                                    socklen_t aLen) {
 |  | ||||||
| -    if (aFd < 0) {
 |  | ||||||
| -      return -EBADF;
 |  | ||||||
| -    }
 |  | ||||||
| -    const auto maybeDomain = DoGetSockOpt(aFd, SO_DOMAIN);
 |  | ||||||
| -    if (!maybeDomain) {
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    if (*maybeDomain != AF_UNIX) {
 |  | ||||||
| -      return -EAFNOSUPPORT;
 |  | ||||||
| -    }
 |  | ||||||
| -    const auto maybeType = DoGetSockOpt(aFd, SO_TYPE);
 |  | ||||||
| -    if (!maybeType) {
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    const int oldFlags = fcntl(aFd, F_GETFL);
 |  | ||||||
| -    if (oldFlags == -1) {
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    const int newFd = aBroker->Connect(aAddr, aLen, *maybeType);
 |  | ||||||
| -    if (newFd < 0) {
 |  | ||||||
| -      return newFd;
 |  | ||||||
| -    }
 |  | ||||||
| -    // Copy over the nonblocking flag.  The connect() won't be
 |  | ||||||
| -    // nonblocking in that case, but that shouldn't matter for
 |  | ||||||
| -    // AF_UNIX.  The other fcntl-settable flags are either irrelevant
 |  | ||||||
| -    // for sockets (e.g., O_APPEND) or would be blocked by this
 |  | ||||||
| -    // seccomp-bpf policy, so they're ignored.
 |  | ||||||
| -    if (fcntl(newFd, F_SETFL, oldFlags & O_NONBLOCK) != 0) {
 |  | ||||||
| -      close(newFd);
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    if (dup2(newFd, aFd) < 0) {
 |  | ||||||
| -      close(newFd);
 |  | ||||||
| -      return -errno;
 |  | ||||||
| -    }
 |  | ||||||
| -    close(newFd);
 |  | ||||||
| -    return 0;
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  static intptr_t ConnectTrap(ArgsRef aArgs, void* aux) {
 |  | ||||||
| -    typedef const struct sockaddr_un* AddrPtr;
 |  | ||||||
| -
 |  | ||||||
| -    return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
 |  | ||||||
| -                             static_cast<int>(aArgs.args[0]),
 |  | ||||||
| -                             reinterpret_cast<AddrPtr>(aArgs.args[1]),
 |  | ||||||
| -                             static_cast<socklen_t>(aArgs.args[2]));
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
| -  static intptr_t ConnectTrapLegacy(ArgsRef aArgs, void* aux) {
 |  | ||||||
| -    const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
 |  | ||||||
| -    typedef const struct sockaddr_un* AddrPtr;
 |  | ||||||
| -
 |  | ||||||
| -    return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
 |  | ||||||
| -                             static_cast<int>(innerArgs[0]),
 |  | ||||||
| -                             reinterpret_cast<AddrPtr>(innerArgs[1]),
 |  | ||||||
| -                             static_cast<socklen_t>(innerArgs[2]));
 |  | ||||||
| -  }
 |  | ||||||
| -
 |  | ||||||
|   public: |  | ||||||
|    ContentSandboxPolicy(SandboxBrokerClient* aBroker, |  | ||||||
|                         ContentProcessSandboxParams&& aParams) |  | ||||||
|        : mParams(std::move(aParams)), |  | ||||||
|          mAllowSysV(PR_GetEnv("MOZ_SANDBOX_ALLOW_SYSV") != nullptr), |  | ||||||
|          mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) { |  | ||||||
|      mBroker = aBroker; |  | ||||||
|      mMayCreateShmem = true; |  | ||||||
|      mAllowUnsafeSocketPair = true; |  | ||||||
| +    mBrokeredConnect = true;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    ~ContentSandboxPolicy() override = default; |  | ||||||
|   |  | ||||||
|    Maybe<ResultExpr> EvaluateSocketCall(int aCall, |  | ||||||
| @@ -1232,18 +1262,16 @@
 |  | ||||||
|   |  | ||||||
|  #ifdef ANDROID |  | ||||||
|        case SYS_SOCKET: |  | ||||||
|          return Some(Error(EACCES)); |  | ||||||
|  #else  // #ifdef DESKTOP |  | ||||||
| -      case SYS_SOCKET: {
 |  | ||||||
| -        const auto trapFn = aHasArgs ? FakeSocketTrap : FakeSocketTrapLegacy;
 |  | ||||||
| -        return Some(AllowBelowLevel(4, Trap(trapFn, nullptr)));
 |  | ||||||
| -      }
 |  | ||||||
| -      case SYS_CONNECT: {
 |  | ||||||
| -        const auto trapFn = aHasArgs ? ConnectTrap : ConnectTrapLegacy;
 |  | ||||||
| -        return Some(AllowBelowLevel(4, Trap(trapFn, mBroker)));
 |  | ||||||
| -      }
 |  | ||||||
| +      case SYS_SOCKET:
 |  | ||||||
| +      case SYS_CONNECT:
 |  | ||||||
| +        if (BelowLevel(4)) {
 |  | ||||||
| +          return Some(Allow());
 |  | ||||||
| +        }
 |  | ||||||
| +        return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
 |  | ||||||
|        case SYS_RECV: |  | ||||||
|        case SYS_SEND: |  | ||||||
|        case SYS_GETSOCKOPT: |  | ||||||
|        case SYS_SETSOCKOPT: |  | ||||||
|        case SYS_GETSOCKNAME: |  | ||||||
| @@ -1458,13 +1486,10 @@
 |  | ||||||
|   |  | ||||||
|        case __NR_getrusage: |  | ||||||
|        case __NR_times: |  | ||||||
|          return Allow(); |  | ||||||
|   |  | ||||||
| -      CASES_FOR_dup2:  // See ConnectTrapCommon
 |  | ||||||
| -        return Allow();
 |  | ||||||
| -
 |  | ||||||
|        case __NR_fsync: |  | ||||||
|        case __NR_msync: |  | ||||||
|          return Allow(); |  | ||||||
|   |  | ||||||
|        case __NR_getpriority: |  | ||||||
| 
 |  | ||||||
							
								
								
									
										90
									
								
								D146273.diff
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								D146273.diff
									
									
									
									
									
								
							| @ -1,90 +0,0 @@ | |||||||
| diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| --- a/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| +++ b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| @@ -699,10 +699,18 @@
 |  | ||||||
|    Maybe<ResultExpr> EvaluateSocketCall(int aCall, |  | ||||||
|                                         bool aHasArgs) const override { |  | ||||||
|      switch (aCall) { |  | ||||||
|        case SYS_RECVMSG: |  | ||||||
|        case SYS_SENDMSG: |  | ||||||
| +        // These next four aren't needed for IPC or other core
 |  | ||||||
| +        // functionality at the time of this writing, but they're
 |  | ||||||
| +        // subsets of recvmsg/sendmsg so there's nothing gained by not
 |  | ||||||
| +        // allowing them here (and simplifying subclasses).
 |  | ||||||
| +      case SYS_RECVFROM:
 |  | ||||||
| +      case SYS_SENDTO:
 |  | ||||||
| +      case SYS_RECV:
 |  | ||||||
| +      case SYS_SEND:
 |  | ||||||
|          return Some(Allow()); |  | ||||||
|   |  | ||||||
|        case SYS_SOCKETPAIR: { |  | ||||||
|          // We try to allow "safe" (always connected) socketpairs when using the |  | ||||||
|          // file broker, or for content processes, but we may need to fall back |  | ||||||
| @@ -1253,12 +1261,10 @@
 |  | ||||||
|    ~ContentSandboxPolicy() override = default; |  | ||||||
|   |  | ||||||
|    Maybe<ResultExpr> EvaluateSocketCall(int aCall, |  | ||||||
|                                         bool aHasArgs) const override { |  | ||||||
|      switch (aCall) { |  | ||||||
| -      case SYS_RECVFROM:
 |  | ||||||
| -      case SYS_SENDTO:
 |  | ||||||
|        case SYS_SENDMMSG:  // libresolv via libasyncns; see bug 1355274 |  | ||||||
|          return Some(Allow()); |  | ||||||
|   |  | ||||||
|  #ifdef ANDROID |  | ||||||
|        case SYS_SOCKET: |  | ||||||
| @@ -1268,18 +1274,21 @@
 |  | ||||||
|        case SYS_CONNECT: |  | ||||||
|          if (BelowLevel(4)) { |  | ||||||
|            return Some(Allow()); |  | ||||||
|          } |  | ||||||
|          return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs); |  | ||||||
| -      case SYS_RECV:
 |  | ||||||
| -      case SYS_SEND:
 |  | ||||||
| +
 |  | ||||||
| +        // FIXME (bug 1761134): sockopts should be filtered
 |  | ||||||
|        case SYS_GETSOCKOPT: |  | ||||||
|        case SYS_SETSOCKOPT: |  | ||||||
| +        // These next 3 were needed for X11; they may not be needed
 |  | ||||||
| +        // with X11 lockdown, but there's not much attack surface here.
 |  | ||||||
|        case SYS_GETSOCKNAME: |  | ||||||
|        case SYS_GETPEERNAME: |  | ||||||
|        case SYS_SHUTDOWN: |  | ||||||
|          return Some(Allow()); |  | ||||||
| +
 |  | ||||||
|        case SYS_ACCEPT: |  | ||||||
|        case SYS_ACCEPT4: |  | ||||||
|          if (mUsingRenderDoc) { |  | ||||||
|            return Some(Allow()); |  | ||||||
|          } |  | ||||||
| @@ -1908,26 +1917,19 @@
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    Maybe<ResultExpr> EvaluateSocketCall(int aCall, |  | ||||||
|                                         bool aHasArgs) const override { |  | ||||||
|      switch (aCall) { |  | ||||||
| +      case SYS_SOCKET:
 |  | ||||||
| +      case SYS_CONNECT:
 |  | ||||||
|        case SYS_BIND: |  | ||||||
|          return Some(Allow()); |  | ||||||
|   |  | ||||||
| -      case SYS_SOCKET:
 |  | ||||||
| -        return Some(Allow());
 |  | ||||||
| -
 |  | ||||||
| -      case SYS_CONNECT:
 |  | ||||||
| -        return Some(Allow());
 |  | ||||||
| -
 |  | ||||||
| -      case SYS_RECVFROM:
 |  | ||||||
| -      case SYS_SENDTO:
 |  | ||||||
| +        // FIXME(bug 1641401) do we really need this?
 |  | ||||||
|        case SYS_SENDMMSG: |  | ||||||
|          return Some(Allow()); |  | ||||||
|   |  | ||||||
| -      case SYS_RECV:
 |  | ||||||
| -      case SYS_SEND:
 |  | ||||||
|        case SYS_GETSOCKOPT: |  | ||||||
|        case SYS_SETSOCKOPT: |  | ||||||
|        case SYS_GETSOCKNAME: |  | ||||||
|        case SYS_GETPEERNAME: |  | ||||||
|        case SYS_SHUTDOWN: |  | ||||||
| 
 |  | ||||||
							
								
								
									
										158
									
								
								D146274.diff
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								D146274.diff
									
									
									
									
									
								
							| @ -1,158 +0,0 @@ | |||||||
| diff --git a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| --- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| +++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| @@ -325,30 +325,84 @@
 |  | ||||||
|        policy->AddDynamic(perms, trimPath.get()); |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static void AddX11Dependencies(SandboxBroker::Policy* policy) {
 |  | ||||||
| +  // Allow Primus to contact the Bumblebee daemon to manage GPU
 |  | ||||||
| +  // switching on NVIDIA Optimus systems.
 |  | ||||||
| +  const char* bumblebeeSocket = PR_GetEnv("BUMBLEBEE_SOCKET");
 |  | ||||||
| +  if (bumblebeeSocket == nullptr) {
 |  | ||||||
| +    bumblebeeSocket = "/var/run/bumblebee.socket";
 |  | ||||||
| +  }
 |  | ||||||
| +  policy->AddPath(SandboxBroker::MAY_CONNECT, bumblebeeSocket);
 |  | ||||||
| +
 |  | ||||||
| +#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11)
 |  | ||||||
| +  // Allow local X11 connections, for several purposes:
 |  | ||||||
| +  //
 |  | ||||||
| +  // * for content processes to use WebGL when the browser is in headless
 |  | ||||||
| +  //   mode, by opening the X display if/when needed
 |  | ||||||
| +  //
 |  | ||||||
| +  // * if Primus or VirtualGL is used, to contact the secondary X server
 |  | ||||||
| +  static const bool kIsX11 =
 |  | ||||||
| +      !mozilla::widget::GdkIsWaylandDisplay() && PR_GetEnv("DISPLAY");
 |  | ||||||
| +  if (kIsX11) {
 |  | ||||||
| +    policy->AddPrefix(SandboxBroker::MAY_CONNECT, "/tmp/.X11-unix/X");
 |  | ||||||
| +    if (auto* const xauth = PR_GetEnv("XAUTHORITY")) {
 |  | ||||||
| +      policy->AddPath(rdonly, xauth);
 |  | ||||||
| +    } else if (auto* const home = PR_GetEnv("HOME")) {
 |  | ||||||
| +      // This follows the logic in libXau: append "/.Xauthority",
 |  | ||||||
| +      // even if $HOME ends in a slash, except in the special case
 |  | ||||||
| +      // where HOME=/ because POSIX allows implementations to treat
 |  | ||||||
| +      // an initial double slash specially.
 |  | ||||||
| +      nsAutoCString xauth(home);
 |  | ||||||
| +      if (xauth != "/"_ns) {
 |  | ||||||
| +        xauth.Append('/');
 |  | ||||||
| +      }
 |  | ||||||
| +      xauth.AppendLiteral(".Xauthority");
 |  | ||||||
| +      policy->AddPath(rdonly, xauth.get());
 |  | ||||||
| +    }
 |  | ||||||
| +  }
 |  | ||||||
| +#endif
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +static void AddGLDependencies(SandboxBroker::Policy* policy) {
 |  | ||||||
| +  // Devices
 |  | ||||||
| +  policy->AddDir(rdwr, "/dev/dri");
 |  | ||||||
| +  policy->AddFilePrefix(rdwr, "/dev", "nvidia");
 |  | ||||||
| +
 |  | ||||||
| +  // Hardware info
 |  | ||||||
| +  AddDriPaths(policy);
 |  | ||||||
| +
 |  | ||||||
| +  // /etc and /usr/share (glvnd, libdrm, drirc, ...?)
 |  | ||||||
| +  policy->AddDir(rdonly, "/etc");
 |  | ||||||
| +  policy->AddDir(rdonly, "/usr/share");
 |  | ||||||
| +  policy->AddDir(rdonly, "/usr/local/share");
 |  | ||||||
| +
 |  | ||||||
| +  // Note: This function doesn't do anything about Mesa's shader
 |  | ||||||
| +  // cache, because the details can vary by process type, including
 |  | ||||||
| +  // whether caching is enabled.
 |  | ||||||
| +
 |  | ||||||
| +  AddX11Dependencies(policy);
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  void SandboxBrokerPolicyFactory::InitContentPolicy() { |  | ||||||
|    const bool headless = |  | ||||||
|        StaticPrefs::security_sandbox_content_headless_AtStartup(); |  | ||||||
|   |  | ||||||
|    // Policy entries that are the same in every process go here, and |  | ||||||
|    // are cached over the lifetime of the factory. |  | ||||||
|    SandboxBroker::Policy* policy = new SandboxBroker::Policy; |  | ||||||
|    // Write permssions |  | ||||||
| -  //
 |  | ||||||
| -  if (!headless) {
 |  | ||||||
| -    // Bug 1308851: NVIDIA proprietary driver when using WebGL
 |  | ||||||
| -    policy->AddFilePrefix(rdwr, "/dev", "nvidia");
 |  | ||||||
| -
 |  | ||||||
| -    // Bug 1312678: Mesa with DRI when using WebGL
 |  | ||||||
| -    policy->AddDir(rdwr, "/dev/dri");
 |  | ||||||
| -  }
 |  | ||||||
|   |  | ||||||
|    // Bug 1575985: WASM library sandbox needs RW access to /dev/null |  | ||||||
|    policy->AddPath(rdwr, "/dev/null"); |  | ||||||
|   |  | ||||||
| +  if (!headless) {
 |  | ||||||
| +    AddGLDependencies(policy);
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
|    // Read permissions |  | ||||||
|    policy->AddPath(rdonly, "/dev/urandom"); |  | ||||||
|    policy->AddPath(rdonly, "/dev/random"); |  | ||||||
|    policy->AddPath(rdonly, "/proc/sys/crypto/fips_enabled"); |  | ||||||
|    policy->AddPath(rdonly, "/proc/cpuinfo"); |  | ||||||
| @@ -370,13 +424,10 @@
 |  | ||||||
|    policy->AddDir(rdonly, "/run/host/fonts"); |  | ||||||
|    policy->AddDir(rdonly, "/run/host/user-fonts"); |  | ||||||
|    policy->AddDir(rdonly, "/run/host/local-fonts"); |  | ||||||
|    policy->AddDir(rdonly, "/var/cache/fontconfig"); |  | ||||||
|   |  | ||||||
| -  if (!headless) {
 |  | ||||||
| -    AddDriPaths(policy);
 |  | ||||||
| -  }
 |  | ||||||
|    AddLdconfigPaths(policy); |  | ||||||
|    AddLdLibraryEnvPaths(policy); |  | ||||||
|   |  | ||||||
|    if (!headless) { |  | ||||||
|      // Bug 1385715: NVIDIA PRIME support |  | ||||||
| @@ -569,45 +620,11 @@
 |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|    if (!headless) { |  | ||||||
| -    // Allow Primus to contact the Bumblebee daemon to manage GPU
 |  | ||||||
| -    // switching on NVIDIA Optimus systems.
 |  | ||||||
| -    const char* bumblebeeSocket = PR_GetEnv("BUMBLEBEE_SOCKET");
 |  | ||||||
| -    if (bumblebeeSocket == nullptr) {
 |  | ||||||
| -      bumblebeeSocket = "/var/run/bumblebee.socket";
 |  | ||||||
| -    }
 |  | ||||||
| -    policy->AddPath(SandboxBroker::MAY_CONNECT, bumblebeeSocket);
 |  | ||||||
| -
 |  | ||||||
| -#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11)
 |  | ||||||
| -    // Allow local X11 connections, for several purposes:
 |  | ||||||
| -    //
 |  | ||||||
| -    // * for content processes to use WebGL when the browser is in headless
 |  | ||||||
| -    //   mode, by opening the X display if/when needed
 |  | ||||||
| -    //
 |  | ||||||
| -    // * if Primus or VirtualGL is used, to contact the secondary X server
 |  | ||||||
| -    static const bool kIsX11 =
 |  | ||||||
| -        !mozilla::widget::GdkIsWaylandDisplay() && PR_GetEnv("DISPLAY");
 |  | ||||||
| -    if (kIsX11) {
 |  | ||||||
| -      policy->AddPrefix(SandboxBroker::MAY_CONNECT, "/tmp/.X11-unix/X");
 |  | ||||||
| -      if (auto* const xauth = PR_GetEnv("XAUTHORITY")) {
 |  | ||||||
| -        policy->AddPath(rdonly, xauth);
 |  | ||||||
| -      } else if (auto* const home = PR_GetEnv("HOME")) {
 |  | ||||||
| -        // This follows the logic in libXau: append "/.Xauthority",
 |  | ||||||
| -        // even if $HOME ends in a slash, except in the special case
 |  | ||||||
| -        // where HOME=/ because POSIX allows implementations to treat
 |  | ||||||
| -        // an initial double slash specially.
 |  | ||||||
| -        nsAutoCString xauth(home);
 |  | ||||||
| -        if (xauth != "/"_ns) {
 |  | ||||||
| -          xauth.Append('/');
 |  | ||||||
| -        }
 |  | ||||||
| -        xauth.AppendLiteral(".Xauthority");
 |  | ||||||
| -        policy->AddPath(rdonly, xauth.get());
 |  | ||||||
| -      }
 |  | ||||||
| -    }
 |  | ||||||
| -#endif
 |  | ||||||
| +    AddX11Dependencies(policy);
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    // Bug 1732580: when packaged as a strictly confined snap, may need |  | ||||||
|    // read-access to configuration files under $SNAP/. |  | ||||||
|    const char* snap = PR_GetEnv("SNAP"); |  | ||||||
| 
 |  | ||||||
							
								
								
									
										125
									
								
								D146275.diff
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								D146275.diff
									
									
									
									
									
								
							| @ -1,125 +0,0 @@ | |||||||
| diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
 |  | ||||||
| --- a/ipc/glue/GeckoChildProcessHost.cpp
 |  | ||||||
| +++ b/ipc/glue/GeckoChildProcessHost.cpp
 |  | ||||||
| @@ -418,10 +418,17 @@
 |  | ||||||
|      nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR, |  | ||||||
|                                           getter_AddRefs(contentTempDir)); |  | ||||||
|      if (NS_SUCCEEDED(rv)) { |  | ||||||
|        contentTempDir->GetNativePath(mTmpDirName); |  | ||||||
|      } |  | ||||||
| +  } else if (aProcessType == GeckoProcessType_RDD) {
 |  | ||||||
| +    // The RDD process makes limited use of EGL.  If Mesa's shader
 |  | ||||||
| +    // cache is enabled and the directory isn't explicitly set, then
 |  | ||||||
| +    // it will try to getpwuid() the user which can cause problems
 |  | ||||||
| +    // with sandboxing.  Because we shouldn't need shader caching in
 |  | ||||||
| +    // this process, we just disable the cache to prevent that.
 |  | ||||||
| +    mLaunchOptions->env_map["MESA_GLSL_CACHE_DISABLE"] = "true";
 |  | ||||||
|    } |  | ||||||
|  #endif |  | ||||||
|  #if defined(MOZ_ENABLE_FORKSERVER) |  | ||||||
|    if (aProcessType == GeckoProcessType_Content && ForkServiceChild::Get()) { |  | ||||||
|      mLaunchOptions->use_forkserver = true; |  | ||||||
| diff --git a/security/sandbox/common/test/SandboxTestingChildTests.h b/security/sandbox/common/test/SandboxTestingChildTests.h
 |  | ||||||
| --- a/security/sandbox/common/test/SandboxTestingChildTests.h
 |  | ||||||
| +++ b/security/sandbox/common/test/SandboxTestingChildTests.h
 |  | ||||||
| @@ -21,14 +21,16 @@
 |  | ||||||
|  #    include <termios.h> |  | ||||||
|  #    include <sys/resource.h> |  | ||||||
|  #    include <sys/time.h> |  | ||||||
|  #    include <sys/utsname.h> |  | ||||||
|  #    include <sched.h> |  | ||||||
| +#    include <sys/socket.h>
 |  | ||||||
|  #    include <sys/syscall.h> |  | ||||||
|  #    include <sys/un.h> |  | ||||||
|  #    include <linux/mempolicy.h> |  | ||||||
|  #    include "mozilla/ProcInfo_linux.h" |  | ||||||
| +#    include "mozilla/UniquePtrExtensions.h"
 |  | ||||||
|  #    ifdef MOZ_X11 |  | ||||||
|  #      include "X11/Xlib.h" |  | ||||||
|  #      include "X11UndefineNone.h" |  | ||||||
|  #    endif  // MOZ_X11 |  | ||||||
|  #  endif    // XP_LINUX |  | ||||||
| @@ -595,12 +597,25 @@
 |  | ||||||
|      return rv; |  | ||||||
|    }); |  | ||||||
|   |  | ||||||
|    RunTestsSched(child); |  | ||||||
|   |  | ||||||
| -  child->ErrnoTest("socket"_ns, false,
 |  | ||||||
| -                   [] { return socket(AF_UNIX, SOCK_STREAM, 0); });
 |  | ||||||
| +  child->ErrnoTest("socket_inet"_ns, false,
 |  | ||||||
| +                   [] { return socket(AF_INET, SOCK_STREAM, 0); });
 |  | ||||||
| +
 |  | ||||||
| +  {
 |  | ||||||
| +    UniqueFileHandle fd(socket(AF_UNIX, SOCK_STREAM, 0));
 |  | ||||||
| +    child->ErrnoTest("socket_unix"_ns, true, [&] { return fd.get(); });
 |  | ||||||
| +
 |  | ||||||
| +    struct sockaddr_un sun {};
 |  | ||||||
| +    sun.sun_family = AF_UNIX;
 |  | ||||||
| +    strncpy(sun.sun_path, "/tmp/forbidden-sock", sizeof(sun.sun_path));
 |  | ||||||
| +
 |  | ||||||
| +    child->ErrnoValueTest("socket_unix_bind"_ns, ENOSYS, [&] {
 |  | ||||||
| +      return bind(fd.get(), (struct sockaddr*)&sun, sizeof(sun));
 |  | ||||||
| +    });
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    child->ErrnoTest("uname"_ns, true, [] { |  | ||||||
|      struct utsname uts; |  | ||||||
|      return uname(&uts); |  | ||||||
|    }); |  | ||||||
| diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| --- a/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| +++ b/security/sandbox/linux/SandboxFilter.cpp
 |  | ||||||
| @@ -1783,10 +1783,11 @@
 |  | ||||||
|  class RDDSandboxPolicy final : public SandboxPolicyCommon { |  | ||||||
|   public: |  | ||||||
|    explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker) { |  | ||||||
|      mBroker = aBroker; |  | ||||||
|      mMayCreateShmem = true; |  | ||||||
| +    mBrokeredConnect = true;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|  #ifndef ANDROID |  | ||||||
|    Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const override { |  | ||||||
|      // The Intel media driver uses SysV IPC (semaphores and shared |  | ||||||
| @@ -1818,15 +1819,15 @@
 |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|    Maybe<ResultExpr> EvaluateSocketCall(int aCall, |  | ||||||
|                                         bool aHasArgs) const override { |  | ||||||
|      switch (aCall) { |  | ||||||
| -      // Mesa can call getpwuid_r to get the home dir, which can try
 |  | ||||||
| -      // to connect to nscd (or maybe servers like NIS or LDAP); this
 |  | ||||||
| -      // can't be safely allowed, but we can quietly deny it.
 |  | ||||||
| -      case SYS_SOCKET:
 |  | ||||||
| -        return Some(Error(EACCES));
 |  | ||||||
| +      // These are for X11.
 |  | ||||||
| +      case SYS_GETSOCKNAME:
 |  | ||||||
| +      case SYS_GETPEERNAME:
 |  | ||||||
| +      case SYS_SHUTDOWN:
 |  | ||||||
| +        return Some(Allow());
 |  | ||||||
|   |  | ||||||
|        default: |  | ||||||
|          return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs); |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
| diff --git a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| --- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| +++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
 |  | ||||||
| @@ -853,13 +853,12 @@
 |  | ||||||
|      if (developer_repo_dir) { |  | ||||||
|        policy->AddDir(rdonly, developer_repo_dir); |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  // VA-API needs DRI and GPU detection
 |  | ||||||
| -  policy->AddDir(rdwr, "/dev/dri");
 |  | ||||||
| -  AddDriPaths(policy.get());
 |  | ||||||
| +  // VA-API needs GPU access and GL context creation
 |  | ||||||
| +  AddGLDependencies(policy.get());
 |  | ||||||
|   |  | ||||||
|    // FFmpeg and GPU drivers may need general-case library loading |  | ||||||
|    AddLdconfigPaths(policy.get()); |  | ||||||
|    AddLdLibraryEnvPaths(policy.get()); |  | ||||||
|   |  | ||||||
| 
 |  | ||||||
							
								
								
									
										125
									
								
								D147635.diff
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								D147635.diff
									
									
									
									
									
								
							| @ -1,125 +0,0 @@ | |||||||
| 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; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  // - |  | ||||||
| 
 |  | ||||||
							
								
								
									
										278
									
								
								D147636.diff
									
									
									
									
									
								
							
							
						
						
									
										278
									
								
								D147636.diff
									
									
									
									
									
								
							| @ -1,278 +0,0 @@ | |||||||
| 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())); |  | ||||||
| 
 |  | ||||||
							
								
								
									
										139
									
								
								D147637.diff
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								D147637.diff
									
									
									
									
									
								
							| @ -1,139 +0,0 @@ | |||||||
| diff -up firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp
 |  | ||||||
| --- firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff	2022-06-23 09:08:46.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp	2022-06-28 16:37:52.264835137 +0200
 |  | ||||||
| @@ -9,25 +9,58 @@
 |  | ||||||
|  #include "GLContextEGL.h" |  | ||||||
|  #include "MozFramebuffer.h" |  | ||||||
|  #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc |  | ||||||
| +#include "mozilla/gfx/gfxVars.h"
 |  | ||||||
|   |  | ||||||
|  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)) {
 |  | ||||||
| -    return nullptr;
 |  | ||||||
| +  const auto& gle = GLContextEGL::Cast(desc.gl);
 |  | ||||||
| +  const auto& context = gle->mContext;
 |  | ||||||
| +  const auto& egl = *(gle->mEgl);
 |  | ||||||
| +
 |  | ||||||
| +  RefPtr<DMABufSurface> surface;
 |  | ||||||
| +  UniquePtr<MozFramebuffer> fb;
 |  | ||||||
| +
 |  | ||||||
| +  if (!HasDmaBufExtensions(gle) || !gfx::gfxVars::UseDMABufSurfaceExport()) {
 |  | ||||||
| +    // Use MESA_image_dma_buf_export is not supported or it's broken.
 |  | ||||||
| +    // Create dmabuf surface directly via. GBM and create
 |  | ||||||
| +    // EGLImage/framebuffer over it.
 |  | ||||||
| +    const auto flags = static_cast<DMABufSurfaceFlags>(
 |  | ||||||
| +        DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA);
 |  | ||||||
| +    surface = DMABufSurfaceRGBA::CreateDMABufSurface(desc.size.width,
 |  | ||||||
| +                                                     desc.size.height, flags);
 |  | ||||||
| +    if (!surface || !surface->CreateTexture(desc.gl)) {
 |  | ||||||
| +      return nullptr;
 |  | ||||||
| +    }
 |  | ||||||
| +    const auto tex = surface->GetTexture();
 |  | ||||||
| +    fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false,
 |  | ||||||
| +                                          LOCAL_GL_TEXTURE_2D, tex);
 |  | ||||||
| +    if (!fb) return nullptr;
 |  | ||||||
| +  } else {
 |  | ||||||
| +    // Use MESA_image_dma_buf_export so create EGLImage/framebuffer directly
 |  | ||||||
| +    // and derive dmabuf from it.
 |  | ||||||
| +    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;
 |  | ||||||
| +
 |  | ||||||
| +    surface = DMABufSurfaceRGBA::CreateDMABufSurface(
 |  | ||||||
| +        desc.gl, image, desc.size.width, desc.size.height);
 |  | ||||||
| +    if (!surface) return nullptr;
 |  | ||||||
|    } |  | ||||||
| -
 |  | ||||||
| -  const auto tex = surface->GetTexture();
 |  | ||||||
| -  auto fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false,
 |  | ||||||
| -                                             LOCAL_GL_TEXTURE_2D, tex);
 |  | ||||||
| -  if (!fb) return nullptr;
 |  | ||||||
| -
 |  | ||||||
|    return AsUnique(new SharedSurface_DMABUF(desc, std::move(fb), surface)); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -61,7 +94,7 @@ UniquePtr<SurfaceFactory_DMABUF> Surface
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    auto dmabufFactory = MakeUnique<SurfaceFactory_DMABUF>(gl); |  | ||||||
| -  if (dmabufFactory->CanCreateSurface()) {
 |  | ||||||
| +  if (dmabufFactory->CanCreateSurface(gl)) {
 |  | ||||||
|      return dmabufFactory; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| @@ -71,8 +104,38 @@ UniquePtr<SurfaceFactory_DMABUF> Surface
 |  | ||||||
|    return nullptr; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +bool SurfaceFactory_DMABUF::CanCreateSurface(GLContext& gl) {
 |  | ||||||
| +  UniquePtr<SharedSurface> test =
 |  | ||||||
| +      CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB);
 |  | ||||||
| +  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-102.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h
 |  | ||||||
| --- firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff	2022-06-23 09:08:47.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h	2022-06-28 15:00:20.339991965 +0200
 |  | ||||||
| @@ -59,11 +59,7 @@ class SurfaceFactory_DMABUF : public Sur
 |  | ||||||
|      return SharedSurface_DMABUF::Create(desc); |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  bool CanCreateSurface() {
 |  | ||||||
| -    UniquePtr<SharedSurface> test =
 |  | ||||||
| -        CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB);
 |  | ||||||
| -    return test != nullptr;
 |  | ||||||
| -  }
 |  | ||||||
| +  bool CanCreateSurface(GLContext& gl);
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  }  // namespace gl |  | ||||||
							
								
								
									
										64
									
								
								D147874.diff
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								D147874.diff
									
									
									
									
									
								
							| @ -1,64 +0,0 @@ | |||||||
| 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, |  | ||||||
							
								
								
									
										250
									
								
								D148946.diff
									
									
									
									
									
								
							
							
						
						
									
										250
									
								
								D148946.diff
									
									
									
									
									
								
							| @ -1,250 +0,0 @@ | |||||||
| diff -up firefox-102.0/gfx/gl/GLContextProviderEGL.cpp.D148946.diff firefox-102.0/gfx/gl/GLContextProviderEGL.cpp
 |  | ||||||
| --- firefox-102.0/gfx/gl/GLContextProviderEGL.cpp.D148946.diff	2022-06-23 09:08:47.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/GLContextProviderEGL.cpp	2022-06-28 14:47:40.904700050 +0200
 |  | ||||||
| @@ -1182,42 +1182,16 @@ 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; |  | ||||||
|    } |  | ||||||
| -  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();
 |  | ||||||
| +  mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
 |  | ||||||
| +  auto ret = GLContextEGL::CreateEGLPBufferOffscreenContext(
 |  | ||||||
| +      display, desc, dummySize, out_failureId);
 |  | ||||||
| +  return ret.forget();
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  // Don't want a global context on Android as 1) share groups across 2 threads |  | ||||||
| diff -up firefox-102.0/gfx/gl/GLDefs.h.D148946.diff firefox-102.0/gfx/gl/GLDefs.h
 |  | ||||||
| --- firefox-102.0/gfx/gl/GLDefs.h.D148946.diff	2022-06-23 09:08:47.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/GLDefs.h	2022-06-28 14:47:40.904700050 +0200
 |  | ||||||
| @@ -104,9 +104,6 @@ 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-102.0/gfx/gl/GLLibraryEGL.cpp.D148946.diff firefox-102.0/gfx/gl/GLLibraryEGL.cpp
 |  | ||||||
| --- firefox-102.0/gfx/gl/GLLibraryEGL.cpp.D148946.diff	2022-06-28 14:47:40.900699918 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/GLLibraryEGL.cpp	2022-06-28 14:49:47.810911199 +0200
 |  | ||||||
| @@ -54,9 +54,15 @@ StaticRefPtr<GLLibraryEGL> GLLibraryEGL:
 |  | ||||||
|   |  | ||||||
|  // should match the order of EGLExtensions, and be null-terminated. |  | ||||||
|  static const char* sEGLLibraryExtensionNames[] = { |  | ||||||
| -    "EGL_ANDROID_get_native_client_buffer", "EGL_ANGLE_device_creation",
 |  | ||||||
| -    "EGL_ANGLE_device_creation_d3d11",      "EGL_ANGLE_platform_angle",
 |  | ||||||
| -    "EGL_ANGLE_platform_angle_d3d",         "EGL_EXT_device_query"};
 |  | ||||||
| +    "EGL_ANDROID_get_native_client_buffer",
 |  | ||||||
| +    "EGL_ANGLE_device_creation",
 |  | ||||||
| +    "EGL_ANGLE_device_creation_d3d11",
 |  | ||||||
| +    "EGL_ANGLE_platform_angle",
 |  | ||||||
| +    "EGL_ANGLE_platform_angle_d3d",
 |  | ||||||
| +    "EGL_EXT_device_enumeration",
 |  | ||||||
| +    "EGL_EXT_device_query",
 |  | ||||||
| +    "EGL_EXT_platform_device",
 |  | ||||||
| +    "EGL_MESA_platform_surfaceless"};
 |  | ||||||
|   |  | ||||||
|  // should match the order of EGLExtensions, and be null-terminated. |  | ||||||
|  static const char* sEGLExtensionNames[] = { |  | ||||||
| @@ -84,7 +90,6 @@ static const char* sEGLExtensionNames[]
 |  | ||||||
|      "EGL_EXT_buffer_age", |  | ||||||
|      "EGL_KHR_partial_update", |  | ||||||
|      "EGL_NV_robustness_video_memory_purge", |  | ||||||
| -    "EGL_MESA_platform_surfaceless",
 |  | ||||||
|      "EGL_EXT_image_dma_buf_import", |  | ||||||
|      "EGL_EXT_image_dma_buf_import_modifiers", |  | ||||||
|      "EGL_MESA_image_dma_buf_export"}; |  | ||||||
| @@ -157,8 +162,52 @@ static std::shared_ptr<EglDisplay> GetAn
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #ifdef MOZ_WAYLAND |  | ||||||
| +static std::shared_ptr<EglDisplay> GetAndInitDeviceDisplay(
 |  | ||||||
| +    GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) {
 |  | ||||||
| +  nsAutoCString drmRenderDevice(gfx::gfxVars::DrmRenderDevice());
 |  | ||||||
| +  if (drmRenderDevice.IsEmpty() ||
 |  | ||||||
| +      !egl.IsExtensionSupported(EGLLibExtension::EXT_platform_device) ||
 |  | ||||||
| +      !egl.IsExtensionSupported(EGLLibExtension::EXT_device_enumeration)) {
 |  | ||||||
| +    return nullptr;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  EGLint maxDevices;
 |  | ||||||
| +  if (!egl.fQueryDevicesEXT(0, nullptr, &maxDevices)) {
 |  | ||||||
| +    return nullptr;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  std::vector<EGLDeviceEXT> devices(maxDevices);
 |  | ||||||
| +  EGLint numDevices;
 |  | ||||||
| +  if (!egl.fQueryDevicesEXT(devices.size(), devices.data(), &numDevices)) {
 |  | ||||||
| +    return nullptr;
 |  | ||||||
| +  }
 |  | ||||||
| +  devices.resize(numDevices);
 |  | ||||||
| +
 |  | ||||||
| +  EGLDisplay display = EGL_NO_DISPLAY;
 |  | ||||||
| +  for (const auto& device : devices) {
 |  | ||||||
| +    const char* renderNodeString =
 |  | ||||||
| +        egl.fQueryDeviceStringEXT(device, LOCAL_EGL_DRM_RENDER_NODE_FILE_EXT);
 |  | ||||||
| +    if (renderNodeString &&
 |  | ||||||
| +        strcmp(renderNodeString, drmRenderDevice.get()) == 0) {
 |  | ||||||
| +      const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE};
 |  | ||||||
| +      display = egl.fGetPlatformDisplay(LOCAL_EGL_PLATFORM_DEVICE_EXT, device,
 |  | ||||||
| +                                        attrib_list);
 |  | ||||||
| +      break;
 |  | ||||||
| +    }
 |  | ||||||
| +  }
 |  | ||||||
| +  if (!display) {
 |  | ||||||
| +    return nullptr;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  return EglDisplay::Create(egl, display, true, aProofOfLock);
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  static std::shared_ptr<EglDisplay> GetAndInitSurfacelessDisplay( |  | ||||||
|      GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) { |  | ||||||
| +  if (!egl.IsExtensionSupported(EGLLibExtension::MESA_platform_surfaceless)) {
 |  | ||||||
| +    return nullptr;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
|    const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE}; |  | ||||||
|    const EGLDisplay display = egl.fGetPlatformDisplay( |  | ||||||
|        LOCAL_EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, attrib_list); |  | ||||||
| @@ -611,9 +660,9 @@ bool GLLibraryEGL::Init(nsACString* cons
 |  | ||||||
|      (void)fnLoadSymbols(symbols); |  | ||||||
|    } |  | ||||||
|    { |  | ||||||
| -    const SymLoadStruct symbols[] = {SYMBOL(QueryDisplayAttribEXT),
 |  | ||||||
| -                                     SYMBOL(QueryDeviceAttribEXT),
 |  | ||||||
| -                                     END_OF_SYMBOLS};
 |  | ||||||
| +    const SymLoadStruct symbols[] = {
 |  | ||||||
| +        SYMBOL(QueryDisplayAttribEXT), SYMBOL(QueryDeviceAttribEXT),
 |  | ||||||
| +        SYMBOL(QueryDeviceStringEXT), END_OF_SYMBOLS};
 |  | ||||||
|      (void)fnLoadSymbols(symbols); |  | ||||||
|    } |  | ||||||
|    { |  | ||||||
| @@ -658,6 +707,10 @@ bool GLLibraryEGL::Init(nsACString* cons
 |  | ||||||
|                                       END_OF_SYMBOLS}; |  | ||||||
|      (void)fnLoadSymbols(symbols); |  | ||||||
|    } |  | ||||||
| +  {
 |  | ||||||
| +    const SymLoadStruct symbols[] = {SYMBOL(QueryDevicesEXT), END_OF_SYMBOLS};
 |  | ||||||
| +    (void)fnLoadSymbols(symbols);
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    return true; |  | ||||||
|  } |  | ||||||
| @@ -835,7 +888,10 @@ std::shared_ptr<EglDisplay> GLLibraryEGL
 |  | ||||||
|  #ifdef MOZ_WAYLAND |  | ||||||
|      GdkDisplay* gdkDisplay = gdk_display_get_default(); |  | ||||||
|      if (!gdkDisplay) { |  | ||||||
| -      ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock);
 |  | ||||||
| +      ret = GetAndInitDeviceDisplay(*this, aProofOfLock);
 |  | ||||||
| +      if (!ret) {
 |  | ||||||
| +        ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock);
 |  | ||||||
| +      }
 |  | ||||||
|      } else if (widget::GdkIsWaylandDisplay(gdkDisplay)) { |  | ||||||
|        // Wayland does not support EGL_DEFAULT_DISPLAY |  | ||||||
|        nativeDisplay = widget::WaylandDisplayGetWLDisplay(gdkDisplay); |  | ||||||
| diff -up firefox-102.0/gfx/gl/GLLibraryEGL.h.D148946.diff firefox-102.0/gfx/gl/GLLibraryEGL.h
 |  | ||||||
| --- firefox-102.0/gfx/gl/GLLibraryEGL.h.D148946.diff	2022-06-28 14:47:40.899699885 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/gl/GLLibraryEGL.h	2022-06-28 14:47:40.904700050 +0200
 |  | ||||||
| @@ -71,7 +71,10 @@ enum class EGLLibExtension {
 |  | ||||||
|    ANGLE_device_creation_d3d11, |  | ||||||
|    ANGLE_platform_angle, |  | ||||||
|    ANGLE_platform_angle_d3d, |  | ||||||
| +  EXT_device_enumeration,
 |  | ||||||
|    EXT_device_query, |  | ||||||
| +  EXT_platform_device,
 |  | ||||||
| +  MESA_platform_surfaceless,
 |  | ||||||
|    Max |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -107,7 +110,6 @@ enum class EGLExtension {
 |  | ||||||
|    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, |  | ||||||
| @@ -436,6 +438,10 @@ class GLLibraryEGL final {
 |  | ||||||
|      WRAP(fQueryDeviceAttribEXT(device, attribute, value)); |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| +  const char* fQueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) {
 |  | ||||||
| +    WRAP(fQueryDeviceStringEXT(device, name));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
|   private: |  | ||||||
|    // NV_stream_consumer_gltexture_yuv |  | ||||||
|    EGLBoolean fStreamConsumerGLTextureExternalAttribsNV( |  | ||||||
| @@ -478,6 +484,13 @@ class GLLibraryEGL final {
 |  | ||||||
|      WRAP(fExportDMABUFImageMESA(dpy, image, fds, strides, offsets)); |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| + public:
 |  | ||||||
| +  // EGL_EXT_device_enumeration
 |  | ||||||
| +  EGLBoolean fQueryDevicesEXT(EGLint max_devices, EGLDeviceEXT* devices,
 |  | ||||||
| +                              EGLint* num_devices) {
 |  | ||||||
| +    WRAP(fQueryDevicesEXT(max_devices, devices, num_devices));
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
|  #undef WRAP |  | ||||||
|   |  | ||||||
|  #undef WRAP |  | ||||||
| @@ -586,6 +599,9 @@ class GLLibraryEGL final {
 |  | ||||||
|      EGLBoolean(GLAPIENTRY* fQueryDeviceAttribEXT)(EGLDeviceEXT device, |  | ||||||
|                                                    EGLint attribute, |  | ||||||
|                                                    EGLAttrib* value); |  | ||||||
| +    const char*(GLAPIENTRY* fQueryDeviceStringEXT)(EGLDeviceEXT device,
 |  | ||||||
| +                                                   EGLint name);
 |  | ||||||
| +
 |  | ||||||
|      // NV_stream_consumer_gltexture_yuv |  | ||||||
|      EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalAttribsNV)( |  | ||||||
|          EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list); |  | ||||||
| @@ -623,6 +639,10 @@ class GLLibraryEGL final {
 |  | ||||||
|                                                     EGLint* strides, |  | ||||||
|                                                     EGLint* offsets); |  | ||||||
|   |  | ||||||
| +    EGLBoolean(GLAPIENTRY* fQueryDevicesEXT)(EGLint max_devices,
 |  | ||||||
| +                                             EGLDeviceEXT* devices,
 |  | ||||||
| +                                             EGLint* num_devices);
 |  | ||||||
| +
 |  | ||||||
|    } mSymbols = {}; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
							
								
								
									
										80
									
								
								D149135.diff
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								D149135.diff
									
									
									
									
									
								
							| @ -1,80 +0,0 @@ | |||||||
| diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp
 |  | ||||||
| --- a/widget/gtk/DMABufSurface.cpp
 |  | ||||||
| +++ b/widget/gtk/DMABufSurface.cpp
 |  | ||||||
| @@ -642,11 +642,11 @@
 |  | ||||||
|   |  | ||||||
|  void DMABufSurfaceRGBA::ReleaseTextures() { |  | ||||||
|    LOGDMABUF(("DMABufSurfaceRGBA::ReleaseTextures() UID %d\n", mUID)); |  | ||||||
|    FenceDelete(); |  | ||||||
|   |  | ||||||
| -  if (!mTexture) {
 |  | ||||||
| +  if (!mTexture && mEGLImage == LOCAL_EGL_NO_IMAGE) {
 |  | ||||||
|      return; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    if (!mGL) { |  | ||||||
|  #ifdef NIGHTLY |  | ||||||
| @@ -663,17 +663,17 @@
 |  | ||||||
|    const auto& egl = gle->mEgl; |  | ||||||
|   |  | ||||||
|    if (mTexture && mGL->MakeCurrent()) { |  | ||||||
|      mGL->fDeleteTextures(1, &mTexture); |  | ||||||
|      mTexture = 0; |  | ||||||
| -    mGL = nullptr;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    if (mEGLImage != LOCAL_EGL_NO_IMAGE) { |  | ||||||
|      egl->fDestroyImage(mEGLImage); |  | ||||||
|      mEGLImage = LOCAL_EGL_NO_IMAGE; |  | ||||||
|    } |  | ||||||
| +  mGL = nullptr;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  void DMABufSurfaceRGBA::ReleaseSurface() { |  | ||||||
|    MOZ_ASSERT(!IsMapped(), "We can't release mapped buffer!"); |  | ||||||
|   |  | ||||||
| @@ -1325,11 +1325,11 @@
 |  | ||||||
|   |  | ||||||
|    FenceDelete(); |  | ||||||
|   |  | ||||||
|    bool textureActive = false; |  | ||||||
|    for (int i = 0; i < mBufferPlaneCount; i++) { |  | ||||||
| -    if (mTexture[i]) {
 |  | ||||||
| +    if (mTexture[i] || mEGLImage[i] != LOCAL_EGL_NO_IMAGE) {
 |  | ||||||
|        textureActive = true; |  | ||||||
|        break; |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| @@ -1346,18 +1346,23 @@
 |  | ||||||
|          "leaking textures!"); |  | ||||||
|      return; |  | ||||||
|  #endif |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  if (textureActive && mGL->MakeCurrent()) {
 |  | ||||||
| -    mGL->fDeleteTextures(DMABUF_BUFFER_PLANES, mTexture);
 |  | ||||||
| -    for (int i = 0; i < DMABUF_BUFFER_PLANES; i++) {
 |  | ||||||
| -      mTexture[i] = 0;
 |  | ||||||
| -    }
 |  | ||||||
| -    ReleaseEGLImages(mGL);
 |  | ||||||
| -    mGL = nullptr;
 |  | ||||||
| +  if (!mGL->MakeCurrent()) {
 |  | ||||||
| +    NS_WARNING(
 |  | ||||||
| +        "DMABufSurfaceYUV::ReleaseTextures(): Failed to create GL context "
 |  | ||||||
| +        "current. We're leaking textures!");
 |  | ||||||
| +    return;
 |  | ||||||
|    } |  | ||||||
| +
 |  | ||||||
| +  mGL->fDeleteTextures(DMABUF_BUFFER_PLANES, mTexture);
 |  | ||||||
| +  for (int i = 0; i < DMABUF_BUFFER_PLANES; i++) {
 |  | ||||||
| +    mTexture[i] = 0;
 |  | ||||||
| +  }
 |  | ||||||
| +  ReleaseEGLImages(mGL);
 |  | ||||||
| +  mGL = nullptr;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  bool DMABufSurfaceYUV::VerifyTextureCreation() { |  | ||||||
|    LOGDMABUF(("DMABufSurfaceYUV::VerifyTextureCreation() UID %d", mUID)); |  | ||||||
|   |  | ||||||
| 
 |  | ||||||
							
								
								
									
										34
									
								
								D149238.diff
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								D149238.diff
									
									
									
									
									
								
							| @ -1,34 +0,0 @@ | |||||||
| diff -up firefox-102.0/gfx/config/gfxVars.h.D149238.diff firefox-102.0/gfx/config/gfxVars.h
 |  | ||||||
| --- firefox-102.0/gfx/config/gfxVars.h.D149238.diff	2022-06-23 09:08:47.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/config/gfxVars.h	2022-06-28 16:40:54.130895063 +0200
 |  | ||||||
| @@ -91,7 +91,8 @@ class gfxVarReceiver;
 |  | ||||||
|    _(AllowWebGPU, bool, false)                                      \ |  | ||||||
|    _(UseVP8HwDecode, bool, false)                                   \ |  | ||||||
|    _(UseVP9HwDecode, bool, false)                                   \ |  | ||||||
| -  _(HwDecodedVideoZeroCopy, bool, false)
 |  | ||||||
| +  _(HwDecodedVideoZeroCopy, bool, false)                           \
 |  | ||||||
| +  _(UseDMABufSurfaceExport, bool, true)
 |  | ||||||
|   |  | ||||||
|  /* Add new entries above this line. */ |  | ||||||
|   |  | ||||||
| diff -up firefox-102.0/gfx/thebes/gfxPlatform.cpp.D149238.diff firefox-102.0/gfx/thebes/gfxPlatform.cpp
 |  | ||||||
| --- firefox-102.0/gfx/thebes/gfxPlatform.cpp.D149238.diff	2022-06-23 09:08:47.000000000 +0200
 |  | ||||||
| +++ firefox-102.0/gfx/thebes/gfxPlatform.cpp	2022-06-28 16:40:54.130895063 +0200
 |  | ||||||
| @@ -2861,6 +2861,17 @@ void gfxPlatform::InitWebGLConfig() {
 |  | ||||||
|        gfxVars::SetAllowEglRbab(false); |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
| +
 |  | ||||||
| +  if (kIsWayland || kIsX11) {
 |  | ||||||
| +    // Disable EGL_MESA_image_dma_buf_export on mesa/radeonsi due to
 |  | ||||||
| +    // https://gitlab.freedesktop.org/mesa/mesa/-/issues/6666
 |  | ||||||
| +    nsString adapterDriverVendor;
 |  | ||||||
| +    gfxInfo->GetAdapterDriverVendor(adapterDriverVendor);
 |  | ||||||
| +    if (adapterDriverVendor.Find("mesa") != -1 &&
 |  | ||||||
| +        adapterDriverVendor.Find("radeonsi") != -1) {
 |  | ||||||
| +      gfxVars::SetUseDMABufSurfaceExport(false);
 |  | ||||||
| +    }
 |  | ||||||
| +  }
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  void gfxPlatform::InitWebGPUConfig() { |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,23 +0,0 @@ | |||||||
| diff -up firefox-54.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old firefox-54.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium
 |  | ||||||
| diff -up firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp.old firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp
 |  | ||||||
| --- firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp.old	2017-06-08 14:59:08.786996664 +0200
 |  | ||||||
| +++ firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp	2017-06-08 14:59:22.642946570 +0200
 |  | ||||||
| @@ -211,7 +211,6 @@
 |  | ||||||
|                      '-Wno-parentheses', |  | ||||||
|                      '-Wno-strict-prototypes', |  | ||||||
|                      '-Wmissing-prototypes', |  | ||||||
| -                    '-Wno-format',
 |  | ||||||
|                   ], |  | ||||||
|                   'defines' : [ |  | ||||||
|                       'LINUX', |  | ||||||
| diff -up firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp.build firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp
 |  | ||||||
| --- firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp.build	2017-06-08 15:08:03.627063097 +0200
 |  | ||||||
| +++ firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp	2017-06-08 15:08:15.657019606 +0200
 |  | ||||||
| @@ -206,7 +206,6 @@
 |  | ||||||
|                       '-Wno-parentheses', |  | ||||||
|                       '-Wno-strict-prototypes', |  | ||||||
|                       '-Wmissing-prototypes', |  | ||||||
| -                     '-Wno-format',
 |  | ||||||
|                   ], |  | ||||||
|                   'defines' : [ |  | ||||||
|                       'LINUX', |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| diff -up firefox-87.0/widget/GfxInfoX11.cpp.firefox-kde-webrender firefox-87.0/widget/GfxInfoX11.cpp
 |  | ||||||
| --- firefox-87.0/widget/GfxInfoX11.cpp.firefox-kde-webrender	2021-03-22 19:55:59.169952960 +0100
 |  | ||||||
| +++ firefox-87.0/widget/GfxInfoX11.cpp	2021-03-22 20:04:35.332183657 +0100
 |  | ||||||
| @@ -738,6 +738,14 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
 |  | ||||||
|          DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), |  | ||||||
|          "FEATURE_ROLLOUT_INTEL_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); |  | ||||||
|   |  | ||||||
| +    APPEND_TO_DRIVER_BLOCKLIST_EXT(
 |  | ||||||
| +        OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
 |  | ||||||
| +        DesktopEnvironment::KDE, WindowProtocol::Wayland,
 |  | ||||||
| +        DriverVendor::MesaAll, DeviceFamily::IntelRolloutWebRender,
 |  | ||||||
| +        nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
 |  | ||||||
| +        DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0),
 |  | ||||||
| +        "FEATURE_ROLLOUT_INTEL_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0");
 |  | ||||||
| +
 |  | ||||||
|      // ATI Mesa baseline, chosen arbitrarily. |  | ||||||
|      APPEND_TO_DRIVER_BLOCKLIST_EXT( |  | ||||||
|          OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, |  | ||||||
| @@ -754,6 +762,14 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
 |  | ||||||
|          DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), |  | ||||||
|          "FEATURE_ROLLOUT_ATI_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); |  | ||||||
|   |  | ||||||
| +    APPEND_TO_DRIVER_BLOCKLIST_EXT(
 |  | ||||||
| +        OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
 |  | ||||||
| +        DesktopEnvironment::KDE, WindowProtocol::Wayland,
 |  | ||||||
| +        DriverVendor::MesaAll, DeviceFamily::AtiRolloutWebRender,
 |  | ||||||
| +        nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
 |  | ||||||
| +        DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0),
 |  | ||||||
| +       "FEATURE_ROLLOUT_ATI_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0");
 |  | ||||||
| +
 |  | ||||||
|  #ifdef EARLY_BETA_OR_EARLIER |  | ||||||
|      // Intel Mesa baseline, chosen arbitrarily. |  | ||||||
|      APPEND_TO_DRIVER_BLOCKLIST_EXT( |  | ||||||
| @ -1076,6 +1076,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : | |||||||
| * Tue Aug 23 2022 Kalev Lember <klember@redhat.com> - 104.0-5 | * Tue Aug 23 2022 Kalev Lember <klember@redhat.com> - 104.0-5 | ||||||
| - Use constrain_build macro to simplify parallel make handling | - Use constrain_build macro to simplify parallel make handling | ||||||
| - Drop obsolete build conditionals | - Drop obsolete build conditionals | ||||||
|  | - Drop unused patches | ||||||
| 
 | 
 | ||||||
| * Tue Aug 23 2022 Jan Horak <jhorak@redhat.com> - 104.0-4 | * Tue Aug 23 2022 Jan Horak <jhorak@redhat.com> - 104.0-4 | ||||||
| - Rebuild due to ppc64le fixes | - Rebuild due to ppc64le fixes | ||||||
|  | |||||||
| @ -1,16 +0,0 @@ | |||||||
| diff --git a/config/makefiles/rust.mk b/config/makefiles/rust.mk
 |  | ||||||
| --- a/config/makefiles/rust.mk
 |  | ||||||
| +++ b/config/makefiles/rust.mk
 |  | ||||||
| @@ -61,7 +61,11 @@
 |  | ||||||
|  # Enable link-time optimization for release builds, but not when linking |  | ||||||
|  # gkrust_gtest. |  | ||||||
|  ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE))) |  | ||||||
| +# Pass -Clto for older versions of rust, and CARGO_PROFILE_RELEASE_LTO=true
 |  | ||||||
| +# for newer ones that support it. Combining the latter with -Clto works, so
 |  | ||||||
| +# set both everywhere.
 |  | ||||||
|  cargo_rustc_flags += -Clto |  | ||||||
| +export CARGO_PROFILE_RELEASE_LTO=true
 |  | ||||||
|  endif |  | ||||||
|  endif |  | ||||||
|  endif |  | ||||||
| 
 |  | ||||||
| @ -1,91 +0,0 @@ | |||||||
| diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp
 |  | ||||||
| --- a/gfx/layers/ipc/CompositorBridgeParent.cpp
 |  | ||||||
| +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
 |  | ||||||
| @@ -2376,30 +2376,28 @@
 |  | ||||||
|    if (mWrBridge->PipelineId() == aPipelineId) { |  | ||||||
|      mWrBridge->RemoveEpochDataPriorTo(aEpoch); |  | ||||||
|   |  | ||||||
| -    if (!mPaused) {
 |  | ||||||
| -      if (mIsForcedFirstPaint) {
 |  | ||||||
| -        uiController->NotifyFirstPaint();
 |  | ||||||
| -        mIsForcedFirstPaint = false;
 |  | ||||||
| -      }
 |  | ||||||
| -
 |  | ||||||
| -      std::pair<wr::PipelineId, wr::Epoch> key(aPipelineId, aEpoch);
 |  | ||||||
| -      nsTArray<CompositionPayload> payload =
 |  | ||||||
| -          mWrBridge->TakePendingScrollPayload(key);
 |  | ||||||
| -      if (!payload.IsEmpty()) {
 |  | ||||||
| -        RecordCompositionPayloadsPresented(payload);
 |  | ||||||
| -      }
 |  | ||||||
| -
 |  | ||||||
| -      TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(
 |  | ||||||
| -          aEpoch, aCompositeStartId, aCompositeStart, aRenderStart,
 |  | ||||||
| -          aCompositeEnd, uiController);
 |  | ||||||
| -      Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart,
 |  | ||||||
| -                                 aCompositeEnd);
 |  | ||||||
| -
 |  | ||||||
| -      nsTArray<ImageCompositeNotificationInfo> notifications;
 |  | ||||||
| -      mWrBridge->ExtractImageCompositeNotifications(¬ifications);
 |  | ||||||
| -      if (!notifications.IsEmpty()) {
 |  | ||||||
| -        Unused << ImageBridgeParent::NotifyImageComposites(notifications);
 |  | ||||||
| -      }
 |  | ||||||
| +    if (mIsForcedFirstPaint) {
 |  | ||||||
| +      uiController->NotifyFirstPaint();
 |  | ||||||
| +      mIsForcedFirstPaint = false;
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    std::pair<wr::PipelineId, wr::Epoch> key(aPipelineId, aEpoch);
 |  | ||||||
| +    nsTArray<CompositionPayload> payload =
 |  | ||||||
| +        mWrBridge->TakePendingScrollPayload(key);
 |  | ||||||
| +    if (!payload.IsEmpty()) {
 |  | ||||||
| +      RecordCompositionPayloadsPresented(payload);
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(
 |  | ||||||
| +        aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, aCompositeEnd,
 |  | ||||||
| +        uiController);
 |  | ||||||
| +    Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart,
 |  | ||||||
| +                               aCompositeEnd);
 |  | ||||||
| +
 |  | ||||||
| +    nsTArray<ImageCompositeNotificationInfo> notifications;
 |  | ||||||
| +    mWrBridge->ExtractImageCompositeNotifications(¬ifications);
 |  | ||||||
| +    if (!notifications.IsEmpty()) {
 |  | ||||||
| +      Unused << ImageBridgeParent::NotifyImageComposites(notifications);
 |  | ||||||
|      } |  | ||||||
|      return; |  | ||||||
|    } |  | ||||||
| @@ -2408,21 +2406,19 @@
 |  | ||||||
|    if (wrBridge && wrBridge->GetCompositorBridge()) { |  | ||||||
|      MOZ_ASSERT(!wrBridge->IsRootWebRenderBridgeParent()); |  | ||||||
|      wrBridge->RemoveEpochDataPriorTo(aEpoch); |  | ||||||
| -    if (!mPaused) {
 |  | ||||||
| -      std::pair<wr::PipelineId, wr::Epoch> key(aPipelineId, aEpoch);
 |  | ||||||
| -      nsTArray<CompositionPayload> payload =
 |  | ||||||
| -          wrBridge->TakePendingScrollPayload(key);
 |  | ||||||
| -      if (!payload.IsEmpty()) {
 |  | ||||||
| -        RecordCompositionPayloadsPresented(payload);
 |  | ||||||
| -      }
 |  | ||||||
| -
 |  | ||||||
| -      TransactionId transactionId = wrBridge->FlushTransactionIdsForEpoch(
 |  | ||||||
| -          aEpoch, aCompositeStartId, aCompositeStart, aRenderStart,
 |  | ||||||
| -          aCompositeEnd, uiController, aStats, &stats);
 |  | ||||||
| -      Unused << wrBridge->GetCompositorBridge()->SendDidComposite(
 |  | ||||||
| -          wrBridge->GetLayersId(), transactionId, aCompositeStart,
 |  | ||||||
| -          aCompositeEnd);
 |  | ||||||
| +
 |  | ||||||
| +    std::pair<wr::PipelineId, wr::Epoch> key(aPipelineId, aEpoch);
 |  | ||||||
| +    nsTArray<CompositionPayload> payload =
 |  | ||||||
| +        wrBridge->TakePendingScrollPayload(key);
 |  | ||||||
| +    if (!payload.IsEmpty()) {
 |  | ||||||
| +      RecordCompositionPayloadsPresented(payload);
 |  | ||||||
|      } |  | ||||||
| +
 |  | ||||||
| +    TransactionId transactionId = wrBridge->FlushTransactionIdsForEpoch(
 |  | ||||||
| +        aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, aCompositeEnd,
 |  | ||||||
| +        uiController, aStats, &stats);
 |  | ||||||
| +    Unused << wrBridge->GetCompositorBridge()->SendDidComposite(
 |  | ||||||
| +        wrBridge->GetLayersId(), transactionId, aCompositeStart, aCompositeEnd);
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    if (!stats.IsEmpty()) { |  | ||||||
| 
 |  | ||||||
| @ -1,351 +0,0 @@ | |||||||
| changeset:   556172:143b4ca96ec9 |  | ||||||
| tag:         tip |  | ||||||
| parent:      556169:61c35792ca70 |  | ||||||
| user:        stransky <stransky@redhat.com> |  | ||||||
| date:        Mon Oct 26 12:15:49 2020 +0100 |  | ||||||
| files:       widget/gtk/WindowSurfaceWayland.cpp widget/gtk/WindowSurfaceWayland.h |  | ||||||
| description: |  | ||||||
| Bug 1673313 [Wayland] Don't fail when Shm allocation fails, r?jhorak |  | ||||||
| 
 |  | ||||||
| - Make WaylandAllocateShmMemory() fallible.
 |  | ||||||
| - Implement WaylandReAllocateShmMemory() to re-allocate Shm pool.
 |  | ||||||
| - Remove WaylandShmPool::Resize() and use WaylandShmPool::Create() only.
 |  | ||||||
| - Implement and use WaylandShmPool::Release().
 |  | ||||||
| - Make WindowSurfaceWayland::CreateWaylandBuffer() as fallible.
 |  | ||||||
| 
 |  | ||||||
| Differential Revision: https://phabricator.services.mozilla.com/D94735 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
 |  | ||||||
| --- a/widget/gtk/WindowSurfaceWayland.cpp
 |  | ||||||
| +++ b/widget/gtk/WindowSurfaceWayland.cpp
 |  | ||||||
| @@ -209,14 +209,23 @@ RefPtr<nsWaylandDisplay> WindowBackBuffe
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int WaylandAllocateShmMemory(int aSize) { |  | ||||||
| -  static int counter = 0;
 |  | ||||||
| -  nsPrintfCString shmName("/wayland.mozilla.ipc.%d", counter++);
 |  | ||||||
| -  int fd = shm_open(shmName.get(), O_CREAT | O_RDWR | O_EXCL, 0600);
 |  | ||||||
| -  if (fd >= 0) {
 |  | ||||||
| -    shm_unlink(shmName.get());
 |  | ||||||
| -  } else {
 |  | ||||||
| -    printf_stderr("Unable to SHM memory segment\n");
 |  | ||||||
| -    MOZ_CRASH();
 |  | ||||||
| +  int fd = -1;
 |  | ||||||
| +  do {
 |  | ||||||
| +    static int counter = 0;
 |  | ||||||
| +    nsPrintfCString shmName("/wayland.mozilla.ipc.%d", counter++);
 |  | ||||||
| +    fd = shm_open(shmName.get(), O_CREAT | O_RDWR | O_EXCL, 0600);
 |  | ||||||
| +    if (fd >= 0) {
 |  | ||||||
| +      // We don't want to use leaked file
 |  | ||||||
| +      if (shm_unlink(shmName.get()) != 0) {
 |  | ||||||
| +        NS_WARNING("shm_unlink failed");
 |  | ||||||
| +        return -1;
 |  | ||||||
| +      }
 |  | ||||||
| +    }
 |  | ||||||
| +  } while (fd < 0 && errno == EEXIST);
 |  | ||||||
| +
 |  | ||||||
| +  if (fd < 0) {
 |  | ||||||
| +    NS_WARNING(nsPrintfCString("shm_open failed: %s", strerror(errno)).get());
 |  | ||||||
| +    return -1;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    int ret = 0; |  | ||||||
| @@ -225,59 +234,103 @@ static int WaylandAllocateShmMemory(int 
 |  | ||||||
|      ret = posix_fallocate(fd, 0, aSize); |  | ||||||
|    } while (ret == EINTR); |  | ||||||
|    if (ret != 0) { |  | ||||||
| +    NS_WARNING(
 |  | ||||||
| +        nsPrintfCString("posix_fallocate() fails to allocate shm memory: %s",
 |  | ||||||
| +                        strerror(ret))
 |  | ||||||
| +            .get());
 |  | ||||||
|      close(fd); |  | ||||||
| -    MOZ_CRASH("posix_fallocate() fails to allocate shm memory");
 |  | ||||||
| +    return -1;
 |  | ||||||
|    } |  | ||||||
|  #else |  | ||||||
|    do { |  | ||||||
|      ret = ftruncate(fd, aSize); |  | ||||||
|    } while (ret < 0 && errno == EINTR); |  | ||||||
|    if (ret < 0) { |  | ||||||
| +    NS_WARNING(nsPrintfCString("ftruncate() fails to allocate shm memory: %s",
 |  | ||||||
| +                               strerror(ret))
 |  | ||||||
| +                   .get());
 |  | ||||||
|      close(fd); |  | ||||||
| -    MOZ_CRASH("ftruncate() fails to allocate shm memory");
 |  | ||||||
| +    fd = -1;
 |  | ||||||
|    } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|    return fd; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -WaylandShmPool::WaylandShmPool(RefPtr<nsWaylandDisplay> aWaylandDisplay,
 |  | ||||||
| -                               int aSize)
 |  | ||||||
| -    : mAllocatedSize(aSize) {
 |  | ||||||
| -  mShmPoolFd = WaylandAllocateShmMemory(mAllocatedSize);
 |  | ||||||
| -  mImageData = mmap(nullptr, mAllocatedSize, PROT_READ | PROT_WRITE, MAP_SHARED,
 |  | ||||||
| -                    mShmPoolFd, 0);
 |  | ||||||
| -  MOZ_RELEASE_ASSERT(mImageData != MAP_FAILED,
 |  | ||||||
| -                     "Unable to map drawing surface!");
 |  | ||||||
| +static bool WaylandReAllocateShmMemory(int aFd, int aSize) {
 |  | ||||||
| +  if (ftruncate(aFd, aSize) < 0) {
 |  | ||||||
| +    return false;
 |  | ||||||
| +  }
 |  | ||||||
| +#ifdef HAVE_POSIX_FALLOCATE
 |  | ||||||
| +  do {
 |  | ||||||
| +    errno = posix_fallocate(aFd, 0, aSize);
 |  | ||||||
| +  } while (errno == EINTR);
 |  | ||||||
| +  if (errno != 0) {
 |  | ||||||
| +    return false;
 |  | ||||||
| +  }
 |  | ||||||
| +#endif
 |  | ||||||
| +  return true;
 |  | ||||||
| +}
 |  | ||||||
|   |  | ||||||
| -  mShmPool =
 |  | ||||||
| -      wl_shm_create_pool(aWaylandDisplay->GetShm(), mShmPoolFd, mAllocatedSize);
 |  | ||||||
| +WaylandShmPool::WaylandShmPool()
 |  | ||||||
| +    : mShmPool(nullptr),
 |  | ||||||
| +      mShmPoolFd(-1),
 |  | ||||||
| +      mAllocatedSize(0),
 |  | ||||||
| +      mImageData(MAP_FAILED){};
 |  | ||||||
|   |  | ||||||
| -  // We set our queue to get mShmPool events at compositor thread.
 |  | ||||||
| -  wl_proxy_set_queue((struct wl_proxy*)mShmPool,
 |  | ||||||
| -                     aWaylandDisplay->GetEventQueue());
 |  | ||||||
| +void WaylandShmPool::Release() {
 |  | ||||||
| +  if (mImageData != MAP_FAILED) {
 |  | ||||||
| +    munmap(mImageData, mAllocatedSize);
 |  | ||||||
| +    mImageData = MAP_FAILED;
 |  | ||||||
| +  }
 |  | ||||||
| +  if (mShmPool) {
 |  | ||||||
| +    wl_shm_pool_destroy(mShmPool);
 |  | ||||||
| +    mShmPool = 0;
 |  | ||||||
| +  }
 |  | ||||||
| +  if (mShmPoolFd >= 0) {
 |  | ||||||
| +    close(mShmPoolFd);
 |  | ||||||
| +    mShmPoolFd = -1;
 |  | ||||||
| +  }
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -bool WaylandShmPool::Resize(int aSize) {
 |  | ||||||
| +bool WaylandShmPool::Create(RefPtr<nsWaylandDisplay> aWaylandDisplay,
 |  | ||||||
| +                            int aSize) {
 |  | ||||||
|    // We do size increase only |  | ||||||
| -  if (aSize <= mAllocatedSize) return true;
 |  | ||||||
| -
 |  | ||||||
| -  if (ftruncate(mShmPoolFd, aSize) < 0) return false;
 |  | ||||||
| +  if (aSize <= mAllocatedSize) {
 |  | ||||||
| +    return true;
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
| -#ifdef HAVE_POSIX_FALLOCATE
 |  | ||||||
| -  do {
 |  | ||||||
| -    errno = posix_fallocate(mShmPoolFd, 0, aSize);
 |  | ||||||
| -  } while (errno == EINTR);
 |  | ||||||
| -  if (errno != 0) return false;
 |  | ||||||
| -#endif
 |  | ||||||
| +  if (mShmPoolFd < 0) {
 |  | ||||||
| +    mShmPoolFd = WaylandAllocateShmMemory(aSize);
 |  | ||||||
| +    if (mShmPoolFd < 0) {
 |  | ||||||
| +      return false;
 |  | ||||||
| +    }
 |  | ||||||
| +  } else {
 |  | ||||||
| +    if (!WaylandReAllocateShmMemory(mShmPoolFd, aSize)) {
 |  | ||||||
| +      Release();
 |  | ||||||
| +      return false;
 |  | ||||||
| +    }
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
| -  wl_shm_pool_resize(mShmPool, aSize);
 |  | ||||||
| -
 |  | ||||||
| -  munmap(mImageData, mAllocatedSize);
 |  | ||||||
| -
 |  | ||||||
| +  if (mImageData != MAP_FAILED) {
 |  | ||||||
| +    munmap(mImageData, mAllocatedSize);
 |  | ||||||
| +  }
 |  | ||||||
|    mImageData = |  | ||||||
|        mmap(nullptr, aSize, PROT_READ | PROT_WRITE, MAP_SHARED, mShmPoolFd, 0); |  | ||||||
| -  if (mImageData == MAP_FAILED) return false;
 |  | ||||||
| +  if (mImageData == MAP_FAILED) {
 |  | ||||||
| +    NS_WARNING("Unable to map drawing surface!");
 |  | ||||||
| +    Release();
 |  | ||||||
| +    return false;
 |  | ||||||
| +  }
 |  | ||||||
| +
 |  | ||||||
| +  if (mShmPool) {
 |  | ||||||
| +    wl_shm_pool_resize(mShmPool, aSize);
 |  | ||||||
| +  } else {
 |  | ||||||
| +    mShmPool = wl_shm_create_pool(aWaylandDisplay->GetShm(), mShmPoolFd, aSize);
 |  | ||||||
| +    // We set our queue to get mShmPool events at compositor thread.
 |  | ||||||
| +    wl_proxy_set_queue((struct wl_proxy*)mShmPool,
 |  | ||||||
| +                       aWaylandDisplay->GetEventQueue());
 |  | ||||||
| +  }
 |  | ||||||
|   |  | ||||||
|    mAllocatedSize = aSize; |  | ||||||
|    return true; |  | ||||||
| @@ -289,11 +342,7 @@ void WaylandShmPool::SetImageDataFromPoo
 |  | ||||||
|    memcpy(mImageData, aSourcePool->GetImageData(), aImageDataSize); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -WaylandShmPool::~WaylandShmPool() {
 |  | ||||||
| -  munmap(mImageData, mAllocatedSize);
 |  | ||||||
| -  wl_shm_pool_destroy(mShmPool);
 |  | ||||||
| -  close(mShmPoolFd);
 |  | ||||||
| -}
 |  | ||||||
| +WaylandShmPool::~WaylandShmPool() { Release(); }
 |  | ||||||
|   |  | ||||||
|  static void buffer_release(void* data, wl_buffer* buffer) { |  | ||||||
|    auto surface = reinterpret_cast<WindowBackBuffer*>(data); |  | ||||||
| @@ -302,14 +351,14 @@ static void buffer_release(void* data, w
 |  | ||||||
|   |  | ||||||
|  static const struct wl_buffer_listener buffer_listener = {buffer_release}; |  | ||||||
|   |  | ||||||
| -void WindowBackBufferShm::Create(int aWidth, int aHeight) {
 |  | ||||||
| +bool WindowBackBufferShm::Create(int aWidth, int aHeight) {
 |  | ||||||
|    MOZ_ASSERT(!IsAttached(), "We can't create attached buffers."); |  | ||||||
| -  MOZ_ASSERT(!mWLBuffer, "there is wl_buffer already!");
 |  | ||||||
|   |  | ||||||
| -  int newBufferSize = aWidth * aHeight * BUFFER_BPP;
 |  | ||||||
| -  if (!mShmPool.Resize(newBufferSize)) {
 |  | ||||||
| -    mWLBuffer = nullptr;
 |  | ||||||
| -    return;
 |  | ||||||
| +  ReleaseShmSurface();
 |  | ||||||
| +
 |  | ||||||
| +  int size = aWidth * aHeight * BUFFER_BPP;
 |  | ||||||
| +  if (!mShmPool.Create(GetWaylandDisplay(), size)) {
 |  | ||||||
| +    return false;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    mWLBuffer = |  | ||||||
| @@ -325,14 +374,16 @@ void WindowBackBufferShm::Create(int aWi
 |  | ||||||
|    LOGWAYLAND(("WindowBackBufferShm::Create [%p] wl_buffer %p ID %d\n", |  | ||||||
|                (void*)this, (void*)mWLBuffer, |  | ||||||
|                mWLBuffer ? wl_proxy_get_id((struct wl_proxy*)mWLBuffer) : -1)); |  | ||||||
| +  return true;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  void WindowBackBufferShm::ReleaseShmSurface() { |  | ||||||
|    LOGWAYLAND(("WindowBackBufferShm::Release [%p]\n", (void*)this)); |  | ||||||
| -
 |  | ||||||
| -  wl_buffer_destroy(mWLBuffer);
 |  | ||||||
| +  if (mWLBuffer) {
 |  | ||||||
| +    wl_buffer_destroy(mWLBuffer);
 |  | ||||||
| +    mWLBuffer = nullptr;
 |  | ||||||
| +  }
 |  | ||||||
|    mWidth = mHeight = 0; |  | ||||||
| -  mWLBuffer = nullptr;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  void WindowBackBufferShm::Clear() { |  | ||||||
| @@ -340,16 +391,13 @@ void WindowBackBufferShm::Clear() {
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  WindowBackBufferShm::WindowBackBufferShm( |  | ||||||
| -    WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight)
 |  | ||||||
| +    WindowSurfaceWayland* aWindowSurfaceWayland)
 |  | ||||||
|      : WindowBackBuffer(aWindowSurfaceWayland), |  | ||||||
| -      mShmPool(aWindowSurfaceWayland->GetWaylandDisplay(),
 |  | ||||||
| -               aWidth * aHeight * BUFFER_BPP),
 |  | ||||||
| +      mShmPool(),
 |  | ||||||
|        mWLBuffer(nullptr), |  | ||||||
| -      mWidth(aWidth),
 |  | ||||||
| -      mHeight(aHeight),
 |  | ||||||
| -      mAttached(false) {
 |  | ||||||
| -  Create(aWidth, aHeight);
 |  | ||||||
| -}
 |  | ||||||
| +      mWidth(0),
 |  | ||||||
| +      mHeight(0),
 |  | ||||||
| +      mAttached(false) {}
 |  | ||||||
|   |  | ||||||
|  WindowBackBufferShm::~WindowBackBufferShm() { ReleaseShmSurface(); } |  | ||||||
|   |  | ||||||
| @@ -357,13 +405,9 @@ bool WindowBackBufferShm::Resize(int aWi
 |  | ||||||
|    if (aWidth == mWidth && aHeight == mHeight) { |  | ||||||
|      return true; |  | ||||||
|    } |  | ||||||
| -
 |  | ||||||
|    LOGWAYLAND(("WindowBackBufferShm::Resize [%p] %d %d\n", (void*)this, aWidth, |  | ||||||
|                aHeight)); |  | ||||||
| -
 |  | ||||||
| -  ReleaseShmSurface();
 |  | ||||||
|    Create(aWidth, aHeight); |  | ||||||
| -
 |  | ||||||
|    return (mWLBuffer != nullptr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -488,11 +532,13 @@ WindowBackBuffer* WindowSurfaceWayland::
 |  | ||||||
|      return nullptr; |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  WindowBackBuffer* buffer = new WindowBackBufferShm(this, aWidth, aHeight);
 |  | ||||||
| -  if (buffer) {
 |  | ||||||
| -    mShmBackupBuffer[availableBuffer] = buffer;
 |  | ||||||
| +  WindowBackBuffer* buffer = new WindowBackBufferShm(this);
 |  | ||||||
| +  if (!buffer->Create(aWidth, aHeight)) {
 |  | ||||||
| +    delete buffer;
 |  | ||||||
| +    return nullptr;
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| +  mShmBackupBuffer[availableBuffer] = buffer;
 |  | ||||||
|    return buffer; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
 |  | ||||||
| --- a/widget/gtk/WindowSurfaceWayland.h
 |  | ||||||
| +++ b/widget/gtk/WindowSurfaceWayland.h
 |  | ||||||
| @@ -25,14 +25,14 @@ class WindowSurfaceWayland;
 |  | ||||||
|  // Allocates and owns shared memory for Wayland drawing surface |  | ||||||
|  class WaylandShmPool { |  | ||||||
|   public: |  | ||||||
| -  WaylandShmPool(RefPtr<nsWaylandDisplay> aDisplay, int aSize);
 |  | ||||||
| -  ~WaylandShmPool();
 |  | ||||||
| -
 |  | ||||||
| -  bool Resize(int aSize);
 |  | ||||||
| +  bool Create(RefPtr<nsWaylandDisplay> aWaylandDisplay, int aSize);
 |  | ||||||
| +  void Release();
 |  | ||||||
|    wl_shm_pool* GetShmPool() { return mShmPool; }; |  | ||||||
|    void* GetImageData() { return mImageData; }; |  | ||||||
|    void SetImageDataFromPool(class WaylandShmPool* aSourcePool, |  | ||||||
|                              int aImageDataSize); |  | ||||||
| +  WaylandShmPool();
 |  | ||||||
| +  ~WaylandShmPool();
 |  | ||||||
|   |  | ||||||
|   private: |  | ||||||
|    wl_shm_pool* mShmPool; |  | ||||||
| @@ -53,6 +53,7 @@ class WindowBackBuffer {
 |  | ||||||
|    virtual bool IsAttached() = 0; |  | ||||||
|   |  | ||||||
|    virtual void Clear() = 0; |  | ||||||
| +  virtual bool Create(int aWidth, int aHeight) = 0;
 |  | ||||||
|    virtual bool Resize(int aWidth, int aHeight) = 0; |  | ||||||
|   |  | ||||||
|    virtual int GetWidth() = 0; |  | ||||||
| @@ -87,8 +88,7 @@ class WindowBackBuffer {
 |  | ||||||
|   |  | ||||||
|  class WindowBackBufferShm : public WindowBackBuffer { |  | ||||||
|   public: |  | ||||||
| -  WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth,
 |  | ||||||
| -                      int aHeight);
 |  | ||||||
| +  WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland);
 |  | ||||||
|    ~WindowBackBufferShm(); |  | ||||||
|   |  | ||||||
|    already_AddRefed<gfx::DrawTarget> Lock(); |  | ||||||
| @@ -100,6 +100,7 @@ class WindowBackBufferShm : public Windo
 |  | ||||||
|    void SetAttached() { mAttached = true; }; |  | ||||||
|   |  | ||||||
|    void Clear(); |  | ||||||
| +  bool Create(int aWidth, int aHeight);
 |  | ||||||
|    bool Resize(int aWidth, int aHeight); |  | ||||||
|    bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); |  | ||||||
|   |  | ||||||
| @@ -109,7 +110,6 @@ class WindowBackBufferShm : public Windo
 |  | ||||||
|    wl_buffer* GetWlBuffer() { return mWLBuffer; }; |  | ||||||
|   |  | ||||||
|   private: |  | ||||||
| -  void Create(int aWidth, int aHeight);
 |  | ||||||
|    void ReleaseShmSurface(); |  | ||||||
|   |  | ||||||
|    // WaylandShmPool provides actual shared memory we draw into |  | ||||||
| 
 |  | ||||||
| @ -1,51 +0,0 @@ | |||||||
| diff --git a/gfx/wr/swgl/src/blend.h b/gfx/wr/swgl/src/blend.h
 |  | ||||||
| --- a/gfx/wr/swgl/src/blend.h
 |  | ||||||
| +++ b/gfx/wr/swgl/src/blend.h
 |  | ||||||
| @@ -405,7 +405,7 @@
 |  | ||||||
|    blend_key = BlendKey(AA_BLEND_KEY_NONE + blend_key); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static ALWAYS_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst,
 |  | ||||||
| +static PREFER_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst,
 |  | ||||||
|                                              WideRGBA8 src, int span = 4) { |  | ||||||
|    WideRGBA8 dst = unpack(pdst); |  | ||||||
|    const WideRGBA8 RGB_MASK = {0xFFFF, 0xFFFF, 0xFFFF, 0,      0xFFFF, 0xFFFF, |  | ||||||
| @@ -686,7 +686,7 @@
 |  | ||||||
|    // clang-format on |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static ALWAYS_INLINE WideR8 blend_pixels(uint8_t* buf, WideR8 dst, WideR8 src,
 |  | ||||||
| +static PREFER_INLINE WideR8 blend_pixels(uint8_t* buf, WideR8 dst, WideR8 src,
 |  | ||||||
|                                           int span = 4) { |  | ||||||
|  // clang-format off |  | ||||||
|  #define BLEND_CASE_KEY(key)                          \ |  | ||||||
| diff --git a/gfx/wr/swgl/src/gl.cc b/gfx/wr/swgl/src/gl.cc
 |  | ||||||
| --- a/gfx/wr/swgl/src/gl.cc
 |  | ||||||
| +++ b/gfx/wr/swgl/src/gl.cc
 |  | ||||||
| @@ -58,10 +58,24 @@
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #else |  | ||||||
| -#  define ALWAYS_INLINE __attribute__((always_inline)) inline
 |  | ||||||
| +// GCC is slower when dealing with always_inline, especially in debug builds.
 |  | ||||||
| +// When using Clang, use always_inline more aggressively.
 |  | ||||||
| +#  if defined(__clang__) || defined(NDEBUG)
 |  | ||||||
| +#    define ALWAYS_INLINE __attribute__((always_inline)) inline
 |  | ||||||
| +#  else
 |  | ||||||
| +#    define ALWAYS_INLINE inline
 |  | ||||||
| +#  endif
 |  | ||||||
|  #  define NO_INLINE __attribute__((noinline)) |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +// Some functions may cause excessive binary bloat if inlined in debug or with
 |  | ||||||
| +// GCC builds, so use PREFER_INLINE on these instead of ALWAYS_INLINE.
 |  | ||||||
| +#if defined(__clang__) && defined(NDEBUG)
 |  | ||||||
| +#  define PREFER_INLINE ALWAYS_INLINE
 |  | ||||||
| +#else
 |  | ||||||
| +#  define PREFER_INLINE inline
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
|  #define UNREACHABLE __builtin_unreachable() |  | ||||||
|   |  | ||||||
|  #define UNUSED [[maybe_unused]] |  | ||||||
| 
 |  | ||||||
| @ -1,23 +0,0 @@ | |||||||
| diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp
 |  | ||||||
| --- a/dom/media/gmp/GMPParent.cpp
 |  | ||||||
| +++ b/dom/media/gmp/GMPParent.cpp
 |  | ||||||
| @@ -884,7 +884,7 @@
 |  | ||||||
|    // |  | ||||||
|    // Google's code to parse manifests can be used as a reference for strings |  | ||||||
|    // the manifest may contain |  | ||||||
| -  // https://cs.chromium.org/chromium/src/chrome/common/media/cdm_manifest.cc?l=73&rcl=393e60bfc2299449db7ef374c0ef1c324716e562
 |  | ||||||
| +  // https://source.chromium.org/chromium/chromium/src/+/master:components/cdm/common/cdm_manifest.cc;l=74;drc=775880ced8a989191281e93854c7f2201f25068f
 |  | ||||||
|    // |  | ||||||
|    // Gecko's internal strings can be found at |  | ||||||
|    // https://searchfox.org/mozilla-central/rev/ea63a0888d406fae720cf24f4727d87569a8cab5/dom/media/eme/MediaKeySystemAccess.cpp#149-155 |  | ||||||
| @@ -892,7 +892,8 @@
 |  | ||||||
|      nsCString codec; |  | ||||||
|      if (chromiumCodec.EqualsASCII("vp8")) { |  | ||||||
|        codec = "vp8"_ns; |  | ||||||
| -    } else if (chromiumCodec.EqualsASCII("vp9.0")) {
 |  | ||||||
| +    } else if (chromiumCodec.EqualsASCII("vp9.0") ||  // Legacy string.
 |  | ||||||
| +               chromiumCodec.EqualsASCII("vp09")) {
 |  | ||||||
|        codec = "vp9"_ns; |  | ||||||
|      } else if (chromiumCodec.EqualsASCII("avc1")) { |  | ||||||
|        codec = "h264"_ns; |  | ||||||
| 
 |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| diff --git a/tools/profiler/rust-api/build.rs b/tools/profiler/rust-api/build.rs
 |  | ||||||
| --- a/tools/profiler/rust-api/build.rs
 |  | ||||||
| +++ b/tools/profiler/rust-api/build.rs
 |  | ||||||
| @@ -61,6 +61,7 @@
 |  | ||||||
|      let mut builder = Builder::default() |  | ||||||
|          .enable_cxx_namespaces() |  | ||||||
|          .with_codegen_config(CodegenConfig::TYPES | CodegenConfig::VARS | CodegenConfig::FUNCTIONS) |  | ||||||
| +        .disable_untagged_union()
 |  | ||||||
|          .size_t_is_usize(true); |  | ||||||
|   |  | ||||||
|      for dir in SEARCH_PATHS.iter() { |  | ||||||
| 
 |  | ||||||
| @ -1,28 +0,0 @@ | |||||||
| changeset:   623785:a6b80ee8c35f |  | ||||||
| tag:         tip |  | ||||||
| parent:      623782:b1ed2fa50612 |  | ||||||
| user:        stransky <stransky@redhat.com> |  | ||||||
| date:        Wed Jun 15 14:54:19 2022 +0200 |  | ||||||
| files:       dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp |  | ||||||
| description: |  | ||||||
| Bug 1758948 [FFmpeg] Use AVFrame::pts instead of AVFrame::pkt_pts on ffmpeg 4.x r?alwu |  | ||||||
| 
 |  | ||||||
| AVFrame::pkt_pts has been deprecated and gives us wrong values for AV1 VA-API. Let's use AVFrame::pts instead on ffmpeg 4.x |  | ||||||
| as well as we use on ffmpeg 5.0 where AVFrame::pkt_pts is removed. |  | ||||||
| 
 |  | ||||||
| Differential Revision: https://phabricator.services.mozilla.com/D149386 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 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
 |  | ||||||
| @@ -774,7 +774,7 @@ void FFmpegVideoDecoder<LIBAV_VER>::Init
 |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  static int64_t GetFramePts(AVFrame* aFrame) { |  | ||||||
| -#if LIBAVCODEC_VERSION_MAJOR > 58
 |  | ||||||
| +#if LIBAVCODEC_VERSION_MAJOR > 57
 |  | ||||||
|    return aFrame->pts; |  | ||||||
|  #else |  | ||||||
|    return aFrame->pkt_pts; |  | ||||||
| 
 |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| changeset:   623945:6117c9ecd16b |  | ||||||
| tag:         tip |  | ||||||
| parent:      623941:45e313943df5 |  | ||||||
| user:        stransky <stransky@redhat.com> |  | ||||||
| date:        Fri Jun 17 12:36:38 2022 +0200 |  | ||||||
| files:       gfx/thebes/gfxPlatform.cpp |  | ||||||
| description: |  | ||||||
| Bug 1774271 [Linux] Don't use EGL_MESA_image_dma_buf_export in Mesa/Intel due to https://gitlab.freedesktop.org/mesa/mesa/-/issues/6688 r?jgilbert |  | ||||||
| 
 |  | ||||||
| Depends on https://phabricator.services.mozilla.com/D149238 |  | ||||||
| 
 |  | ||||||
| Differential Revision: https://phabricator.services.mozilla.com/D149608 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
 |  | ||||||
| --- a/gfx/thebes/gfxPlatform.cpp
 |  | ||||||
| +++ b/gfx/thebes/gfxPlatform.cpp
 |  | ||||||
| @@ -2871,6 +2871,12 @@ void gfxPlatform::InitWebGLConfig() {
 |  | ||||||
|          adapterDriverVendor.Find("radeonsi") != -1) { |  | ||||||
|        gfxVars::SetUseDMABufSurfaceExport(false); |  | ||||||
|      } |  | ||||||
| +    // Disable EGL_MESA_image_dma_buf_export on mesa/iris due to
 |  | ||||||
| +    // https://gitlab.freedesktop.org/mesa/mesa/-/issues/6688
 |  | ||||||
| +    if (adapterDriverVendor.Find("mesa") != -1 &&
 |  | ||||||
| +        adapterDriverVendor.Find("iris") != -1) {
 |  | ||||||
| +      gfxVars::SetUseDMABufSurfaceExport(false);
 |  | ||||||
| +    }
 |  | ||||||
|    } |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| 
 |  | ||||||
| @ -1,21 +0,0 @@ | |||||||
| diff --git a/browser/components/shell/nsGNOMEShellDBusHelper.cpp b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
 |  | ||||||
| --- a/browser/components/shell/nsGNOMEShellDBusHelper.cpp
 |  | ||||||
| +++ b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
 |  | ||||||
| @@ -29,7 +29,7 @@ static bool GetGnomeSearchTitle(const ch
 |  | ||||||
|    } |  | ||||||
|   |  | ||||||
|    AutoTArray<nsString, 1> formatStrings; |  | ||||||
| -  CopyASCIItoUTF16(nsCString(aSearchedTerm), *formatStrings.AppendElement());
 |  | ||||||
| +  CopyUTF8toUTF16(nsCString(aSearchedTerm), *formatStrings.AppendElement());
 |  | ||||||
|   |  | ||||||
|    nsAutoString gnomeSearchTitle; |  | ||||||
|    bundle->FormatStringFromName("gnomeSearchProviderSearch", formatStrings, |  | ||||||
| @@ -41,7 +41,7 @@ static bool GetGnomeSearchTitle(const ch
 |  | ||||||
|  static const char* introspect_template = |  | ||||||
|      "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection " |  | ||||||
|      "1.0//EN\"\n" |  | ||||||
| -    "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\";>\n"
 |  | ||||||
| +    "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
 |  | ||||||
|      "<node>\n" |  | ||||||
|      " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" |  | ||||||
|      "   <method name=\"Introspect\">\n" |  | ||||||
| @ -1,111 +0,0 @@ | |||||||
| diff -up firefox-56.0/modules/libpref/prefapi.cpp.440908 firefox-56.0/modules/libpref/prefapi.cpp
 |  | ||||||
| --- firefox-56.0/modules/libpref/prefapi.cpp.440908	2017-09-14 22:15:52.000000000 +0200
 |  | ||||||
| +++ firefox-56.0/modules/libpref/prefapi.cpp	2017-09-25 10:39:39.266572792 +0200
 |  | ||||||
| @@ -1036,8 +1036,8 @@ void PREF_ReaderCallback(void       *clo
 |  | ||||||
|                           PrefValue   value, |  | ||||||
|                           PrefType    type, |  | ||||||
|                           bool        isDefault, |  | ||||||
| -                         bool        isStickyDefault)
 |  | ||||||
| -
 |  | ||||||
| +                         bool        isStickyDefault,
 |  | ||||||
| +                         bool        isLocked)
 |  | ||||||
|  { |  | ||||||
|      uint32_t flags = 0; |  | ||||||
|      if (isDefault) { |  | ||||||
| @@ -1049,4 +1049,6 @@ void PREF_ReaderCallback(void       *clo
 |  | ||||||
|          flags |= kPrefForceSet; |  | ||||||
|      } |  | ||||||
|      pref_HashPref(pref, value, type, flags); |  | ||||||
| +    if (isLocked)
 |  | ||||||
| +        PREF_LockPref(pref, true);
 |  | ||||||
|  } |  | ||||||
| diff -up firefox-56.0/modules/libpref/prefapi.h.440908 firefox-56.0/modules/libpref/prefapi.h
 |  | ||||||
| --- firefox-56.0/modules/libpref/prefapi.h.440908	2017-07-31 18:20:51.000000000 +0200
 |  | ||||||
| +++ firefox-56.0/modules/libpref/prefapi.h	2017-09-25 10:39:39.267572789 +0200
 |  | ||||||
| @@ -246,8 +246,8 @@ void PREF_ReaderCallback( void *closure,
 |  | ||||||
|                            PrefValue   value, |  | ||||||
|                            PrefType    type, |  | ||||||
|                            bool        isDefault, |  | ||||||
| -                          bool        isStickyDefault);
 |  | ||||||
| -
 |  | ||||||
| +                          bool        isStickyDefault,
 |  | ||||||
| +                          bool        isLocked);
 |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * Callback whenever we change a preference |  | ||||||
| diff -up firefox-56.0/modules/libpref/prefread.cpp.440908 firefox-56.0/modules/libpref/prefread.cpp
 |  | ||||||
| --- firefox-56.0/modules/libpref/prefread.cpp.440908	2017-09-14 22:15:52.000000000 +0200
 |  | ||||||
| +++ firefox-56.0/modules/libpref/prefread.cpp	2017-09-25 10:39:39.267572789 +0200
 |  | ||||||
| @@ -43,6 +43,7 @@ enum {
 |  | ||||||
|  #define BITS_PER_HEX_DIGIT      4 |  | ||||||
|   |  | ||||||
|  static const char kUserPref[] = "user_pref"; |  | ||||||
| +static const char kLockPref[] = "lockPref";
 |  | ||||||
|  static const char kPref[] = "pref"; |  | ||||||
|  static const char kPrefSticky[] = "sticky_pref"; |  | ||||||
|  static const char kTrue[] = "true"; |  | ||||||
| @@ -146,7 +147,7 @@ pref_DoCallback(PrefParseState *ps)
 |  | ||||||
|          break; |  | ||||||
|      } |  | ||||||
|      (*ps->reader)(ps->closure, ps->lb, value, ps->vtype, ps->fdefault, |  | ||||||
| -                  ps->fstickydefault);
 |  | ||||||
| +                  ps->fstickydefault, ps->flock);
 |  | ||||||
|      return true; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -215,6 +216,7 @@ PREF_ParseBuf(PrefParseState *ps, const
 |  | ||||||
|                  ps->vtype = PrefType::Invalid; |  | ||||||
|                  ps->fdefault = false; |  | ||||||
|                  ps->fstickydefault = false; |  | ||||||
| +                ps->flock = false;
 |  | ||||||
|              } |  | ||||||
|              switch (c) { |  | ||||||
|              case '/':       /* begin comment block or line? */ |  | ||||||
| @@ -225,11 +227,14 @@ PREF_ParseBuf(PrefParseState *ps, const
 |  | ||||||
|                  break; |  | ||||||
|              case 'u':       /* indicating user_pref */ |  | ||||||
|              case 's':       /* indicating sticky_pref */ |  | ||||||
| +            case 'l':       /* indicating lockPref */
 |  | ||||||
|              case 'p':       /* indicating pref */ |  | ||||||
|                  if (c == 'u') { |  | ||||||
|                    ps->smatch = kUserPref; |  | ||||||
|                  } else if (c == 's') { |  | ||||||
|                    ps->smatch = kPrefSticky; |  | ||||||
| +                } else if (c == 'l') {
 |  | ||||||
| +                  ps->smatch = kLockPref;
 |  | ||||||
|                  } else { |  | ||||||
|                    ps->smatch = kPref; |  | ||||||
|                  } |  | ||||||
| @@ -277,8 +282,10 @@ PREF_ParseBuf(PrefParseState *ps, const
 |  | ||||||
|          /* name parsing */ |  | ||||||
|          case PREF_PARSE_UNTIL_NAME: |  | ||||||
|              if (c == '\"' || c == '\'') { |  | ||||||
| -                ps->fdefault = (ps->smatch == kPref || ps->smatch == kPrefSticky);
 |  | ||||||
| +                ps->fdefault = (ps->smatch == kPref || ps->smatch == kPrefSticky
 |  | ||||||
| +                                || ps->smatch == kLockPref);
 |  | ||||||
|                  ps->fstickydefault = (ps->smatch == kPrefSticky); |  | ||||||
| +                ps->flock = (ps->smatch == kLockPref);
 |  | ||||||
|                  ps->quotechar = c; |  | ||||||
|                  ps->nextstate = PREF_PARSE_UNTIL_COMMA; /* return here when done */ |  | ||||||
|                  state = PREF_PARSE_QUOTED_STRING; |  | ||||||
| diff -up firefox-56.0/modules/libpref/prefread.h.440908 firefox-56.0/modules/libpref/prefread.h
 |  | ||||||
| --- firefox-56.0/modules/libpref/prefread.h.440908	2017-09-14 22:15:52.000000000 +0200
 |  | ||||||
| +++ firefox-56.0/modules/libpref/prefread.h	2017-09-25 10:39:39.267572789 +0200
 |  | ||||||
| @@ -34,7 +34,8 @@ typedef void (*PrefReader)(void       *c
 |  | ||||||
|                             PrefValue   val, |  | ||||||
|                             PrefType    type, |  | ||||||
|                             bool        defPref, |  | ||||||
| -                           bool        stickyPref);
 |  | ||||||
| +                           bool        stickyPref,
 |  | ||||||
| +                           bool        lockPref);
 |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
|   * Report any errors or warnings we encounter during parsing. |  | ||||||
| @@ -62,6 +63,7 @@ typedef struct PrefParseState {
 |  | ||||||
|      PrefType    vtype;      /* PREF_STRING,INT,BOOL          */ |  | ||||||
|      bool        fdefault;   /* true if (default) pref        */ |  | ||||||
|      bool        fstickydefault; /* true if (sticky) pref     */ |  | ||||||
| +    bool        flock;      /* true if pref to be locked     */
 |  | ||||||
|  } PrefParseState; |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @ -1,72 +0,0 @@ | |||||||
| diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp
 |  | ||||||
| --- a/security/certverifier/CertVerifier.cpp
 |  | ||||||
| +++ b/security/certverifier/CertVerifier.cpp
 |  | ||||||
| @@ -120,16 +120,20 @@ IsCertChainRootBuiltInRoot(const UniqueC
 |  | ||||||
|    } |  | ||||||
|    CERTCertificate* root = rootNode->cert; |  | ||||||
|    if (!root) { |  | ||||||
|      return Result::FATAL_ERROR_LIBRARY_FAILURE; |  | ||||||
|    } |  | ||||||
|    return IsCertBuiltInRoot(root, result); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +// The term "builtin root" traditionally refers to a root CA certificate that
 |  | ||||||
| +// has been added to the NSS trust store, because it has been approved
 |  | ||||||
| +// for inclusion according to the Mozilla CA policy, and might be accepted
 |  | ||||||
| +// by Mozilla applications as an issuer for certificates seen on the public web.
 |  | ||||||
|  Result |  | ||||||
|  IsCertBuiltInRoot(CERTCertificate* cert, bool& result) |  | ||||||
|  { |  | ||||||
|    result = false; |  | ||||||
|  #ifdef DEBUG |  | ||||||
|    nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID)); |  | ||||||
|    if (!component) { |  | ||||||
|      return Result::FATAL_ERROR_LIBRARY_FAILURE; |  | ||||||
| @@ -142,25 +146,38 @@ IsCertBuiltInRoot(CERTCertificate* cert,
 |  | ||||||
|      return Success; |  | ||||||
|    } |  | ||||||
|  #endif // DEBUG |  | ||||||
|    AutoSECMODListReadLock lock; |  | ||||||
|    for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list; |  | ||||||
|         list = list->next) { |  | ||||||
|      for (int i = 0; i < list->module->slotCount; i++) { |  | ||||||
|        PK11SlotInfo* slot = list->module->slots[i]; |  | ||||||
| -      // PK11_HasRootCerts should return true if and only if the given slot has
 |  | ||||||
| -      // an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST, which
 |  | ||||||
| -      // should be true only of the builtin root list.
 |  | ||||||
| -      // If we can find a copy of the given certificate on the slot with the
 |  | ||||||
| -      // builtin root list, that certificate must be a builtin.
 |  | ||||||
| -      if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot) &&
 |  | ||||||
| -          PK11_FindCertInSlot(slot, cert, nullptr) != CK_INVALID_HANDLE) {
 |  | ||||||
| -        result = true;
 |  | ||||||
| -        return Success;
 |  | ||||||
| +      // We're searching for the "builtin root module", which is a module that
 |  | ||||||
| +      // contains an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST.
 |  | ||||||
| +      // We use PK11_HasRootCerts() to identify a module with that property.
 |  | ||||||
| +      // In the past, we exclusively used the PKCS#11 module named nssckbi,
 |  | ||||||
| +      // which is provided by the NSS library.
 |  | ||||||
| +      // Nowadays, some distributions use a replacement module, which contains
 |  | ||||||
| +      // the builtin roots, but which also contains additional CA certificates,
 |  | ||||||
| +      // such as CAs trusted in a local deployment.
 |  | ||||||
| +      // We want to be able to distinguish between these two categories,
 |  | ||||||
| +      // because a CA, which may issue certificates for the public web,
 |  | ||||||
| +      // is expected to comply with additional requirements.
 |  | ||||||
| +      // If the certificate has attribute CKA_NSS_MOZILLA_CA_POLICY set to true,
 |  | ||||||
| +      // then we treat it as a "builtin root".
 |  | ||||||
| +      if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) {
 |  | ||||||
| +        CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, cert, nullptr);
 |  | ||||||
| +        if (handle != CK_INVALID_HANDLE &&
 |  | ||||||
| +            PK11_HasAttributeSet(slot, handle, CKA_NSS_MOZILLA_CA_POLICY,
 |  | ||||||
| +                                 false)) {
 |  | ||||||
| +          // Attribute was found, and is set to true
 |  | ||||||
| +          result = true;
 |  | ||||||
| +          break;
 |  | ||||||
| +        }
 |  | ||||||
|        } |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|    return Success; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static Result |  | ||||||
|  BuildCertChainForOneKeyUsage(NSSCertDBTrustDomain& trustDomain, Input certDER, |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user