Title: [278284] trunk/Source/WebCore
Revision
278284
Author
[email protected]
Date
2021-05-31 17:03:03 -0700 (Mon, 31 May 2021)

Log Message

Fix thread safety issues in PannerNode
https://bugs.webkit.org/show_bug.cgi?id=226455

Reviewed by Darin Adler.

Adopt thread safety annotations in PannerNode and fix bugs found by clang.
In particular, the following issues were fixed:
- tailTime() / latencyTime() were accessing m_panner on the audio thread without locking
  even though m_panner gets modified on the main thread.
- process() was accessing panningModel and m_panner before locking, on the audio thread,
  even though those get modified on the main thread.
- processOnlyAudioParams() was failing to grab the process lock.
- requiresTailProcessing() may get called on the audio thread and was failing to grab
  the processLock before accessing m_panner, which gets modified on the main thread.

* Modules/webaudio/PannerNode.cpp:
(WebCore::PannerNode::create):
(WebCore::PannerNode::PannerNode):
(WebCore::PannerNode::process):
(WebCore::PannerNode::processOnlyAudioParams):
(WebCore::PannerNode::setPanningModelForBindings):
(WebCore::PannerNode::setDistanceModelForBindings):
(WebCore::PannerNode::setRefDistanceForBindings):
(WebCore::PannerNode::setMaxDistanceForBindings):
(WebCore::PannerNode::setRolloffFactorForBindings):
(WebCore::PannerNode::setConeOuterGainForBindings):
(WebCore::PannerNode::setConeOuterAngleForBindings):
(WebCore::PannerNode::setConeInnerAngleForBindings):
(WebCore::PannerNode::requiresTailProcessing const):
(WebCore::PannerNode::tailTime const):
(WebCore::PannerNode::latencyTime const):
* Modules/webaudio/PannerNode.h:
* Modules/webaudio/PannerNode.idl:
* platform/audio/Distance.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (278283 => 278284)


--- trunk/Source/WebCore/ChangeLog	2021-05-31 21:14:52 UTC (rev 278283)
+++ trunk/Source/WebCore/ChangeLog	2021-06-01 00:03:03 UTC (rev 278284)
@@ -1,3 +1,40 @@
+2021-05-31  Chris Dumez  <[email protected]>
+
+        Fix thread safety issues in PannerNode
+        https://bugs.webkit.org/show_bug.cgi?id=226455
+
+        Reviewed by Darin Adler.
+
+        Adopt thread safety annotations in PannerNode and fix bugs found by clang.
+        In particular, the following issues were fixed:
+        - tailTime() / latencyTime() were accessing m_panner on the audio thread without locking
+          even though m_panner gets modified on the main thread.
+        - process() was accessing panningModel and m_panner before locking, on the audio thread,
+          even though those get modified on the main thread.
+        - processOnlyAudioParams() was failing to grab the process lock.
+        - requiresTailProcessing() may get called on the audio thread and was failing to grab
+          the processLock before accessing m_panner, which gets modified on the main thread.
+
+        * Modules/webaudio/PannerNode.cpp:
+        (WebCore::PannerNode::create):
+        (WebCore::PannerNode::PannerNode):
+        (WebCore::PannerNode::process):
+        (WebCore::PannerNode::processOnlyAudioParams):
+        (WebCore::PannerNode::setPanningModelForBindings):
+        (WebCore::PannerNode::setDistanceModelForBindings):
+        (WebCore::PannerNode::setRefDistanceForBindings):
+        (WebCore::PannerNode::setMaxDistanceForBindings):
+        (WebCore::PannerNode::setRolloffFactorForBindings):
+        (WebCore::PannerNode::setConeOuterGainForBindings):
+        (WebCore::PannerNode::setConeOuterAngleForBindings):
+        (WebCore::PannerNode::setConeInnerAngleForBindings):
+        (WebCore::PannerNode::requiresTailProcessing const):
+        (WebCore::PannerNode::tailTime const):
+        (WebCore::PannerNode::latencyTime const):
+        * Modules/webaudio/PannerNode.h:
+        * Modules/webaudio/PannerNode.idl:
+        * platform/audio/Distance.h:
+
 2021-05-31  Adrian Perez de Castro  <[email protected]>
 
         Non-unified build fixes, very early June 2021 edition

