Title: [97912] trunk/Source/WebCore
- Revision
- 97912
- Author
- [email protected]
- Date
- 2011-10-19 18:52:17 -0700 (Wed, 19 Oct 2011)
Log Message
Flush denormals to zero on Windows.
https://bugs.webkit.org/show_bug.cgi?id=70140
Patch by Raymond Toy <[email protected]> on 2011-10-19
Reviewed by Kenneth Russell.
* platform/audio/AudioBus.cpp:
(WebCore::AudioBus::processWithGainFromMonoStereo):
Flush any denormals to zero before saving the result. Change
double gain to float gain to match existing float operations.
* platform/audio/DenormalDisabler.h:
(WebCore::DenormalDisabler::flushDenormalFloatToZero):
New function to flush the given float to zero, if it is a denormal
number.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (97911 => 97912)
--- trunk/Source/WebCore/ChangeLog 2011-10-20 01:51:13 UTC (rev 97911)
+++ trunk/Source/WebCore/ChangeLog 2011-10-20 01:52:17 UTC (rev 97912)
@@ -1,3 +1,19 @@
+2011-10-19 Raymond Toy <[email protected]>
+
+ Flush denormals to zero on Windows.
+ https://bugs.webkit.org/show_bug.cgi?id=70140
+
+ Reviewed by Kenneth Russell.
+
+ * platform/audio/AudioBus.cpp:
+ (WebCore::AudioBus::processWithGainFromMonoStereo):
+ Flush any denormals to zero before saving the result. Change
+ double gain to float gain to match existing float operations.
+ * platform/audio/DenormalDisabler.h:
+ (WebCore::DenormalDisabler::flushDenormalFloatToZero):
+ New function to flush the given float to zero, if it is a denormal
+ number.
+
2011-10-19 Raphael Kubo da Costa <[email protected]>
[EFL] Remove the empty paint() implementation in ScrollbarEfl.
Modified: trunk/Source/WebCore/platform/audio/AudioBus.cpp (97911 => 97912)
--- trunk/Source/WebCore/platform/audio/AudioBus.cpp 2011-10-20 01:51:13 UTC (rev 97911)
+++ trunk/Source/WebCore/platform/audio/AudioBus.cpp 2011-10-20 01:52:17 UTC (rev 97912)
@@ -32,6 +32,8 @@
#include "AudioBus.h"
+#include "DenormalDisabler.h"
+
#if !PLATFORM(MAC)
#include "SincResampler.h"
#endif
@@ -238,11 +240,13 @@
// FIXME: Need fast path here when gain has converged on targetGain. In this case, de-zippering is no longer needed.
// FIXME: Need fast path when this==sourceBus && lastMixGain==targetGain==1.0 && sumToBus==false (this is a NOP)
+ // FIXME: targetGain and lastMixGain should be changed to floats instead of doubles.
+
// Take master bus gain into account as well as the targetGain.
- double totalDesiredGain = m_busGain * targetGain;
+ float totalDesiredGain = static_cast<float>(m_busGain * targetGain);
// First time, snap directly to totalDesiredGain.
- double gain = m_isFirstTime ? totalDesiredGain : *lastMixGain;
+ float gain = static_cast<float>(m_isFirstTime ? totalDesiredGain : *lastMixGain);
m_isFirstTime = false;
int numberOfSourceChannels = sourceBus.numberOfChannels();
@@ -255,7 +259,7 @@
float* destinationL = channelByType(ChannelLeft)->data();
float* destinationR = numberOfDestinationChannels > 1 ? channelByType(ChannelRight)->data() : 0;
- const double DezipperRate = 0.005;
+ const float DezipperRate = 0.005f;
int framesToProcess = length();
if (sumToBus) {
@@ -263,33 +267,39 @@
if (sourceR && destinationR) {
// Stereo
while (framesToProcess--) {
- float sampleL = *sourceL++;
- float sampleR = *sourceR++;
- *destinationL++ += static_cast<float>(gain * sampleL);
- *destinationR++ += static_cast<float>(gain * sampleR);
+ float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++);
+ float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + gain * *sourceR++);
+ *destinationL++ = sumL;
+ *destinationR++ = sumR;
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
} else if (destinationR) {
// Mono -> stereo (mix equally into L and R)
// FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
while (framesToProcess--) {
- float sample = *sourceL++;
- *destinationL++ += static_cast<float>(gain * sample);
- *destinationR++ += static_cast<float>(gain * sample);
+ float scaled = gain * *sourceL++;
+ float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + scaled);
+ float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + scaled);
+ *destinationL++ = sumL;
+ *destinationR++ = sumR;
+
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
} else {
// Mono
while (framesToProcess--) {
- float sampleL = *sourceL++;
- *destinationL++ += static_cast<float>(gain * sampleL);
+ float sum = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++);
+ *destinationL++ = sum;
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
}
} else {
@@ -299,37 +309,40 @@
while (framesToProcess--) {
float sampleL = *sourceL++;
float sampleR = *sourceR++;
- *destinationL++ = static_cast<float>(gain * sampleL);
- *destinationR++ = static_cast<float>(gain * sampleR);
+ *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL);
+ *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleR);
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
} else if (destinationR) {
// Mono -> stereo (mix equally into L and R)
// FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
while (framesToProcess--) {
float sample = *sourceL++;
- *destinationL++ = static_cast<float>(gain * sample);
- *destinationR++ = static_cast<float>(gain * sample);
+ *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample);
+ *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample);
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
} else {
// Mono
while (framesToProcess--) {
float sampleL = *sourceL++;
- *destinationL++ = static_cast<float>(gain * sampleL);
+ *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL);
// Slowly change gain to desired gain.
gain += (totalDesiredGain - gain) * DezipperRate;
+ gain = DenormalDisabler::flushDenormalFloatToZero(gain);
}
}
}
// Save the target gain as the starting point for next time around.
- *lastMixGain = gain;
+ *lastMixGain = static_cast<double>(gain);
}
void AudioBus::processWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus)
Modified: trunk/Source/WebCore/platform/audio/DenormalDisabler.h (97911 => 97912)
--- trunk/Source/WebCore/platform/audio/DenormalDisabler.h 2011-10-20 01:51:13 UTC (rev 97911)
+++ trunk/Source/WebCore/platform/audio/DenormalDisabler.h 2011-10-20 01:52:17 UTC (rev 97912)
@@ -25,6 +25,8 @@
#ifndef DenormalDisabler_h
#define DenormalDisabler_h
+#include <wtf/MathExtras.h>
+
namespace WebCore {
// Deal with denormals. They can very seriously impact performance on x86.
@@ -43,6 +45,11 @@
setCSR(m_savedCSR);
}
+ // This is a nop if we can flush denormals to zero in hardware.
+ static inline float flushDenormalFloatToZero(float f)
+ {
+ return f;
+ }
private:
inline int getCSR()
{
@@ -65,6 +72,18 @@
class DenormalDisabler {
public:
DenormalDisabler() { }
+
+ static inline float flushDenormalFloatToZero(float f)
+ {
+#if OS(WINDOWS) && COMPILER(MSVC) && (!_M_IX86_FP)
+ // For systems using x87 instead of sse, there's no hardware support
+ // to flush denormals automatically. Hence, we need to flush
+ // denormals to zero manually.
+ return (fabs(f) < FLT_MIN) ? 0.0f : f;
+#else
+ return f;
+#endif
+ }
};
#endif
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes