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