Modified: trunk/Source/WebCore/Modules/webaudio/PannerNode.cpp (278283 => 278284)


--- trunk/Source/WebCore/Modules/webaudio/PannerNode.cpp	2021-05-31 21:14:52 UTC (rev 278283)
+++ trunk/Source/WebCore/Modules/webaudio/PannerNode.cpp	2021-06-01 00:03:03 UTC (rev 278284)
@@ -58,19 +58,19 @@
     if (result.hasException())
         return result.releaseException();
 
-    result = panner->setMaxDistance(options.maxDistance);
+    result = panner->setMaxDistanceForBindings(options.maxDistance);
     if (result.hasException())
         return result.releaseException();
 
-    result = panner->setRefDistance(options.refDistance);
+    result = panner->setRefDistanceForBindings(options.refDistance);
     if (result.hasException())
         return result.releaseException();
 
-    result = panner->setRolloffFactor(options.rolloffFactor);
+    result = panner->setRolloffFactorForBindings(options.rolloffFactor);
     if (result.hasException())
         return result.releaseException();
 
-    result = panner->setConeOuterGain(options.coneOuterGain);
+    result = panner->setConeOuterGainForBindings(options.coneOuterGain);
     if (result.hasException())
         return result.releaseException();
 
@@ -79,7 +79,10 @@
 
 PannerNode::PannerNode(BaseAudioContext& context, const PannerOptions& options)
     : AudioNode(context, NodeTypePanner)
+    // Load the HRTF database asynchronously so we don't block the _javascript_ thread while creating the HRTF database.
+    , m_hrtfDatabaseLoader(HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(context.sampleRate()))
     , m_panningModel(options.panningModel)
