Update to 113.0
This commit is contained in:
parent
d5f2b2028f
commit
e81ff02c0f
2
.gitignore
vendored
2
.gitignore
vendored
@ -571,3 +571,5 @@ firefox-3.6.4.source.tar.bz2
|
|||||||
/firefox-112.0.1.source.tar.xz
|
/firefox-112.0.1.source.tar.xz
|
||||||
/firefox-langpacks-112.0.2-20230427.tar.xz
|
/firefox-langpacks-112.0.2-20230427.tar.xz
|
||||||
/firefox-112.0.2.source.tar.xz
|
/firefox-112.0.2.source.tar.xz
|
||||||
|
/firefox-langpacks-113.0-20230509.tar.xz
|
||||||
|
/firefox-113.0.source.tar.xz
|
||||||
|
22
D172126.diff
22
D172126.diff
@ -1,22 +0,0 @@
|
|||||||
diff --git a/dom/media/webaudio/AudioNodeEngineGeneric.h b/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
--- a/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
@@ -203,14 +203,14 @@
|
|
||||||
MOZ_ASSERT((aSize % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
"requires tail processing");
|
|
||||||
|
|
||||||
MOZ_UNROLL(2)
|
|
||||||
for (unsigned i = 0; i < aSize * 2;
|
|
||||||
- i += 2 * xsimd::batch<std::complex<float>>::size) {
|
|
||||||
- auto in1 = xsimd::batch<std::complex<float>>::load_aligned(
|
|
||||||
+ i += 2 * xsimd::batch<std::complex<float>, Arch>::size) {
|
|
||||||
+ auto in1 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
reinterpret_cast<const std::complex<float>*>(&aInput[i]));
|
|
||||||
- auto in2 = xsimd::batch<std::complex<float>>::load_aligned(
|
|
||||||
+ auto in2 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
reinterpret_cast<const std::complex<float>*>(&aScale[i]));
|
|
||||||
auto out = in1 * in2;
|
|
||||||
out.store_aligned(reinterpret_cast<std::complex<float>*>(&aOutput[i]));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
736
D172864.diff
736
D172864.diff
@ -1,736 +0,0 @@
|
|||||||
diff --git a/dom/media/webaudio/AudioNodeEngineGeneric.h b/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
--- a/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineGeneric.h
|
|
||||||
@@ -5,331 +5,54 @@
|
|
||||||
|
|
||||||
#ifndef MOZILLA_AUDIONODEENGINEGENERIC_H_
|
|
||||||
#define MOZILLA_AUDIONODEENGINEGENERIC_H_
|
|
||||||
|
|
||||||
#include "AudioNodeEngine.h"
|
|
||||||
-#include "AlignmentUtils.h"
|
|
||||||
|
|
||||||
#include "xsimd/xsimd.hpp"
|
|
||||||
|
|
||||||
-#if defined(__GNUC__) && __GNUC__ > 7
|
|
||||||
-# define MOZ_PRAGMA(tokens) _Pragma(#tokens)
|
|
||||||
-# define MOZ_UNROLL(factor) MOZ_PRAGMA(GCC unroll factor)
|
|
||||||
-#elif defined(__INTEL_COMPILER) || (defined(__clang__) && __clang_major__ > 3)
|
|
||||||
-# define MOZ_PRAGMA(tokens) _Pragma(#tokens)
|
|
||||||
-# define MOZ_UNROLL(factor) MOZ_PRAGMA(unroll factor)
|
|
||||||
-#else
|
|
||||||
-# define MOZ_UNROLL(_)
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
template <class Arch>
|
|
||||||
-static bool is_aligned(const void* ptr) {
|
|
||||||
- return (reinterpret_cast<uintptr_t>(ptr) &
|
|
||||||
- ~(static_cast<uintptr_t>(Arch::alignment()) - 1)) ==
|
|
||||||
- reinterpret_cast<uintptr_t>(ptr);
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-template <class Arch>
|
|
||||||
struct Engine {
|
|
||||||
static void AudioBufferAddWithScale(const float* aInput, float aScale,
|
|
||||||
- float* aOutput, uint32_t aSize) {
|
|
||||||
- if constexpr (Arch::requires_alignment()) {
|
|
||||||
- if (aScale == 1.0f) {
|
|
||||||
- while (!is_aligned<Arch>(aInput) || !is_aligned<Arch>(aOutput)) {
|
|
||||||
- if (!aSize) return;
|
|
||||||
- *aOutput += *aInput;
|
|
||||||
- ++aOutput;
|
|
||||||
- ++aInput;
|
|
||||||
- --aSize;
|
|
||||||
- }
|
|
||||||
- } else {
|
|
||||||
- while (!is_aligned<Arch>(aInput) || !is_aligned<Arch>(aOutput)) {
|
|
||||||
- if (!aSize) return;
|
|
||||||
- *aOutput += *aInput * aScale;
|
|
||||||
- ++aOutput;
|
|
||||||
- ++aInput;
|
|
||||||
- --aSize;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
-
|
|
||||||
- xsimd::batch<float, Arch> vgain(aScale);
|
|
||||||
-
|
|
||||||
- uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vin1 = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
- auto vin2 = xsimd::batch<float, Arch>::load_aligned(&aOutput[i]);
|
|
||||||
- auto vout = xsimd::fma(vin1, vgain, vin2);
|
|
||||||
- vout.store_aligned(&aOutput[i]);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- for (unsigned i = aVSize; i < aSize; ++i) {
|
|
||||||
- aOutput[i] += aInput[i] * aScale;
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ float* aOutput, uint32_t aSize);
|
|
||||||
|
|
||||||
static void AudioBlockCopyChannelWithScale(const float* aInput, float aScale,
|
|
||||||
- float* aOutput) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
- "requires tail processing");
|
|
||||||
-
|
|
||||||
- xsimd::batch<float, Arch> vgain = (aScale);
|
|
||||||
-
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
- i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vin = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
- auto vout = vin * vgain;
|
|
||||||
- vout.store_aligned(&aOutput[i]);
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ float* aOutput);
|
|
||||||
|
|
||||||
static void AudioBlockCopyChannelWithScale(
|
|
||||||
const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const float aScale[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
- float aOutput[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
- "requires tail processing");
|
|
||||||
-
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
- i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vscaled = xsimd::batch<float, Arch>::load_aligned(&aScale[i]);
|
|
||||||
- auto vin = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
- auto vout = vin * vscaled;
|
|
||||||
- vout.store_aligned(&aOutput[i]);
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ float aOutput[WEBAUDIO_BLOCK_SIZE]);
|
|
||||||
|
|
||||||
static void AudioBufferInPlaceScale(float* aBlock, float aScale,
|
|
||||||
- uint32_t aSize) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aBlock), "aBlock is aligned");
|
|
||||||
-
|
|
||||||
- xsimd::batch<float, Arch> vgain(aScale);
|
|
||||||
-
|
|
||||||
- uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vin = xsimd::batch<float, Arch>::load_aligned(&aBlock[i]);
|
|
||||||
- auto vout = vin * vgain;
|
|
||||||
- vout.store_aligned(&aBlock[i]);
|
|
||||||
- }
|
|
||||||
- for (unsigned i = aVSize; i < aSize; ++i) aBlock[i] *= aScale;
|
|
||||||
- };
|
|
||||||
+ uint32_t aSize);
|
|
||||||
|
|
||||||
static void AudioBufferInPlaceScale(float* aBlock, float* aScale,
|
|
||||||
- uint32_t aSize) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aBlock), "aBlock is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
-
|
|
||||||
- uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vin = xsimd::batch<float, Arch>::load_aligned(&aBlock[i]);
|
|
||||||
- auto vgain = xsimd::batch<float, Arch>::load_aligned(&aScale[i]);
|
|
||||||
- auto vout = vin * vgain;
|
|
||||||
- vout.store_aligned(&aBlock[i]);
|
|
||||||
- }
|
|
||||||
- for (uint32_t i = aVSize; i < aSize; ++i) {
|
|
||||||
- *aBlock++ *= *aScale++;
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ uint32_t aSize);
|
|
||||||
|
|
||||||
static void AudioBlockPanStereoToStereo(
|
|
||||||
const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const float aInputR[WEBAUDIO_BLOCK_SIZE], float aGainL, float aGainR,
|
|
||||||
bool aIsOnTheLeft, float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
- float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInputL), "aInputL is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInputR), "aInputR is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutputL), "aOutputL is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutputR), "aOutputR is aligned");
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
- "requires tail processing");
|
|
||||||
-
|
|
||||||
- xsimd::batch<float, Arch> vgainl(aGainL);
|
|
||||||
- xsimd::batch<float, Arch> vgainr(aGainR);
|
|
||||||
-
|
|
||||||
- if (aIsOnTheLeft) {
|
|
||||||
- MOZ_UNROLL(2)
|
|
||||||
- for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
- i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vinl = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
- auto vinr = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
-
|
|
||||||
- /* left channel : aOutputL = aInputL + aInputR * gainL */
|
|
||||||
- auto vout = xsimd::fma(vinr, vgainl, vinl);
|
|
||||||
- vout.store_aligned(&aOutputL[i]);
|
|
||||||
-
|
|
||||||
- /* right channel : aOutputR = aInputR * gainR */
|
|
||||||
- auto vscaled = vinr * vgainr;
|
|
||||||
- vscaled.store_aligned(&aOutputR[i]);
|
|
||||||
- }
|
|
||||||
- } else {
|
|
||||||
- MOZ_UNROLL(2)
|
|
||||||
- for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
- i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vinl = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
- auto vinr = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
-
|
|
||||||
- /* left channel : aInputL * gainL */
|
|
||||||
- auto vscaled = vinl * vgainl;
|
|
||||||
- vscaled.store_aligned(&aOutputL[i]);
|
|
||||||
-
|
|
||||||
- /* right channel: aOutputR = aInputR + aInputL * gainR */
|
|
||||||
- auto vout = xsimd::fma(vinl, vgainr, vinr);
|
|
||||||
- vout.store_aligned(&aOutputR[i]);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
||||||
|
|
||||||
static void BufferComplexMultiply(const float* aInput, const float* aScale,
|
|
||||||
- float* aOutput, uint32_t aSize) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
- MOZ_ASSERT((aSize % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
- "requires tail processing");
|
|
||||||
-
|
|
||||||
- MOZ_UNROLL(2)
|
|
||||||
- for (unsigned i = 0; i < aSize * 2;
|
|
||||||
- i += 2 * xsimd::batch<std::complex<float>, Arch>::size) {
|
|
||||||
- auto in1 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
- reinterpret_cast<const std::complex<float>*>(&aInput[i]));
|
|
||||||
- auto in2 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
- reinterpret_cast<const std::complex<float>*>(&aScale[i]));
|
|
||||||
- auto out = in1 * in2;
|
|
||||||
- out.store_aligned(reinterpret_cast<std::complex<float>*>(&aOutput[i]));
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
-
|
|
||||||
- static float AudioBufferSumOfSquares(const float* aInput, uint32_t aLength) {
|
|
||||||
- float sum = 0.f;
|
|
||||||
-
|
|
||||||
- if constexpr (Arch::requires_alignment()) {
|
|
||||||
- while (!is_aligned<Arch>(aInput)) {
|
|
||||||
- if (!aLength) {
|
|
||||||
- return sum;
|
|
||||||
- }
|
|
||||||
- sum += *aInput * *aInput;
|
|
||||||
- ++aInput;
|
|
||||||
- --aLength;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
-
|
|
||||||
- constexpr uint32_t unroll_factor = 4;
|
|
||||||
- xsimd::batch<float, Arch> accs[unroll_factor] = {0.f, 0.f, 0.f, 0.f};
|
|
||||||
-
|
|
||||||
- uint32_t vLength =
|
|
||||||
- aLength & ~(unroll_factor * xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+ float* aOutput, uint32_t aSize);
|
|
||||||
|
|
||||||
- for (uint32_t i = 0; i < vLength;
|
|
||||||
- i += unroll_factor * xsimd::batch<float, Arch>::size) {
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (uint32_t j = 0; j < unroll_factor; ++j) {
|
|
||||||
- auto in = xsimd::batch<float, Arch>::load_aligned(
|
|
||||||
- &aInput[i + xsimd::batch<float, Arch>::size * j]);
|
|
||||||
- accs[j] = xsimd::fma(in, in, accs[j]);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- sum += reduce_add((accs[0] + accs[1]) + (accs[2] + accs[3]));
|
|
||||||
- for (uint32_t i = vLength; i < aLength; ++i) sum += aInput[i] * aInput[i];
|
|
||||||
- return sum;
|
|
||||||
- };
|
|
||||||
+ static float AudioBufferSumOfSquares(const float* aInput, uint32_t aLength);
|
|
||||||
|
|
||||||
- static void NaNToZeroInPlace(float* aSamples, size_t aCount) {
|
|
||||||
- if constexpr (Arch::requires_alignment()) {
|
|
||||||
- while (!is_aligned<Arch>(aSamples)) {
|
|
||||||
- if (!aCount) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
- if (*aSamples != *aSamples) {
|
|
||||||
- *aSamples = 0.0;
|
|
||||||
- }
|
|
||||||
- ++aSamples;
|
|
||||||
- --aCount;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aSamples), "aSamples is aligned");
|
|
||||||
-
|
|
||||||
- uint32_t vCount = aCount & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
-
|
|
||||||
- MOZ_UNROLL(4)
|
|
||||||
- for (uint32_t i = 0; i < vCount; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto vin = xsimd::batch<float, Arch>::load_aligned(&aSamples[i]);
|
|
||||||
- auto vout =
|
|
||||||
- xsimd::select(xsimd::isnan(vin), xsimd::batch<float, Arch>(0.f), vin);
|
|
||||||
- vout.store_aligned(&aSamples[i]);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- for (uint32_t i = vCount; i < aCount; i++) {
|
|
||||||
- if (aSamples[i] != aSamples[i]) {
|
|
||||||
- aSamples[i] = 0.0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- };
|
|
||||||
+ static void NaNToZeroInPlace(float* aSamples, size_t aCount);
|
|
||||||
|
|
||||||
static void AudioBlockPanStereoToStereo(
|
|
||||||
const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const float aGainL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const float aGainR[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
const bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
- float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
- float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInputL), "aInputL is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aInputR), "aInputR is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aGainL), "aGainL is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aGainR), "aGainR is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aIsOnTheLeft), "aIsOnTheLeft is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutputL), "aOutputL is aligned");
|
|
||||||
- MOZ_ASSERT(is_aligned<Arch>(aOutputR), "aOutputR is aligned");
|
|
||||||
-
|
|
||||||
- MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
- "requires tail processing");
|
|
||||||
-
|
|
||||||
- MOZ_UNROLL(2)
|
|
||||||
- for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
- i += xsimd::batch<float, Arch>::size) {
|
|
||||||
- auto mask =
|
|
||||||
- xsimd::batch_bool<float, Arch>::load_aligned(&aIsOnTheLeft[i]);
|
|
||||||
-
|
|
||||||
- auto inputL = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
- auto inputR = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
- auto gainL = xsimd::batch<float, Arch>::load_aligned(&aGainL[i]);
|
|
||||||
- auto gainR = xsimd::batch<float, Arch>::load_aligned(&aGainR[i]);
|
|
||||||
-
|
|
||||||
- auto outL_true = xsimd::fma(inputR, gainL, inputL);
|
|
||||||
- auto outR_true = inputR * gainR;
|
|
||||||
-
|
|
||||||
- auto outL_false = inputL * gainL;
|
|
||||||
- auto outR_false = xsimd::fma(inputL, gainR, inputR);
|
|
||||||
-
|
|
||||||
- auto outL = xsimd::select(mask, outL_true, outL_false);
|
|
||||||
- auto outR = xsimd::select(mask, outR_true, outR_false);
|
|
||||||
-
|
|
||||||
- outL.store_aligned(&aOutputL[i]);
|
|
||||||
- outR.store_aligned(&aOutputR[i]);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ float aOutputL[WEBAUDIO_BLOCK_SIZE], float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif
|
|
||||||
diff --git a/dom/media/webaudio/AudioNodeEngineGenericImpl.h b/dom/media/webaudio/AudioNodeEngineGenericImpl.h
|
|
||||||
new file mode 100644
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineGenericImpl.h
|
|
||||||
@@ -0,0 +1,341 @@
|
|
||||||
+/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
+/* this source code form is subject to the terms of the mozilla public
|
|
||||||
+ * license, v. 2.0. if a copy of the mpl was not distributed with this file,
|
|
||||||
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
+
|
|
||||||
+#ifndef MOZILLA_AUDIONODEENGINEGENERICIMPL_H_
|
|
||||||
+#define MOZILLA_AUDIONODEENGINEGENERICIMPL_H_
|
|
||||||
+
|
|
||||||
+#include "AudioNodeEngineGeneric.h"
|
|
||||||
+#include "AlignmentUtils.h"
|
|
||||||
+
|
|
||||||
+#if defined(__GNUC__) && __GNUC__ > 7
|
|
||||||
+# define MOZ_PRAGMA(tokens) _Pragma(#tokens)
|
|
||||||
+# define MOZ_UNROLL(factor) MOZ_PRAGMA(GCC unroll factor)
|
|
||||||
+#elif defined(__INTEL_COMPILER) || (defined(__clang__) && __clang_major__ > 3)
|
|
||||||
+# define MOZ_PRAGMA(tokens) _Pragma(#tokens)
|
|
||||||
+# define MOZ_UNROLL(factor) MOZ_PRAGMA(unroll factor)
|
|
||||||
+#else
|
|
||||||
+# define MOZ_UNROLL(_)
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+namespace mozilla {
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+static bool is_aligned(const void* ptr) {
|
|
||||||
+ return (reinterpret_cast<uintptr_t>(ptr) &
|
|
||||||
+ ~(static_cast<uintptr_t>(Arch::alignment()) - 1)) ==
|
|
||||||
+ reinterpret_cast<uintptr_t>(ptr);
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBufferAddWithScale(const float* aInput, float aScale,
|
|
||||||
+ float* aOutput, uint32_t aSize) {
|
|
||||||
+ if constexpr (Arch::requires_alignment()) {
|
|
||||||
+ if (aScale == 1.0f) {
|
|
||||||
+ while (!is_aligned<Arch>(aInput) || !is_aligned<Arch>(aOutput)) {
|
|
||||||
+ if (!aSize) return;
|
|
||||||
+ *aOutput += *aInput;
|
|
||||||
+ ++aOutput;
|
|
||||||
+ ++aInput;
|
|
||||||
+ --aSize;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ while (!is_aligned<Arch>(aInput) || !is_aligned<Arch>(aOutput)) {
|
|
||||||
+ if (!aSize) return;
|
|
||||||
+ *aOutput += *aInput * aScale;
|
|
||||||
+ ++aOutput;
|
|
||||||
+ ++aInput;
|
|
||||||
+ --aSize;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
+
|
|
||||||
+ xsimd::batch<float, Arch> vgain(aScale);
|
|
||||||
+
|
|
||||||
+ uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vin1 = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
+ auto vin2 = xsimd::batch<float, Arch>::load_aligned(&aOutput[i]);
|
|
||||||
+ auto vout = xsimd::fma(vin1, vgain, vin2);
|
|
||||||
+ vout.store_aligned(&aOutput[i]);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (unsigned i = aVSize; i < aSize; ++i) {
|
|
||||||
+ aOutput[i] += aInput[i] * aScale;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBlockCopyChannelWithScale(const float* aInput,
|
|
||||||
+ float aScale,
|
|
||||||
+ float* aOutput) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
+ "requires tail processing");
|
|
||||||
+
|
|
||||||
+ xsimd::batch<float, Arch> vgain = (aScale);
|
|
||||||
+
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
+ i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vin = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
+ auto vout = vin * vgain;
|
|
||||||
+ vout.store_aligned(&aOutput[i]);
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBlockCopyChannelWithScale(
|
|
||||||
+ const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const float aScale[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ float aOutput[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
+ "requires tail processing");
|
|
||||||
+
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
+ i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vscaled = xsimd::batch<float, Arch>::load_aligned(&aScale[i]);
|
|
||||||
+ auto vin = xsimd::batch<float, Arch>::load_aligned(&aInput[i]);
|
|
||||||
+ auto vout = vin * vscaled;
|
|
||||||
+ vout.store_aligned(&aOutput[i]);
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBufferInPlaceScale(float* aBlock, float aScale,
|
|
||||||
+ uint32_t aSize) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aBlock), "aBlock is aligned");
|
|
||||||
+
|
|
||||||
+ xsimd::batch<float, Arch> vgain(aScale);
|
|
||||||
+
|
|
||||||
+ uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vin = xsimd::batch<float, Arch>::load_aligned(&aBlock[i]);
|
|
||||||
+ auto vout = vin * vgain;
|
|
||||||
+ vout.store_aligned(&aBlock[i]);
|
|
||||||
+ }
|
|
||||||
+ for (unsigned i = aVSize; i < aSize; ++i) aBlock[i] *= aScale;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBufferInPlaceScale(float* aBlock, float* aScale,
|
|
||||||
+ uint32_t aSize) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aBlock), "aBlock is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
+
|
|
||||||
+ uint32_t aVSize = aSize & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (unsigned i = 0; i < aVSize; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vin = xsimd::batch<float, Arch>::load_aligned(&aBlock[i]);
|
|
||||||
+ auto vgain = xsimd::batch<float, Arch>::load_aligned(&aScale[i]);
|
|
||||||
+ auto vout = vin * vgain;
|
|
||||||
+ vout.store_aligned(&aBlock[i]);
|
|
||||||
+ }
|
|
||||||
+ for (uint32_t i = aVSize; i < aSize; ++i) {
|
|
||||||
+ *aBlock++ *= *aScale++;
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBlockPanStereoToStereo(
|
|
||||||
+ const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const float aInputR[WEBAUDIO_BLOCK_SIZE], float aGainL, float aGainR,
|
|
||||||
+ bool aIsOnTheLeft, float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInputL), "aInputL is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInputR), "aInputR is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutputL), "aOutputL is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutputR), "aOutputR is aligned");
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
+ "requires tail processing");
|
|
||||||
+
|
|
||||||
+ xsimd::batch<float, Arch> vgainl(aGainL);
|
|
||||||
+ xsimd::batch<float, Arch> vgainr(aGainR);
|
|
||||||
+
|
|
||||||
+ if (aIsOnTheLeft) {
|
|
||||||
+ MOZ_UNROLL(2)
|
|
||||||
+ for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
+ i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vinl = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
+ auto vinr = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
+
|
|
||||||
+ /* left channel : aOutputL = aInputL + aInputR * gainL */
|
|
||||||
+ auto vout = xsimd::fma(vinr, vgainl, vinl);
|
|
||||||
+ vout.store_aligned(&aOutputL[i]);
|
|
||||||
+
|
|
||||||
+ /* right channel : aOutputR = aInputR * gainR */
|
|
||||||
+ auto vscaled = vinr * vgainr;
|
|
||||||
+ vscaled.store_aligned(&aOutputR[i]);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ MOZ_UNROLL(2)
|
|
||||||
+ for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
+ i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vinl = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
+ auto vinr = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
+
|
|
||||||
+ /* left channel : aInputL * gainL */
|
|
||||||
+ auto vscaled = vinl * vgainl;
|
|
||||||
+ vscaled.store_aligned(&aOutputL[i]);
|
|
||||||
+
|
|
||||||
+ /* right channel: aOutputR = aInputR + aInputL * gainR */
|
|
||||||
+ auto vout = xsimd::fma(vinl, vgainr, vinr);
|
|
||||||
+ vout.store_aligned(&aOutputR[i]);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::BufferComplexMultiply(const float* aInput,
|
|
||||||
+ const float* aScale, float* aOutput,
|
|
||||||
+ uint32_t aSize) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutput), "aOutput is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aScale), "aScale is aligned");
|
|
||||||
+ MOZ_ASSERT((aSize % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
+ "requires tail processing");
|
|
||||||
+
|
|
||||||
+ MOZ_UNROLL(2)
|
|
||||||
+ for (unsigned i = 0; i < aSize * 2;
|
|
||||||
+ i += 2 * xsimd::batch<std::complex<float>, Arch>::size) {
|
|
||||||
+ auto in1 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
+ reinterpret_cast<const std::complex<float>*>(&aInput[i]));
|
|
||||||
+ auto in2 = xsimd::batch<std::complex<float>, Arch>::load_aligned(
|
|
||||||
+ reinterpret_cast<const std::complex<float>*>(&aScale[i]));
|
|
||||||
+ auto out = in1 * in2;
|
|
||||||
+ out.store_aligned(reinterpret_cast<std::complex<float>*>(&aOutput[i]));
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+float Engine<Arch>::AudioBufferSumOfSquares(const float* aInput,
|
|
||||||
+ uint32_t aLength) {
|
|
||||||
+ float sum = 0.f;
|
|
||||||
+
|
|
||||||
+ if constexpr (Arch::requires_alignment()) {
|
|
||||||
+ while (!is_aligned<Arch>(aInput)) {
|
|
||||||
+ if (!aLength) {
|
|
||||||
+ return sum;
|
|
||||||
+ }
|
|
||||||
+ sum += *aInput * *aInput;
|
|
||||||
+ ++aInput;
|
|
||||||
+ --aLength;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInput), "aInput is aligned");
|
|
||||||
+
|
|
||||||
+ constexpr uint32_t unroll_factor = 4;
|
|
||||||
+ xsimd::batch<float, Arch> accs[unroll_factor] = {0.f, 0.f, 0.f, 0.f};
|
|
||||||
+
|
|
||||||
+ uint32_t vLength =
|
|
||||||
+ aLength & ~(unroll_factor * xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+
|
|
||||||
+ for (uint32_t i = 0; i < vLength;
|
|
||||||
+ i += unroll_factor * xsimd::batch<float, Arch>::size) {
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (uint32_t j = 0; j < unroll_factor; ++j) {
|
|
||||||
+ auto in = xsimd::batch<float, Arch>::load_aligned(
|
|
||||||
+ &aInput[i + xsimd::batch<float, Arch>::size * j]);
|
|
||||||
+ accs[j] = xsimd::fma(in, in, accs[j]);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ sum += reduce_add((accs[0] + accs[1]) + (accs[2] + accs[3]));
|
|
||||||
+ for (uint32_t i = vLength; i < aLength; ++i) sum += aInput[i] * aInput[i];
|
|
||||||
+ return sum;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::NaNToZeroInPlace(float* aSamples, size_t aCount) {
|
|
||||||
+ if constexpr (Arch::requires_alignment()) {
|
|
||||||
+ while (!is_aligned<Arch>(aSamples)) {
|
|
||||||
+ if (!aCount) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ if (*aSamples != *aSamples) {
|
|
||||||
+ *aSamples = 0.0;
|
|
||||||
+ }
|
|
||||||
+ ++aSamples;
|
|
||||||
+ --aCount;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aSamples), "aSamples is aligned");
|
|
||||||
+
|
|
||||||
+ uint32_t vCount = aCount & ~(xsimd::batch<float, Arch>::size - 1);
|
|
||||||
+
|
|
||||||
+ MOZ_UNROLL(4)
|
|
||||||
+ for (uint32_t i = 0; i < vCount; i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto vin = xsimd::batch<float, Arch>::load_aligned(&aSamples[i]);
|
|
||||||
+ auto vout =
|
|
||||||
+ xsimd::select(xsimd::isnan(vin), xsimd::batch<float, Arch>(0.f), vin);
|
|
||||||
+ vout.store_aligned(&aSamples[i]);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (uint32_t i = vCount; i < aCount; i++) {
|
|
||||||
+ if (aSamples[i] != aSamples[i]) {
|
|
||||||
+ aSamples[i] = 0.0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+template <class Arch>
|
|
||||||
+void Engine<Arch>::AudioBlockPanStereoToStereo(
|
|
||||||
+ const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const float aGainL[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const float aGainR[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ const bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
|
|
||||||
+ float aOutputL[WEBAUDIO_BLOCK_SIZE], float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInputL), "aInputL is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aInputR), "aInputR is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aGainL), "aGainL is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aGainR), "aGainR is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aIsOnTheLeft), "aIsOnTheLeft is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutputL), "aOutputL is aligned");
|
|
||||||
+ MOZ_ASSERT(is_aligned<Arch>(aOutputR), "aOutputR is aligned");
|
|
||||||
+
|
|
||||||
+ MOZ_ASSERT((WEBAUDIO_BLOCK_SIZE % xsimd::batch<float, Arch>::size == 0),
|
|
||||||
+ "requires tail processing");
|
|
||||||
+
|
|
||||||
+ MOZ_UNROLL(2)
|
|
||||||
+ for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE;
|
|
||||||
+ i += xsimd::batch<float, Arch>::size) {
|
|
||||||
+ auto mask = xsimd::batch_bool<float, Arch>::load_aligned(&aIsOnTheLeft[i]);
|
|
||||||
+
|
|
||||||
+ auto inputL = xsimd::batch<float, Arch>::load_aligned(&aInputL[i]);
|
|
||||||
+ auto inputR = xsimd::batch<float, Arch>::load_aligned(&aInputR[i]);
|
|
||||||
+ auto gainL = xsimd::batch<float, Arch>::load_aligned(&aGainL[i]);
|
|
||||||
+ auto gainR = xsimd::batch<float, Arch>::load_aligned(&aGainR[i]);
|
|
||||||
+
|
|
||||||
+ auto outL_true = xsimd::fma(inputR, gainL, inputL);
|
|
||||||
+ auto outR_true = inputR * gainR;
|
|
||||||
+
|
|
||||||
+ auto outL_false = inputL * gainL;
|
|
||||||
+ auto outR_false = xsimd::fma(inputL, gainR, inputR);
|
|
||||||
+
|
|
||||||
+ auto outL = xsimd::select(mask, outL_true, outL_false);
|
|
||||||
+ auto outR = xsimd::select(mask, outR_true, outR_false);
|
|
||||||
+
|
|
||||||
+ outL.store_aligned(&aOutputL[i]);
|
|
||||||
+ outR.store_aligned(&aOutputR[i]);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+} // namespace mozilla
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
diff --git a/dom/media/webaudio/AudioNodeEngineNEON.cpp b/dom/media/webaudio/AudioNodeEngineNEON.cpp
|
|
||||||
--- a/dom/media/webaudio/AudioNodeEngineNEON.cpp
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineNEON.cpp
|
|
||||||
@@ -1,9 +1,9 @@
|
|
||||||
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* this source code form is subject to the terms of the mozilla public
|
|
||||||
* license, v. 2.0. if a copy of the mpl was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
-#include "AudioNodeEngineGeneric.h"
|
|
||||||
+#include "AudioNodeEngineGenericImpl.h"
|
|
||||||
namespace mozilla {
|
|
||||||
template struct Engine<xsimd::neon>;
|
|
||||||
} // namespace mozilla
|
|
||||||
diff --git a/dom/media/webaudio/AudioNodeEngineSSE2.cpp b/dom/media/webaudio/AudioNodeEngineSSE2.cpp
|
|
||||||
--- a/dom/media/webaudio/AudioNodeEngineSSE2.cpp
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineSSE2.cpp
|
|
||||||
@@ -1,10 +1,10 @@
|
|
||||||
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* this source code form is subject to the terms of the mozilla public
|
|
||||||
* license, v. 2.0. if a copy of the mpl was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
-#include "AudioNodeEngineGeneric.h"
|
|
||||||
+#include "AudioNodeEngineGenericImpl.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
template struct Engine<xsimd::sse2>;
|
|
||||||
} // namespace mozilla
|
|
||||||
diff --git a/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp b/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp
|
|
||||||
--- a/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp
|
|
||||||
+++ b/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp
|
|
||||||
@@ -1,10 +1,10 @@
|
|
||||||
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* this source code form is subject to the terms of the mozilla public
|
|
||||||
* license, v. 2.0. if a copy of the mpl was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
-#include "AudioNodeEngineGeneric.h"
|
|
||||||
+#include "AudioNodeEngineGenericImpl.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
template struct Engine<xsimd::fma3<xsimd::sse4_2>>;
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
82
D173814.diff
82
D173814.diff
@ -1,82 +0,0 @@
|
|||||||
diff --git a/widget/gtk/MozContainerWayland.h b/widget/gtk/MozContainerWayland.h
|
|
||||||
--- a/widget/gtk/MozContainerWayland.h
|
|
||||||
+++ b/widget/gtk/MozContainerWayland.h
|
|
||||||
@@ -83,10 +83,13 @@
|
|
||||||
nsIntSize aSize,
|
|
||||||
int scale);
|
|
||||||
void moz_container_wayland_set_scale_factor(MozContainer* container);
|
|
||||||
void moz_container_wayland_set_scale_factor_locked(
|
|
||||||
const mozilla::MutexAutoLock& aProofOfLock, MozContainer* container);
|
|
||||||
+bool moz_container_wayland_size_matches_scale_factor_locked(
|
|
||||||
+ const mozilla::MutexAutoLock& aProofOfLock, MozContainer* container,
|
|
||||||
+ int aWidth, int aHeight);
|
|
||||||
|
|
||||||
void moz_container_wayland_add_initial_draw_callback_locked(
|
|
||||||
MozContainer* container, const std::function<void(void)>& initial_draw_cb);
|
|
||||||
void moz_container_wayland_add_or_fire_initial_draw_callback(
|
|
||||||
MozContainer* container, const std::function<void(void)>& initial_draw_cb);
|
|
||||||
diff --git a/widget/gtk/MozContainerWayland.cpp b/widget/gtk/MozContainerWayland.cpp
|
|
||||||
--- a/widget/gtk/MozContainerWayland.cpp
|
|
||||||
+++ b/widget/gtk/MozContainerWayland.cpp
|
|
||||||
@@ -595,10 +595,17 @@
|
|
||||||
if (container->wl_container.surface) {
|
|
||||||
moz_container_wayland_set_scale_factor_locked(lock, container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+bool moz_container_wayland_size_matches_scale_factor_locked(
|
|
||||||
+ const MutexAutoLock& aProofOfLock, MozContainer* container, int aWidth,
|
|
||||||
+ int aHeight) {
|
|
||||||
+ return aWidth % container->wl_container.buffer_scale == 0 &&
|
|
||||||
+ aHeight % container->wl_container.buffer_scale == 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static bool moz_container_wayland_surface_create_locked(
|
|
||||||
const MutexAutoLock& aProofOfLock, MozContainer* container) {
|
|
||||||
MozContainerWayland* wl_container = &container->wl_container;
|
|
||||||
|
|
||||||
LOGWAYLAND("%s [%p]\n", __FUNCTION__,
|
|
||||||
diff --git a/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp b/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
|
|
||||||
--- a/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
|
|
||||||
+++ b/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
|
|
||||||
@@ -283,12 +283,12 @@
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mFrameInProcess = false;
|
|
||||||
|
|
||||||
MozContainer* container = mWindow->GetMozContainer();
|
|
||||||
- MozContainerSurfaceLock lock(container);
|
|
||||||
- struct wl_surface* waylandSurface = lock.GetSurface();
|
|
||||||
+ MozContainerSurfaceLock MozContainerLock(container);
|
|
||||||
+ struct wl_surface* waylandSurface = MozContainerLock.GetSurface();
|
|
||||||
if (!waylandSurface) {
|
|
||||||
LOGWAYLAND(
|
|
||||||
"WindowSurfaceWaylandMB::Commit [%p] frame queued: can't lock "
|
|
||||||
"wl_surface\n",
|
|
||||||
(void*)mWindow.get());
|
|
||||||
@@ -317,12 +317,23 @@
|
|
||||||
LayoutDeviceIntRect r = iter.Get();
|
|
||||||
wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // aProofOfLock is a kind of substitution of MozContainerSurfaceLock.
|
|
||||||
+ // MozContainer is locked but MozContainerSurfaceLock doen't convert to
|
|
||||||
+ // MutexAutoLock& so we use aProofOfLock here.
|
|
||||||
moz_container_wayland_set_scale_factor_locked(aProofOfLock, container);
|
|
||||||
- mInProgressBuffer->AttachAndCommit(waylandSurface);
|
|
||||||
+
|
|
||||||
+ // It's possible that scale factor changed between Lock() and Commit()
|
|
||||||
+ // but window size is the same.
|
|
||||||
+ // Don't attach such buffer as it may have incorrect size,
|
|
||||||
+ // we'll paint new content soon.
|
|
||||||
+ if (moz_container_wayland_size_matches_scale_factor_locked(
|
|
||||||
+ aProofOfLock, container, mWindowSize.width, mWindowSize.height)) {
|
|
||||||
+ mInProgressBuffer->AttachAndCommit(waylandSurface);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
mInProgressBuffer->ResetBufferAge();
|
|
||||||
mFrontBuffer = mInProgressBuffer;
|
|
||||||
mFrontBufferInvalidRegion = aInvalidRegion;
|
|
||||||
mInProgressBuffer = nullptr;
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
diff -up firefox-112.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi firefox-112.0/widget/gtk/GfxInfo.cpp
|
diff -up firefox-113.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi firefox-113.0/widget/gtk/GfxInfo.cpp
|
||||||
--- firefox-112.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi 2023-04-05 11:10:14.156695694 +0200
|
--- firefox-113.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi 2023-05-09 19:43:38.495868810 +0200
|
||||||
+++ firefox-112.0/widget/gtk/GfxInfo.cpp 2023-04-05 11:11:40.697665718 +0200
|
+++ firefox-113.0/widget/gtk/GfxInfo.cpp 2023-05-09 19:44:30.943597984 +0200
|
||||||
@@ -810,14 +810,6 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
|
@@ -818,14 +818,6 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
|
||||||
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
|
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
|
||||||
V(0, 0, 0, 0), "FEATURE_HARDWARE_VIDEO_DECODING_NO_LINUX_AMD", "");
|
V(0, 0, 0, 0), "FEATURE_HARDWARE_VIDEO_DECODING_NO_R600", "");
|
||||||
|
|
||||||
- // Disable on Release/late Beta
|
- // Disable on Release/late Beta
|
||||||
-#if !defined(EARLY_BETA_OR_EARLIER)
|
-#if !defined(EARLY_BETA_OR_EARLIER)
|
||||||
|
24
firefox.spec
24
firefox.spec
@ -175,13 +175,13 @@ ExcludeArch: i686
|
|||||||
|
|
||||||
Summary: Mozilla Firefox Web browser
|
Summary: Mozilla Firefox Web browser
|
||||||
Name: firefox
|
Name: firefox
|
||||||
Version: 112.0.2
|
Version: 113.0
|
||||||
Release: 1%{?pre_tag}%{?dist}
|
Release: 1%{?pre_tag}%{?dist}
|
||||||
URL: https://www.mozilla.org/firefox/
|
URL: https://www.mozilla.org/firefox/
|
||||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
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
|
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
|
||||||
%if %{with langpacks}
|
%if %{with langpacks}
|
||||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20230427.tar.xz
|
Source1: firefox-langpacks-%{version}%{?pre_version}-20230509.tar.xz
|
||||||
%endif
|
%endif
|
||||||
Source2: cbindgen-vendor.tar.xz
|
Source2: cbindgen-vendor.tar.xz
|
||||||
Source10: firefox-mozconfig
|
Source10: firefox-mozconfig
|
||||||
@ -229,9 +229,6 @@ Patch61: firefox-glibc-dynstack.patch
|
|||||||
Patch71: 0001-GLIBCXX-fix-for-GCC-12.patch
|
Patch71: 0001-GLIBCXX-fix-for-GCC-12.patch
|
||||||
Patch78: firefox-i686-build.patch
|
Patch78: firefox-i686-build.patch
|
||||||
Patch79: firefox-gcc-13-build.patch
|
Patch79: firefox-gcc-13-build.patch
|
||||||
#Patch80: D172126.diff
|
|
||||||
#Patch81: D172864.diff
|
|
||||||
Patch83: D173814.diff
|
|
||||||
|
|
||||||
# Test patches
|
# Test patches
|
||||||
# Generate without context by
|
# Generate without context by
|
||||||
@ -253,10 +250,8 @@ Patch230: firefox-enable-vaapi.patch
|
|||||||
# Upstream patches
|
# Upstream patches
|
||||||
Patch402: mozilla-1196777.patch
|
Patch402: mozilla-1196777.patch
|
||||||
Patch407: mozilla-1667096.patch
|
Patch407: mozilla-1667096.patch
|
||||||
Patch408: mozilla-1663844.patch
|
# TODO: do we need it?
|
||||||
Patch415: mozilla-1670333.patch
|
#Patch415: mozilla-1670333.patch
|
||||||
# https://phabricator.services.mozilla.com/D173021
|
|
||||||
Patch416: libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch
|
|
||||||
|
|
||||||
# PGO/LTO patches
|
# PGO/LTO patches
|
||||||
Patch600: pgo.patch
|
Patch600: pgo.patch
|
||||||
@ -516,9 +511,6 @@ This package contains results of tests executed during build.
|
|||||||
%patch71 -p1 -b .0001-GLIBCXX-fix-for-GCC-12
|
%patch71 -p1 -b .0001-GLIBCXX-fix-for-GCC-12
|
||||||
%patch78 -p1 -b .firefox-i686
|
%patch78 -p1 -b .firefox-i686
|
||||||
%patch79 -p1 -b .firefox-gcc-13-build
|
%patch79 -p1 -b .firefox-gcc-13-build
|
||||||
#%patch80 -p1 -b .D172126
|
|
||||||
#%patch81 -p1 -b .D172864
|
|
||||||
%patch83 -p1 -b .D173814
|
|
||||||
|
|
||||||
# Test patches
|
# Test patches
|
||||||
#%patch100 -p1 -b .firefox-tests-xpcshell
|
#%patch100 -p1 -b .firefox-tests-xpcshell
|
||||||
@ -538,9 +530,8 @@ This package contains results of tests executed during build.
|
|||||||
|
|
||||||
%patch402 -p1 -b .1196777
|
%patch402 -p1 -b .1196777
|
||||||
%patch407 -p1 -b .1667096
|
%patch407 -p1 -b .1667096
|
||||||
%patch408 -p1 -b .1663844
|
# TODO: do we need it?
|
||||||
%patch415 -p1 -b .1670333
|
#%patch415 -p1 -b .1670333
|
||||||
%patch416 -p1 -b .libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame
|
|
||||||
|
|
||||||
# PGO patches
|
# PGO patches
|
||||||
%if %{build_with_pgo}
|
%if %{build_with_pgo}
|
||||||
@ -1091,6 +1082,9 @@ fi
|
|||||||
#---------------------------------------------------------------------
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue May 9 2023 Martin Stransky <stransky@redhat.com>- 113.0-1
|
||||||
|
- Updated to 113.0
|
||||||
|
|
||||||
* Thu Apr 27 2023 Martin Stransky <stransky@redhat.com>- 112.0.2-1
|
* Thu Apr 27 2023 Martin Stransky <stransky@redhat.com>- 112.0.2-1
|
||||||
- Updated to 112.0.2
|
- Updated to 112.0.2
|
||||||
|
|
||||||
|
@ -1,505 +0,0 @@
|
|||||||
From d9faa73cbbc186d7dd0dbfce0589012a0bed9f17 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jan Grulich <grulja@gmail.com>
|
|
||||||
Date: Fri, 17 Mar 2023 10:58:10 +0100
|
|
||||||
Subject: [PATCH] PipeWire capturer: import DMABufs directly into desktop frame
|
|
||||||
|
|
||||||
Originally DMABufs were imported into a temporary buffer followed by a
|
|
||||||
copy operation into the desktop frame itself. This is not needed as we
|
|
||||||
can import them directly into desktop frames and avoid this overhead.
|
|
||||||
|
|
||||||
Also drop support for MemPtr buffers as both Mutter and KWin don't seem
|
|
||||||
to support them and they are going to be too slow anyway.
|
|
||||||
|
|
||||||
Testing with latest Chromium, I could see two processes with usage around 20% and 40% without this change going down to 10% and 20% with
|
|
||||||
this change applied.
|
|
||||||
|
|
||||||
Bug: webrtc:13429
|
|
||||||
Bug: chrome:1378258
|
|
||||||
Change-Id: Ice3292528ff56300931c8638f8e03d4883d5e331
|
|
||||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/297501
|
|
||||||
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
|
|
||||||
Commit-Queue: Jan Grulich <grulja@gmail.com>
|
|
||||||
Cr-Commit-Position: refs/heads/main@{#39594}
|
|
||||||
---
|
|
||||||
|
|
||||||
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
|
|
||||||
index 5bbd5d7aba..b529077c6d 100644
|
|
||||||
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
|
|
||||||
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
|
|
||||||
@@ -101,11 +101,23 @@ typedef void (*glDeleteTextures_func)(GLsizei n, const GLuint* textures);
|
|
||||||
typedef void (*glGenTextures_func)(GLsizei n, GLuint* textures);
|
|
||||||
typedef GLenum (*glGetError_func)(void);
|
|
||||||
typedef const GLubyte* (*glGetString_func)(GLenum name);
|
|
||||||
-typedef void (*glGetTexImage_func)(GLenum target,
|
|
||||||
- GLint level,
|
|
||||||
- GLenum format,
|
|
||||||
- GLenum type,
|
|
||||||
- void* pixels);
|
|
||||||
+typedef void (*glReadPixels_func)(GLint x,
|
|
||||||
+ GLint y,
|
|
||||||
+ GLsizei width,
|
|
||||||
+ GLsizei height,
|
|
||||||
+ GLenum format,
|
|
||||||
+ GLenum type,
|
|
||||||
+ void* data);
|
|
||||||
+typedef void (*glGenFramebuffers_func)(GLsizei n, GLuint* ids);
|
|
||||||
+typedef void (*glDeleteFramebuffers_func)(GLsizei n,
|
|
||||||
+ const GLuint* framebuffers);
|
|
||||||
+typedef void (*glBindFramebuffer_func)(GLenum target, GLuint framebuffer);
|
|
||||||
+typedef void (*glFramebufferTexture2D_func)(GLenum target,
|
|
||||||
+ GLenum attachment,
|
|
||||||
+ GLenum textarget,
|
|
||||||
+ GLuint texture,
|
|
||||||
+ GLint level);
|
|
||||||
+typedef GLenum (*glCheckFramebufferStatus_func)(GLenum target);
|
|
||||||
typedef void (*glTexParameteri_func)(GLenum target, GLenum pname, GLint param);
|
|
||||||
typedef void* (*glXGetProcAddressARB_func)(const char*);
|
|
||||||
|
|
||||||
@@ -118,7 +130,12 @@ glDeleteTextures_func GlDeleteTextures = nullptr;
|
|
||||||
glGenTextures_func GlGenTextures = nullptr;
|
|
||||||
glGetError_func GlGetError = nullptr;
|
|
||||||
glGetString_func GlGetString = nullptr;
|
|
||||||
-glGetTexImage_func GlGetTexImage = nullptr;
|
|
||||||
+glReadPixels_func GlReadPixels = nullptr;
|
|
||||||
+glGenFramebuffers_func GlGenFramebuffers = nullptr;
|
|
||||||
+glDeleteFramebuffers_func GlDeleteFramebuffers = nullptr;
|
|
||||||
+glBindFramebuffer_func GlBindFramebuffer = nullptr;
|
|
||||||
+glFramebufferTexture2D_func GlFramebufferTexture2D = nullptr;
|
|
||||||
+glCheckFramebufferStatus_func GlCheckFramebufferStatus = nullptr;
|
|
||||||
glTexParameteri_func GlTexParameteri = nullptr;
|
|
||||||
glXGetProcAddressARB_func GlXGetProcAddressARB = nullptr;
|
|
||||||
|
|
||||||
@@ -279,12 +296,26 @@ static bool LoadGL() {
|
|
||||||
(glDeleteTextures_func)GlXGetProcAddressARB("glDeleteTextures");
|
|
||||||
GlGenTextures = (glGenTextures_func)GlXGetProcAddressARB("glGenTextures");
|
|
||||||
GlGetError = (glGetError_func)GlXGetProcAddressARB("glGetError");
|
|
||||||
- GlGetTexImage = (glGetTexImage_func)GlXGetProcAddressARB("glGetTexImage");
|
|
||||||
+ GlReadPixels = (glReadPixels_func)GlXGetProcAddressARB("glReadPixels");
|
|
||||||
+ GlGenFramebuffers =
|
|
||||||
+ (glGenFramebuffers_func)GlXGetProcAddressARB("glGenFramebuffers");
|
|
||||||
+ GlDeleteFramebuffers =
|
|
||||||
+ (glDeleteFramebuffers_func)GlXGetProcAddressARB("glDeleteFramebuffers");
|
|
||||||
+ GlBindFramebuffer =
|
|
||||||
+ (glBindFramebuffer_func)GlXGetProcAddressARB("glBindFramebuffer");
|
|
||||||
+ GlFramebufferTexture2D = (glFramebufferTexture2D_func)GlXGetProcAddressARB(
|
|
||||||
+ "glFramebufferTexture2D");
|
|
||||||
+ GlCheckFramebufferStatus =
|
|
||||||
+ (glCheckFramebufferStatus_func)GlXGetProcAddressARB(
|
|
||||||
+ "glCheckFramebufferStatus");
|
|
||||||
+
|
|
||||||
GlTexParameteri =
|
|
||||||
(glTexParameteri_func)GlXGetProcAddressARB("glTexParameteri");
|
|
||||||
|
|
||||||
return GlBindTexture && GlDeleteTextures && GlGenTextures && GlGetError &&
|
|
||||||
- GlGetTexImage && GlTexParameteri;
|
|
||||||
+ GlReadPixels && GlGenFramebuffers && GlDeleteFramebuffers &&
|
|
||||||
+ GlBindFramebuffer && GlFramebufferTexture2D &&
|
|
||||||
+ GlCheckFramebufferStatus && GlTexParameteri;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
@@ -435,6 +466,14 @@ EglDmaBuf::~EglDmaBuf() {
|
|
||||||
EglTerminate(egl_.display);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (fbo_) {
|
|
||||||
+ GlDeleteFramebuffers(1, &fbo_);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (texture_) {
|
|
||||||
+ GlDeleteTextures(1, &texture_);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// BUG: crbug.com/1290566
|
|
||||||
// Closing libEGL.so.1 when using NVidia drivers causes a crash
|
|
||||||
// when EglGetPlatformDisplayEXT() is used, at least this one is enough
|
|
||||||
@@ -466,20 +505,20 @@ bool EglDmaBuf::GetClientExtensions(EGLDisplay dpy, EGLint name) {
|
|
||||||
}
|
|
||||||
|
|
||||||
RTC_NO_SANITIZE("cfi-icall")
|
|
||||||
-std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
|
|
||||||
- const DesktopSize& size,
|
|
||||||
- uint32_t format,
|
|
||||||
- const std::vector<PlaneData>& plane_datas,
|
|
||||||
- uint64_t modifier) {
|
|
||||||
- std::unique_ptr<uint8_t[]> src;
|
|
||||||
-
|
|
||||||
+bool EglDmaBuf::ImageFromDmaBuf(const DesktopSize& size,
|
|
||||||
+ uint32_t format,
|
|
||||||
+ const std::vector<PlaneData>& plane_datas,
|
|
||||||
+ uint64_t modifier,
|
|
||||||
+ const DesktopVector& offset,
|
|
||||||
+ const DesktopSize& buffer_size,
|
|
||||||
+ uint8_t* data) {
|
|
||||||
if (!egl_initialized_) {
|
|
||||||
- return src;
|
|
||||||
+ return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plane_datas.size() <= 0) {
|
|
||||||
RTC_LOG(LS_ERROR) << "Failed to process buffer: invalid number of planes";
|
|
||||||
- return src;
|
|
||||||
+ return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGLint attribs[47];
|
|
||||||
@@ -568,20 +607,32 @@ std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
|
|
||||||
if (image == EGL_NO_IMAGE) {
|
|
||||||
RTC_LOG(LS_ERROR) << "Failed to record frame: Error creating EGLImage - "
|
|
||||||
<< FormatEGLError(EglGetError());
|
|
||||||
- return src;
|
|
||||||
+ return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create GL 2D texture for framebuffer
|
|
||||||
- GLuint texture;
|
|
||||||
- GlGenTextures(1, &texture);
|
|
||||||
- GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
- GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
- GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
- GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
- GlBindTexture(GL_TEXTURE_2D, texture);
|
|
||||||
+ if (!texture_) {
|
|
||||||
+ GlGenTextures(1, &texture_);
|
|
||||||
+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
+ }
|
|
||||||
+ GlBindTexture(GL_TEXTURE_2D, texture_);
|
|
||||||
GlEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
|
||||||
|
|
||||||
- src = std::make_unique<uint8_t[]>(plane_datas[0].stride * size.height());
|
|
||||||
+ if (!fbo_) {
|
|
||||||
+ GlGenFramebuffers(1, &fbo_);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ GlBindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
|
||||||
+ GlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
|
||||||
+ texture_, 0);
|
|
||||||
+ if (GlCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
+ RTC_LOG(LS_ERROR) << "Failed to bind DMA buf framebuffer";
|
|
||||||
+ EglDestroyImageKHR(egl_.display, image);
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
GLenum gl_format = GL_BGRA;
|
|
||||||
switch (format) {
|
|
||||||
@@ -598,17 +649,18 @@ std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
|
|
||||||
gl_format = GL_BGRA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- GlGetTexImage(GL_TEXTURE_2D, 0, gl_format, GL_UNSIGNED_BYTE, src.get());
|
|
||||||
|
|
||||||
- if (GlGetError()) {
|
|
||||||
+ GlReadPixels(offset.x(), offset.y(), buffer_size.width(),
|
|
||||||
+ buffer_size.height(), gl_format, GL_UNSIGNED_BYTE, data);
|
|
||||||
+
|
|
||||||
+ const GLenum error = GlGetError();
|
|
||||||
+ if (error) {
|
|
||||||
RTC_LOG(LS_ERROR) << "Failed to get image from DMA buffer.";
|
|
||||||
- return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
- GlDeleteTextures(1, &texture);
|
|
||||||
EglDestroyImageKHR(egl_.display, image);
|
|
||||||
|
|
||||||
- return src;
|
|
||||||
+ return !error;
|
|
||||||
}
|
|
||||||
|
|
||||||
RTC_NO_SANITIZE("cfi-icall")
|
|
||||||
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
|
|
||||||
index f1d96b2f80..22a8f5ab52 100644
|
|
||||||
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
|
|
||||||
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
|
|
||||||
@@ -41,11 +41,15 @@ class EglDmaBuf {
|
|
||||||
EglDmaBuf();
|
|
||||||
~EglDmaBuf();
|
|
||||||
|
|
||||||
- std::unique_ptr<uint8_t[]> ImageFromDmaBuf(
|
|
||||||
- const DesktopSize& size,
|
|
||||||
- uint32_t format,
|
|
||||||
- const std::vector<PlaneData>& plane_datas,
|
|
||||||
- uint64_t modifiers);
|
|
||||||
+ // Returns whether the image was successfully imported from
|
|
||||||
+ // given DmaBuf and its parameters
|
|
||||||
+ bool ImageFromDmaBuf(const DesktopSize& size,
|
|
||||||
+ uint32_t format,
|
|
||||||
+ const std::vector<PlaneData>& plane_datas,
|
|
||||||
+ uint64_t modifiers,
|
|
||||||
+ const DesktopVector& offset,
|
|
||||||
+ const DesktopSize& buffer_size,
|
|
||||||
+ uint8_t* data);
|
|
||||||
std::vector<uint64_t> QueryDmaBufModifiers(uint32_t format);
|
|
||||||
|
|
||||||
bool IsEglInitialized() const { return egl_initialized_; }
|
|
||||||
@@ -58,6 +62,8 @@ class EglDmaBuf {
|
|
||||||
int32_t drm_fd_ = -1; // for GBM buffer mmap
|
|
||||||
gbm_device* gbm_device_ = nullptr; // for passed GBM buffer retrieval
|
|
||||||
|
|
||||||
+ GLuint fbo_ = 0;
|
|
||||||
+ GLuint texture_ = 0;
|
|
||||||
EGLStruct egl_;
|
|
||||||
|
|
||||||
absl::optional<std::string> GetRenderNode();
|
|
||||||
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
|
||||||
index 0ca75d00fc..a8879764c7 100644
|
|
||||||
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
|
||||||
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
|
|
||||||
@@ -149,6 +149,12 @@ class SharedScreenCastStreamPrivate {
|
|
||||||
struct spa_video_info_raw spa_video_format_;
|
|
||||||
|
|
||||||
void ProcessBuffer(pw_buffer* buffer);
|
|
||||||
+ bool ProcessMemFDBuffer(pw_buffer* buffer,
|
|
||||||
+ DesktopFrame& frame,
|
|
||||||
+ const DesktopVector& offset);
|
|
||||||
+ bool ProcessDMABuffer(pw_buffer* buffer,
|
|
||||||
+ DesktopFrame& frame,
|
|
||||||
+ const DesktopVector& offset);
|
|
||||||
void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
|
|
||||||
|
|
||||||
// PipeWire callbacks
|
|
||||||
@@ -268,9 +274,8 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged(
|
|
||||||
std::vector<const spa_pod*> params;
|
|
||||||
const int buffer_types =
|
|
||||||
has_modifier || (that->pw_server_version_ >= kDmaBufMinVersion)
|
|
||||||
- ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd) |
|
|
||||||
- (1 << SPA_DATA_MemPtr)
|
|
||||||
- : (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr);
|
|
||||||
+ ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd)
|
|
||||||
+ : (1 << SPA_DATA_MemFd);
|
|
||||||
|
|
||||||
params.push_back(reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
|
|
||||||
&builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
|
|
||||||
@@ -605,9 +610,6 @@ DesktopVector SharedScreenCastStreamPrivate::CaptureCursorPosition() {
|
|
||||||
RTC_NO_SANITIZE("cfi-icall")
|
|
||||||
void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
spa_buffer* spa_buffer = buffer->buffer;
|
|
||||||
- ScopedBuf map;
|
|
||||||
- std::unique_ptr<uint8_t[]> src_unique_ptr;
|
|
||||||
- uint8_t* src = nullptr;
|
|
||||||
|
|
||||||
// Try to update the mouse cursor first, because it can be the only
|
|
||||||
// information carried by the buffer
|
|
||||||
@@ -641,76 +643,6 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (spa_buffer->datas[0].type == SPA_DATA_MemFd) {
|
|
||||||
- map.initialize(
|
|
||||||
- static_cast<uint8_t*>(
|
|
||||||
- mmap(nullptr,
|
|
||||||
- spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
|
|
||||||
- PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
|
|
||||||
- spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
|
|
||||||
- spa_buffer->datas[0].fd);
|
|
||||||
-
|
|
||||||
- if (!map) {
|
|
||||||
- RTC_LOG(LS_ERROR) << "Failed to mmap the memory: "
|
|
||||||
- << std::strerror(errno);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t);
|
|
||||||
- } else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) {
|
|
||||||
- const uint n_planes = spa_buffer->n_datas;
|
|
||||||
-
|
|
||||||
- if (!n_planes) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- std::vector<EglDmaBuf::PlaneData> plane_datas;
|
|
||||||
- for (uint32_t i = 0; i < n_planes; ++i) {
|
|
||||||
- EglDmaBuf::PlaneData data = {
|
|
||||||
- static_cast<int32_t>(spa_buffer->datas[i].fd),
|
|
||||||
- static_cast<uint32_t>(spa_buffer->datas[i].chunk->stride),
|
|
||||||
- static_cast<uint32_t>(spa_buffer->datas[i].chunk->offset)};
|
|
||||||
- plane_datas.push_back(data);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- // When importing DMA-BUFs, we use the stride (number of bytes from one row
|
|
||||||
- // of pixels in the buffer) provided by PipeWire. The stride from PipeWire
|
|
||||||
- // is given by the graphics driver and some drivers might add some
|
|
||||||
- // additional padding for memory layout optimizations so not everytime the
|
|
||||||
- // stride is equal to BYTES_PER_PIXEL x WIDTH. This is fine, because during
|
|
||||||
- // the import we will use OpenGL and same graphics driver so it will be able
|
|
||||||
- // to work with the stride it provided, but later on when we work with
|
|
||||||
- // images we get from DMA-BUFs we will need to update the stride to be equal
|
|
||||||
- // to BYTES_PER_PIXEL x WIDTH as that's the size of the DesktopFrame we
|
|
||||||
- // allocate for each captured frame.
|
|
||||||
- src_unique_ptr = egl_dmabuf_->ImageFromDmaBuf(
|
|
||||||
- stream_size_, spa_video_format_.format, plane_datas, modifier_);
|
|
||||||
- if (src_unique_ptr) {
|
|
||||||
- src = src_unique_ptr.get();
|
|
||||||
- } else {
|
|
||||||
- RTC_LOG(LS_ERROR) << "Dropping DMA-BUF modifier: " << modifier_
|
|
||||||
- << " and trying to renegotiate stream parameters";
|
|
||||||
-
|
|
||||||
- if (pw_server_version_ >= kDropSingleModifierMinVersion) {
|
|
||||||
- modifiers_.erase(
|
|
||||||
- std::remove(modifiers_.begin(), modifiers_.end(), modifier_),
|
|
||||||
- modifiers_.end());
|
|
||||||
- } else {
|
|
||||||
- modifiers_.clear();
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_),
|
|
||||||
- renegotiate_);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
- } else if (spa_buffer->datas[0].type == SPA_DATA_MemPtr) {
|
|
||||||
- src = static_cast<uint8_t*>(spa_buffer->datas[0].data);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (!src) {
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
// Use SPA_META_VideoCrop metadata to get the frame size. KDE and GNOME do
|
|
||||||
// handle screen/window sharing differently. KDE/KWin doesn't use
|
|
||||||
// SPA_META_VideoCrop metadata and when sharing a window, it always sets
|
|
||||||
@@ -763,8 +695,8 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the position of the video crop within the stream. Just double-check
|
|
||||||
- // that the position doesn't exceed the size of the stream itself. NOTE:
|
|
||||||
- // Currently it looks there is no implementation using this.
|
|
||||||
+ // that the position doesn't exceed the size of the stream itself.
|
|
||||||
+ // NOTE: Currently it looks there is no implementation using this.
|
|
||||||
uint32_t y_offset =
|
|
||||||
videocrop_metadata_use &&
|
|
||||||
(videocrop_metadata->region.position.y + frame_size_.height() <=
|
|
||||||
@@ -777,22 +709,7 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
stream_size_.width())
|
|
||||||
? videocrop_metadata->region.position.x
|
|
||||||
: 0;
|
|
||||||
-
|
|
||||||
- const uint32_t stream_stride = kBytesPerPixel * stream_size_.width();
|
|
||||||
- uint32_t buffer_stride = spa_buffer->datas[0].chunk->stride;
|
|
||||||
- uint32_t src_stride = buffer_stride;
|
|
||||||
-
|
|
||||||
- if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf &&
|
|
||||||
- buffer_stride > stream_stride) {
|
|
||||||
- // When DMA-BUFs are used, sometimes spa_buffer->stride we get might
|
|
||||||
- // contain additional padding, but after we import the buffer, the stride
|
|
||||||
- // we used is no longer relevant and we should just calculate it based on
|
|
||||||
- // the stream width. For more context see https://crbug.com/1333304.
|
|
||||||
- src_stride = stream_stride;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- uint8_t* updated_src =
|
|
||||||
- src + (src_stride * y_offset) + (kBytesPerPixel * x_offset);
|
|
||||||
+ DesktopVector offset = DesktopVector(x_offset, y_offset);
|
|
||||||
|
|
||||||
webrtc::MutexLock lock(&queue_lock_);
|
|
||||||
|
|
||||||
@@ -813,9 +730,17 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame)));
|
|
||||||
}
|
|
||||||
|
|
||||||
- queue_.current_frame()->CopyPixelsFrom(
|
|
||||||
- updated_src, (src_stride - (kBytesPerPixel * x_offset)),
|
|
||||||
- DesktopRect::MakeWH(frame_size_.width(), frame_size_.height()));
|
|
||||||
+ bool bufferProcessed = false;
|
|
||||||
+ if (spa_buffer->datas[0].type == SPA_DATA_MemFd) {
|
|
||||||
+ bufferProcessed =
|
|
||||||
+ ProcessMemFDBuffer(buffer, *queue_.current_frame(), offset);
|
|
||||||
+ } else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) {
|
|
||||||
+ bufferProcessed = ProcessDMABuffer(buffer, *queue_.current_frame(), offset);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!bufferProcessed) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
|
|
||||||
spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
|
|
||||||
@@ -832,6 +757,87 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
|
||||||
DesktopRect::MakeSize(queue_.current_frame()->size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
+RTC_NO_SANITIZE("cfi-icall")
|
|
||||||
+bool SharedScreenCastStreamPrivate::ProcessMemFDBuffer(
|
|
||||||
+ pw_buffer* buffer,
|
|
||||||
+ DesktopFrame& frame,
|
|
||||||
+ const DesktopVector& offset) {
|
|
||||||
+ spa_buffer* spa_buffer = buffer->buffer;
|
|
||||||
+ ScopedBuf map;
|
|
||||||
+ uint8_t* src = nullptr;
|
|
||||||
+
|
|
||||||
+ map.initialize(
|
|
||||||
+ static_cast<uint8_t*>(
|
|
||||||
+ mmap(nullptr,
|
|
||||||
+ spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
|
|
||||||
+ PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
|
|
||||||
+ spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
|
|
||||||
+ spa_buffer->datas[0].fd);
|
|
||||||
+
|
|
||||||
+ if (!map) {
|
|
||||||
+ RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t);
|
|
||||||
+
|
|
||||||
+ uint32_t buffer_stride = spa_buffer->datas[0].chunk->stride;
|
|
||||||
+ uint32_t src_stride = buffer_stride;
|
|
||||||
+
|
|
||||||
+ uint8_t* updated_src =
|
|
||||||
+ src + (src_stride * offset.y()) + (kBytesPerPixel * offset.x());
|
|
||||||
+
|
|
||||||
+ frame.CopyPixelsFrom(
|
|
||||||
+ updated_src, (src_stride - (kBytesPerPixel * offset.x())),
|
|
||||||
+ DesktopRect::MakeWH(frame.size().width(), frame.size().height()));
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+RTC_NO_SANITIZE("cfi-icall")
|
|
||||||
+bool SharedScreenCastStreamPrivate::ProcessDMABuffer(
|
|
||||||
+ pw_buffer* buffer,
|
|
||||||
+ DesktopFrame& frame,
|
|
||||||
+ const DesktopVector& offset) {
|
|
||||||
+ spa_buffer* spa_buffer = buffer->buffer;
|
|
||||||
+
|
|
||||||
+ const uint n_planes = spa_buffer->n_datas;
|
|
||||||
+
|
|
||||||
+ if (!n_planes) {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ std::vector<EglDmaBuf::PlaneData> plane_datas;
|
|
||||||
+ for (uint32_t i = 0; i < n_planes; ++i) {
|
|
||||||
+ EglDmaBuf::PlaneData data = {
|
|
||||||
+ static_cast<int32_t>(spa_buffer->datas[i].fd),
|
|
||||||
+ static_cast<uint32_t>(spa_buffer->datas[i].chunk->stride),
|
|
||||||
+ static_cast<uint32_t>(spa_buffer->datas[i].chunk->offset)};
|
|
||||||
+ plane_datas.push_back(data);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ const bool imported = egl_dmabuf_->ImageFromDmaBuf(
|
|
||||||
+ stream_size_, spa_video_format_.format, plane_datas, modifier_, offset,
|
|
||||||
+ frame.size(), frame.data());
|
|
||||||
+ if (!imported) {
|
|
||||||
+ RTC_LOG(LS_ERROR) << "Dropping DMA-BUF modifier: " << modifier_
|
|
||||||
+ << " and trying to renegotiate stream parameters";
|
|
||||||
+
|
|
||||||
+ if (pw_server_version_ >= kDropSingleModifierMinVersion) {
|
|
||||||
+ modifiers_.erase(
|
|
||||||
+ std::remove(modifiers_.begin(), modifiers_.end(), modifier_),
|
|
||||||
+ modifiers_.end());
|
|
||||||
+ } else {
|
|
||||||
+ modifiers_.clear();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_), renegotiate_);
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame,
|
|
||||||
uint32_t size) {
|
|
||||||
for (uint32_t i = 0; i < size; i += 4) {
|
|
@ -1,37 +0,0 @@
|
|||||||
diff -up firefox-109.0/dom/media/gmp/GMPSharedMemManager.h.1663844 firefox-109.0/dom/media/gmp/GMPSharedMemManager.h
|
|
||||||
--- firefox-109.0/dom/media/gmp/GMPSharedMemManager.h.1663844 2023-01-09 20:34:10.000000000 +0100
|
|
||||||
+++ firefox-109.0/dom/media/gmp/GMPSharedMemManager.h 2023-01-12 09:28:56.035741438 +0100
|
|
||||||
@@ -26,7 +26,7 @@ class GMPSharedMem {
|
|
||||||
// returned to the parent pool (which is not included). If more than
|
|
||||||
// this are needed, we presume the client has either crashed or hung
|
|
||||||
// (perhaps temporarily).
|
|
||||||
- static const uint32_t kGMPBufLimit = 20;
|
|
||||||
+ static const uint32_t kGMPBufLimit = 40;
|
|
||||||
|
|
||||||
GMPSharedMem() {
|
|
||||||
for (size_t i = 0; i < sizeof(mGmpAllocated) / sizeof(mGmpAllocated[0]);
|
|
||||||
diff -up firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844 firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
|
|
||||||
--- firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844 2023-01-09 20:34:10.000000000 +0100
|
|
||||||
+++ firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp 2023-01-12 09:28:56.036741473 +0100
|
|
||||||
@@ -84,6 +84,9 @@ media::DecodeSupportSet GMPDecoderModule
|
|
||||||
|
|
||||||
media::DecodeSupportSet GMPDecoderModule::SupportsMimeType(
|
|
||||||
const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
|
|
||||||
+ if (MP4Decoder::IsH264(aMimeType)) {
|
|
||||||
+ return media::DecodeSupport::SoftwareDecode;
|
|
||||||
+ }
|
|
||||||
return media::DecodeSupport::Unsupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844 firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
|
|
||||||
--- firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844 2023-01-12 09:28:56.036741473 +0100
|
|
||||||
+++ firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp 2023-01-12 14:18:12.354866405 +0100
|
|
||||||
@@ -81,6 +81,8 @@ void GMPVideoDecoder::Decoded(GMPVideoi4
|
|
||||||
});
|
|
||||||
|
|
||||||
mDecodedData.AppendElement(std::move(v));
|
|
||||||
+ mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
|
|
||||||
+ mDecodedData = DecodedData();
|
|
||||||
} else {
|
|
||||||
mDecodedData.Clear();
|
|
||||||
mDecodePromise.RejectIfExists(
|
|
4
sources
4
sources
@ -1,4 +1,4 @@
|
|||||||
SHA512 (cbindgen-vendor.tar.xz) = 0d45c1decfd7aaee853748745c9f5a907c0c6a0cf809c2387aac1cdcf680b0844b1ef4d05148e0527de4ff6e4d4666110bea317bd00b7d73a1210eb58a815563
|
SHA512 (cbindgen-vendor.tar.xz) = 0d45c1decfd7aaee853748745c9f5a907c0c6a0cf809c2387aac1cdcf680b0844b1ef4d05148e0527de4ff6e4d4666110bea317bd00b7d73a1210eb58a815563
|
||||||
SHA512 (mochitest-python.tar.gz) = e0a2c569dafe013b6a4c073516388549a8f398d8aa4538a3bc69dcda44737a3a3cf070285e9fa040a15d7a62446665c6158d42a1b6dc3e8d7f4680bc2ef17a16
|
SHA512 (mochitest-python.tar.gz) = e0a2c569dafe013b6a4c073516388549a8f398d8aa4538a3bc69dcda44737a3a3cf070285e9fa040a15d7a62446665c6158d42a1b6dc3e8d7f4680bc2ef17a16
|
||||||
SHA512 (firefox-langpacks-112.0.2-20230427.tar.xz) = 20a1bd9c9de131fd544d379a2867294cd6d9812bf7d66e8e2237c40eb86e1a44a1c5bc194f9f38e1249ded947d00ae9d0c695ea2813a46997ec64ced7b07e89e
|
SHA512 (firefox-langpacks-113.0-20230509.tar.xz) = 090478c1e29540bc99fe1857c83ec93da0dab5b44c5f8765d14e51a30ff5baf2fe8983e997fe0980efc69afbce6dc185899a9bc39826e55294472a327d53efc2
|
||||||
SHA512 (firefox-112.0.2.source.tar.xz) = 2cd7adeb6c9a39ad4c5366982e0e58382d7f205e6f2cee02b8ec2867034d1c0c884eeeb870a35db35cba60fa9c84aea73f8c77cfd9f36b5146dde06464aaabd1
|
SHA512 (firefox-113.0.source.tar.xz) = 96b0f0774083270f4fcce06085b177ced25ba05da7291d777f1da1d5bbad30721bc6363b76e06ccb64fc092778c8326a426a8bfdfa3cbaafd4f1169b924744a5
|
||||||
|
Loading…
Reference in New Issue
Block a user