haikuwebkit/PerformanceTests/Media/AudioElementCreation.html

43 lines
1.0 KiB
HTML
Raw Permalink Normal View History

[Mac] Audio and Video element creation up to 300x slower than other browsers https://bugs.webkit.org/show_bug.cgi?id=218206 <rdar://problem/62451019> Reviewed by Eric Carlson. PerformanceTests: * Media/AudioElementCreation.html: Added. * Media/VideoElementCreation.html: Added. Source/WebCore: Tests: PerformanceTests/Media/AudioElementCreation.html PerformanceTests/Media/VideoElementCreation.html Currently, a large percent of the element creation code occurrs as a result of adding its session to PlatformMediaSessionManager, which forces iterating over all extant sessions and then to set various properties of the audio hardware in response. This patch addresses the bulk of those expensive calls, but more performance optimizations are available to further reduce media element creation costs. When an <audio> element is created, we set the preferred audio output buffer size to a large value for performance reasons. However, there's no need to repeatedly call into CoreAudio if the buffer size is already set to that same high value. Store the result of setting the preferred buffer size, and also add a property change listener to detect other callers modifying that same value, so that all set operations with identical sizes become no-ops, and all queries just return cached values. When any media element is created, the entire list of extant sessions is iterated and properties on each are queried. Rather than do these inside the same run-loop, use a TaskQueue to enqueue a task to query the list of created elements during the next run-loop. Between these two optimization, the runtime cost of creating 1000 audio elements is reduced (on this engineer's machine) from 2s to 40ms. * platform/audio/PlatformMediaSessionManager.cpp: (WebCore::PlatformMediaSessionManager::beginInterruption): (WebCore::PlatformMediaSessionManager::addSession): (WebCore::PlatformMediaSessionManager::removeSession): (WebCore::PlatformMediaSessionManager::sessionStateChanged): (WebCore::PlatformMediaSessionManager::forEachDocumentSession): (WebCore::PlatformMediaSessionManager::forEachSession): (WebCore::PlatformMediaSessionManager::anyOfSessions const): * platform/audio/PlatformMediaSessionManager.h: * platform/audio/mac/AudioSessionMac.mm: (WebCore::AudioSessionPrivate::addSampleRateObserverIfNeeded): (WebCore::AudioSessionPrivate::handleSampleRateChange): (WebCore::AudioSessionPrivate::addBufferSizeObserverIfNeeded): (WebCore::AudioSessionPrivate::handleBufferSizeChange): (WebCore::AudioSession::sampleRate const): (WebCore::AudioSession::bufferSize const): (WebCore::AudioSession::preferredBufferSize const): (WebCore::AudioSession::setPreferredBufferSize): Canonical link: https://commits.webkit.org/230965@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269077 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-27 22:21:28 +00:00
<!DOCTYPE html>
<html>
<head>
<script src="../resources/runner.js"></script>
<script>
window.addEventListener('load', event => {
const numberOfIterations = 20;
const numberOfItems = 1000;
PerfTestRunner.prepareToMeasureValuesAsync({
customIterationCount: numberOfIterations,
unit: 'ms',
done: function () {
PerfTestRunner.gc();
}
});
function startIteration()
{
testGenerator = runIteration();
testGenerator.next();
}
function *runIteration()
{
var startTime = PerfTestRunner.now();
for (let i = 0; i < numberOfItems; ++i)
document.createElement('audio');
if (!PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
return;
PerfTestRunner.gc();
setTimeout(startIteration, 0);
}
startIteration();
})
</script>
</head>
<body></body>
</html>