+    , m_panner(Panner::create(m_panningModel, sampleRate(), m_hrtfDatabaseLoader.ptr()))
     , m_positionX(AudioParam::create(context, "positionX"_s, options.positionX, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
     , m_positionY(AudioParam::create(context, "positionY"_s, options.positionY, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
     , m_positionZ(AudioParam::create(context, "positionZ"_s, options.positionZ, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
@@ -86,12 +89,10 @@
     , m_orientationX(AudioParam::create(context, "orientationX"_s, options.orientationX, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
     , m_orientationY(AudioParam::create(context, "orientationY"_s, options.orientationY, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
     , m_orientationZ(AudioParam::create(context, "orientationZ"_s, options.orientationZ, -FLT_MAX, FLT_MAX, AutomationRate::ARate))
-    // Load the HRTF database asynchronously so we don't block the _javascript_ thread while creating the HRTF database.
-    , m_hrtfDatabaseLoader(HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(context.sampleRate()))
 {
-    setDistanceModel(options.distanceModel);
-    setConeInnerAngle(options.coneInnerAngle);
-    setConeOuterAngle(options.coneOuterAngle);
+    setDistanceModelForBindings(options.distanceModel);
+    setConeInnerAngleForBindings(options.coneInnerAngle);
+    setConeOuterAngleForBindings(options.coneOuterAngle);
 
     addInput();
     addOutput(2);
@@ -108,7 +109,7 @@
 {
     AudioBus* destination = output(0)->bus();
 
-    if (!isInitialized() || !input(0)->isConnected() || !m_panner.get()) {
+    if (!isInitialized() || !input(0)->isConnected()) {
         destination->zero();
         return;
     }
@@ -119,8 +120,21 @@
         return;
     }
 
-    // HRTFDatabase should be loaded before proceeding for offline audio context when panningModel() is "HRTF".
-    if (panningModel() == PanningModelType::HRTF && !m_hrtfDatabaseLoader->isLoaded()) {
+    // The audio thread can't block on this lock, so we use tryLock() instead.
+    if (!m_processLock.tryLock()) {
+        // Too bad - tryLock() failed. We must be in the middle of changing the panner.
+        destination->zero();
+        return;
+    }
+    Locker locker { AdoptLock, m_processLock };
+
+    if (!m_panner) {
+        destination->zero();
+        return;
+    }
+
+    // HRTFDatabase should be loaded before proceeding for offline audio context when m_panningModel is "HRTF".
+    if (m_panningModel == PanningModelType::HRTF && !m_hrtfDatabaseLoader->isLoaded()) {
         if (context().isOfflineContext())
             m_hrtfDatabaseLoader->waitForLoaderThreadCompletion();
         else {
@@ -129,14 +143,6 @@
         }
     }
 
-    // The audio thread can't block on this lock, so we use tryLock() instead.
-    if (!m_processLock.tryLock()) {
-        // Too bad - tryLock() failed. We must be in the middle of changing the panner.
-        destination->zero();
-        return;
-    }
-    Locker locker { AdoptLock, m_processLock };
-
     if ((hasSampleAccurateValues() || listener().hasSampleAccurateValues()) && (shouldUseARate() || listener().shouldUseARate())) {
         processSampleAccurateValues(destination, source, framesToProcess);
         return;
@@ -157,6 +163,11 @@
 
 void PannerNode::processOnlyAudioParams(size_t framesToProcess)
 {
+    ASSERT(context().isAudioThread());
+    if (!m_processLock.tryLock())
+        return;
+
+    Locker locker { AdoptLock, m_processLock };
     float values[AudioUtilities::renderQuantumSize];
     ASSERT(framesToProcess <= AudioUtilities::renderQuantumSize);
 
@@ -245,39 +256,19 @@
         || m_orientationZ->automationRate() == AutomationRate::ARate;
 }
 
-void PannerNode::initialize()
-{
-    if (isInitialized())
-        return;
-
-    m_panner = Panner::create(m_panningModel, sampleRate(), m_hrtfDatabaseLoader.get());
-
-    AudioNode::initialize();
-}
-
-void PannerNode::uninitialize()
-{
-    if (!isInitialized())
-        return;
-        
-    m_panner = nullptr;
-    AudioNode::uninitialize();
-}
-
 AudioListener& PannerNode::listener()
 {
     return context().listener();
 }
 
-void PannerNode::setPanningModel(PanningModelType model)
+void PannerNode::setPanningModelForBindings(PanningModelType model)
 {
     ASSERT(isMainThread());
 
-    if (!m_panner.get() || model != m_panningModel) {
-        // This synchronizes with process().
-        Locker locker { m_processLock };
-
-        m_panner = Panner::create(model, sampleRate(), m_hrtfDatabaseLoader.get());
+    // This synchronizes with process().
+    Locker locker { m_processLock };
+    if (!m_panner || model != m_panningModel) {
+        m_panner = Panner::create(model, sampleRate(), m_hrtfDatabaseLoader.ptr());
         m_panningModel = model;
     }
 }
@@ -336,12 +327,13 @@
     return { };
 }
 
-DistanceModelType PannerNode::distanceModel() const
+DistanceModelType PannerNode::distanceModelForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS
 {
-    return const_cast<PannerNode*>(this)->m_distanceEffect.model();
+    ASSERT(isMainThread());
+    return m_distanceEffect.model();
 }
 
-void PannerNode::setDistanceModel(DistanceModelType model)
+void PannerNode::setDistanceModelForBindings(DistanceModelType model)
 {
     ASSERT(isMainThread());
 
@@ -351,7 +343,7 @@
     m_distanceEffect.setModel(model, true);
 }
 
-ExceptionOr<void> PannerNode::setRefDistance(double refDistance)
+ExceptionOr<void> PannerNode::setRefDistanceForBindings(double refDistance)
 {
     ASSERT(isMainThread());
 
@@ -365,7 +357,7 @@
     return { };
 }
 
-ExceptionOr<void> PannerNode::setMaxDistance(double maxDistance)
+ExceptionOr<void> PannerNode::setMaxDistanceForBindings(double maxDistance)
 {
     ASSERT(isMainThread());
 
@@ -379,7 +371,7 @@
     return { };
 }
 
-ExceptionOr<void> PannerNode::setRolloffFactor(double rolloffFactor)
+ExceptionOr<void> PannerNode::setRolloffFactorForBindings(double rolloffFactor)
 {
     ASSERT(isMainThread());
 
@@ -393,7 +385,7 @@
     return { };
 }
 
-ExceptionOr<void> PannerNode::setConeOuterGain(double gain)
+ExceptionOr<void> PannerNode::setConeOuterGainForBindings(double gain)
 {
     ASSERT(isMainThread());
 
@@ -407,7 +399,7 @@
     return { };
 }
 
-void PannerNode::setConeOuterAngle(double angle)
+void PannerNode::setConeOuterAngleForBindings(double angle)
 {
     ASSERT(isMainThread());
 
@@ -417,7 +409,7 @@
     m_coneEffect.setOuterAngle(angle);
 }
 
-void PannerNode::setConeInnerAngle(double angle)
+void PannerNode::setConeInnerAngleForBindings(double angle)
 {
     ASSERT(isMainThread());
 
@@ -515,6 +507,9 @@
 
 bool PannerNode::requiresTailProcessing() const
 {
+    if (!m_processLock.tryLock())
+        return true;
+    Locker locker { AdoptLock, m_processLock };
     // If there's no internal panner method set up yet, assume we require tail
     // processing in case the HRTF panner is set later, which does require tail
     // processing.
@@ -539,6 +534,22 @@
     return calculateDistanceConeGain(position(), orientation(), listener().position());
 }
 
+double PannerNode::tailTime() const
+{
+    if (!m_processLock.tryLock())
+        return std::numeric_limits<double>::infinity();
+    Locker locker { AdoptLock, m_processLock };
+    return m_panner ? m_panner->tailTime() : 0;
+}
+
+double PannerNode::latencyTime() const
+{
+    if (!m_processLock.tryLock())
+        return std::numeric_limits<double>::infinity();
+    Locker locker { AdoptLock, m_processLock };
+    return m_panner ? m_panner->latencyTime() : 0;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUDIO)

Modified: trunk/Source/WebCore/Modules/webaudio/PannerNode.h (278283 => 278284)


--- trunk/Source/WebCore/Modules/webaudio/PannerNode.h	2021-05-31 21:14:52 UTC (rev 278283)
+++ trunk/Source/WebCore/Modules/webaudio/PannerNode.h	2021-06-01 00:03:03 UTC (rev 278284)
@@ -61,94 +61,90 @@
     // AudioNode
     void process(size_t framesToProcess) override;
     void processOnlyAudioParams(size_t framesToProcess) final;
-    void initialize() override;
-    void uninitialize() override;
 
     // Listener
     AudioListener& listener();
 
     // Panning model
-    PanningModelType panningModel() const { return m_panningModel; }
-    void setPanningModel(PanningModelType);
+    PanningModelType panningModelForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_panningModel; }
+    void setPanningModelForBindings(PanningModelType);
 
     // Position
-    FloatPoint3D position() const;
     ExceptionOr<void> setPosition(float x, float y, float z);
-    AudioParam& positionX() { return m_positionX.get(); }
-    AudioParam& positionY() { return m_positionY.get(); }
-    AudioParam& positionZ() { return m_positionZ.get(); }
+    AudioParam& positionX() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_positionX.get(); }
+    AudioParam& positionY() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_positionY.get(); }
+    AudioParam& positionZ() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_positionZ.get(); }
 
     // Orientation
-    FloatPoint3D orientation() const;
     ExceptionOr<void> setOrientation(float x, float y, float z);
-    AudioParam& orientationX() { return m_orientationX.get(); }
-    AudioParam& orientationY() { return m_orientationY.get(); }
-    AudioParam& orientationZ() { return m_orientationZ.get(); }
+    AudioParam& orientationX() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_orientationX.get(); }
+    AudioParam& orientationY() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_orientationY.get(); }
+    AudioParam& orientationZ() WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_orientationZ.get(); }
 
     // Distance parameters
-    DistanceModelType distanceModel() const;
-    void setDistanceModel(DistanceModelType);
+    DistanceModelType distanceModelForBindings() const;
+    void setDistanceModelForBindings(DistanceModelType);
 
-    double refDistance() const { return m_distanceEffect.refDistance(); }
-    ExceptionOr<void> setRefDistance(double);
+    double refDistanceForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_distanceEffect.refDistance(); }
+    ExceptionOr<void> setRefDistanceForBindings(double);
 
-    double maxDistance() const { return m_distanceEffect.maxDistance(); }
-    ExceptionOr<void> setMaxDistance(double);
+    double maxDistanceForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_distanceEffect.maxDistance(); }
+    ExceptionOr<void> setMaxDistanceForBindings(double);
 
-    double rolloffFactor() const { return m_distanceEffect.rolloffFactor(); }
-    ExceptionOr<void> setRolloffFactor(double);
+    double rolloffFactorForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_distanceEffect.rolloffFactor(); }
+    ExceptionOr<void> setRolloffFactorForBindings(double);
 
     // Sound cones - angles in degrees
-    double coneInnerAngle() const { return m_coneEffect.innerAngle(); }
-    void setConeInnerAngle(double);
+    double coneInnerAngleForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_coneEffect.innerAngle(); }
+    void setConeInnerAngleForBindings(double);
 
-    double coneOuterAngle() const { return m_coneEffect.outerAngle(); }
-    void setConeOuterAngle(double);
+    double coneOuterAngleForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_coneEffect.outerAngle(); }
+    void setConeOuterAngleForBindings(double);
 
-    double coneOuterGain() const { return m_coneEffect.outerGain(); }
-    ExceptionOr<void> setConeOuterGain(double);
+    double coneOuterGainForBindings() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS { ASSERT(isMainThread()); return m_coneEffect.outerGain(); }
+    ExceptionOr<void> setConeOuterGainForBindings(double);
     
     ExceptionOr<void> setChannelCount(unsigned) final;
     ExceptionOr<void> setChannelCountMode(ChannelCountMode) final;
 
-    void azimuthElevation(double* outAzimuth, double* outElevation);
+    double tailTime() const final;
+    double latencyTime() const final;
 
-    double tailTime() const override { return m_panner ? m_panner->tailTime() : 0; }
-    double latencyTime() const override { return m_panner ? m_panner->latencyTime() : 0; }
-
 private:
     PannerNode(BaseAudioContext&, const PannerOptions&);
 
-    void calculateAzimuthElevation(double* outAzimuth, double* outElevation, const FloatPoint3D& position, const FloatPoint3D& listenerPosition, const FloatPoint3D& listenerForward, const FloatPoint3D& listenerUp);
-    float calculateDistanceConeGain(const FloatPoint3D& position, const FloatPoint3D& orientation, const FloatPoint3D& listenerPosition);
+    void calculateAzimuthElevation(double* outAzimuth, double* outElevation, const FloatPoint3D& position, const FloatPoint3D& listenerPosition, const FloatPoint3D& listenerForward, const FloatPoint3D& listenerUp) WTF_REQUIRES_LOCK(m_processLock);
+    float calculateDistanceConeGain(const FloatPoint3D& position, const FloatPoint3D& orientation, const FloatPoint3D& listenerPosition) WTF_REQUIRES_LOCK(m_processLock);
 
     // Returns the combined distance and cone gain attenuation.
-    float distanceConeGain();
+    float distanceConeGain() WTF_REQUIRES_LOCK(m_processLock);
 
     bool requiresTailProcessing() const final;
 
-    void processSampleAccurateValues(AudioBus* destination, const AudioBus* source, size_t framesToProcess);
-    bool hasSampleAccurateValues() const;
-    bool shouldUseARate() const;
+    void azimuthElevation(double* outAzimuth, double* outElevation) WTF_REQUIRES_LOCK(m_processLock);
+    void processSampleAccurateValues(AudioBus* destination, const AudioBus* source, size_t framesToProcess) WTF_REQUIRES_LOCK(m_processLock);
+    bool hasSampleAccurateValues() const WTF_REQUIRES_LOCK(m_processLock);
+    bool shouldUseARate() const WTF_REQUIRES_LOCK(m_processLock);
 
-    std::unique_ptr<Panner> m_panner;
-    PanningModelType m_panningModel;
+    FloatPoint3D position() const WTF_REQUIRES_LOCK(m_processLock);
+    FloatPoint3D orientation() const WTF_REQUIRES_LOCK(m_processLock);
 
+    Ref<HRTFDatabaseLoader> m_hrtfDatabaseLoader;
+    PanningModelType m_panningModel WTF_GUARDED_BY_LOCK(m_processLock);
+    std::unique_ptr<Panner> m_panner WTF_GUARDED_BY_LOCK(m_processLock);
+
     // Gain
-    DistanceEffect m_distanceEffect;
-    ConeEffect m_coneEffect;
+    DistanceEffect m_distanceEffect WTF_GUARDED_BY_LOCK(m_processLock);
+    ConeEffect m_coneEffect WTF_GUARDED_BY_LOCK(m_processLock);
     
-    Ref<AudioParam> m_positionX;
-    Ref<AudioParam> m_positionY;
-    Ref<AudioParam> m_positionZ;
+    Ref<AudioParam> m_positionX WTF_GUARDED_BY_LOCK(m_processLock);
+    Ref<AudioParam> m_positionY WTF_GUARDED_BY_LOCK(m_processLock);
+    Ref<AudioParam> m_positionZ WTF_GUARDED_BY_LOCK(m_processLock);
     
-    Ref<AudioParam> m_orientationX;
-    Ref<AudioParam> m_orientationY;
-    Ref<AudioParam> m_orientationZ;
+    Ref<AudioParam> m_orientationX WTF_GUARDED_BY_LOCK(m_processLock);
+    Ref<AudioParam> m_orientationY WTF_GUARDED_BY_LOCK(m_processLock);
+    Ref<AudioParam> m_orientationZ WTF_GUARDED_BY_LOCK(m_processLock);
 
-    // HRTF Database loader
-    RefPtr<HRTFDatabaseLoader> m_hrtfDatabaseLoader;
-
     // Synchronize process() with setting of the panning model, source's location
     // information, listener, distance parameters and sound cones.
     mutable Lock m_processLock;

Modified: trunk/Source/WebCore/Modules/webaudio/PannerNode.idl (278283 => 278284)


--- trunk/Source/WebCore/Modules/webaudio/PannerNode.idl	2021-05-31 21:14:52 UTC (rev 278283)
+++ trunk/Source/WebCore/Modules/webaudio/PannerNode.idl	2021-06-01 00:03:03 UTC (rev 278284)
@@ -31,7 +31,7 @@
     constructor (BaseAudioContext context, optional PannerOptions options);
 
     // Default model for stereo is equalpower
-    attribute PanningModelType panningModel;
+    [ImplementedAs=panningModelForBindings] attribute PanningModelType panningModel;
 
     // Uses a 3D cartesian coordinate system 
     undefined setPosition(float x, float y, float z);
@@ -38,16 +38,16 @@
     undefined setOrientation(float x, float y, float z);
     
     // Default distance model is inverse
-    attribute DistanceModelType distanceModel;
+    [ImplementedAs=distanceModelForBindings] attribute DistanceModelType distanceModel;
 
-    attribute double refDistance;
-    attribute double maxDistance;
-    attribute double rolloffFactor;
+    [ImplementedAs=refDistanceForBindings] attribute double refDistance;
+    [ImplementedAs=maxDistanceForBindings] attribute double maxDistance;
+    [ImplementedAs=rolloffFactorForBindings] attribute double rolloffFactor;
 
     // Directional sound cone
-    attribute double coneInnerAngle;
-    attribute double coneOuterAngle;
-    attribute double coneOuterGain;
+    [ImplementedAs=coneInnerAngleForBindings] attribute double coneInnerAngle;
+    [ImplementedAs=coneOuterAngleForBindings] attribute double coneOuterAngle;
+    [ImplementedAs=coneOuterGainForBindings] attribute double coneOuterGain;
     
     // Position of audio source in 3D Cartesian system
     readonly attribute AudioParam positionX;

Modified: trunk/Source/WebCore/platform/audio/Distance.h (278283 => 278284)


--- trunk/Source/WebCore/platform/audio/Distance.h	2021-05-31 21:14:52 UTC (rev 278283)
+++ trunk/Source/WebCore/platform/audio/Distance.h	2021-06-01 00:03:03 UTC (rev 278284)
@@ -48,7 +48,7 @@
     // Returns scalar gain for the given distance the current distance model is used
     double gain(double distance);
 
-    DistanceModelType model() { return m_model; }
+    DistanceModelType model() const { return m_model; }
 
     void setModel(DistanceModelType model, bool clamped)
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to