Bug 1613167 - Enable/Disable rayon in WebRender via pref. r=gw

We need a way to switch it on and off to compare the performance and power usage of various test cases.
The new pref is "webrender.enable-multithreading" and does not require a restart.

Differential Revision: https://phabricator.services.mozilla.com/D61589

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Silva 2020-02-05 09:51:14 +00:00
Родитель 29f4461ccd
Коммит 4269e36963
19 изменённых файлов: 115 добавлений и 5 удалений

Просмотреть файл

@ -45,6 +45,7 @@ class gfxVarReceiver;
_(UseWebRenderTripleBufferingWin, bool, false) \
_(UseWebRenderCompositor, bool, false) \
_(UseWebRenderProgramBinaryDisk, bool, false) \
_(UseWebRenderMultithreading, bool, false) \
_(WebRenderMaxPartialPresentRects, int32_t, 0) \
_(WebRenderDebugFlags, int32_t, 0) \
_(ScreenDepth, int32_t, 0) \

Просмотреть файл

@ -2012,6 +2012,8 @@ void CompositorBridgeParent::AccumulateMemoryReport(wr::MemoryReport* aReport) {
void CompositorBridgeParent::InitializeStatics() {
gfxVars::SetAllowSacrificingSubpixelAAListener(&UpdateQualitySettings);
gfxVars::SetWebRenderDebugFlagsListener(&UpdateDebugFlags);
gfxVars::SetUseWebRenderMultithreadingListener(
&UpdateWebRenderMultithreading);
}
/*static*/
@ -2054,6 +2056,24 @@ void CompositorBridgeParent::UpdateDebugFlags() {
});
}
/*static*/
void CompositorBridgeParent::UpdateWebRenderMultithreading() {
if (!CompositorThreadHolder::IsInCompositorThread()) {
if (CompositorLoop()) {
CompositorLoop()->PostTask(NewRunnableFunction(
"CompositorBridgeParent::UpdateWebRenderMultithreading",
&CompositorBridgeParent::UpdateWebRenderMultithreading));
}
return;
}
MonitorAutoLock lock(*sIndirectLayerTreesLock);
ForEachWebRenderBridgeParent([&](WebRenderBridgeParent* wrBridge) -> void {
wrBridge->UpdateMultithreading();
});
}
RefPtr<WebRenderBridgeParent> CompositorBridgeParent::GetWebRenderBridgeParent()
const {
return mWrBridge;

Просмотреть файл

@ -734,6 +734,11 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
*/
static void UpdateDebugFlags();
/**
* Notify the compositor the debug flags have been updated.
*/
static void UpdateWebRenderMultithreading();
/**
* Wrap the data structure to be sent over IPC.
*/

Просмотреть файл

@ -1755,11 +1755,22 @@ void WebRenderBridgeParent::UpdateQualitySettings() {
}
void WebRenderBridgeParent::UpdateDebugFlags() {
auto flags = gfxVars::WebRenderDebugFlags();
for (auto& api : mApis) {
if (!api) {
continue;
}
api->UpdateDebugFlags(gfxVars::WebRenderDebugFlags());
api->UpdateDebugFlags(flags);
}
}
void WebRenderBridgeParent::UpdateMultithreading() {
bool multithreading = gfxVars::UseWebRenderMultithreading();
for (auto& api : mApis) {
if (!api) {
continue;
}
api->EnableMultithreading(multithreading);
}
}

Просмотреть файл

@ -105,6 +105,7 @@ class WebRenderBridgeParent final
void UpdateQualitySettings();
void UpdateDebugFlags();
void UpdateMultithreading();
mozilla::ipc::IPCResult RecvEnsureConnected(
TextureFactoryIdentifier* aTextureFactoryIdentifier,

Просмотреть файл

@ -615,6 +615,14 @@ static void WebRenderQualityPrefChangeCallback(const char* aPref, void*) {
gfxPlatform::GetPlatform()->UpdateAllowSacrificingSubpixelAA();
}
static void WebRenderMultithreadingPrefChangeCallback(const char* aPrefName,
void*) {
bool enable = Preferences::GetBool(
StaticPrefs::GetPrefName_gfx_webrender_enable_multithreading(), true);
gfx::gfxVars::SetUseWebRenderMultithreading(enable);
}
#if defined(USE_SKIA)
static uint32_t GetSkiaGlyphCacheSize() {
// Only increase font cache size on non-android to save memory.
@ -3334,6 +3342,11 @@ void gfxPlatform::InitWebRenderConfig() {
nsDependentCString(
StaticPrefs::
GetPrefName_gfx_webrender_quality_force_disable_sacrificing_subpixel_aa()));
Preferences::RegisterCallback(
WebRenderMultithreadingPrefChangeCallback,
nsDependentCString(
StaticPrefs::GetPrefName_gfx_webrender_enable_multithreading()));
UpdateAllowSacrificingSubpixelAA();
}
}

Просмотреть файл

@ -525,6 +525,10 @@ void WebRenderAPI::EnableNativeCompositor(bool aEnable) {
wr_api_enable_native_compositor(mDocHandle, aEnable);
}
void WebRenderAPI::EnableMultithreading(bool aEnable) {
wr_api_enable_multithreading(mDocHandle, aEnable);
}
void WebRenderAPI::Pause() {
class PauseEvent : public RendererEvent {
public:

Просмотреть файл

@ -248,6 +248,7 @@ class WebRenderAPI final {
void ClearAllCaches();
void EnableNativeCompositor(bool aEnable);
void EnableMultithreading(bool aEnable);
void Pause();
bool Resume();

Просмотреть файл

@ -1603,6 +1603,11 @@ pub unsafe extern "C" fn wr_api_enable_native_compositor(dh: &mut DocumentHandle
dh.api.send_debug_cmd(DebugCommand::EnableNativeCompositor(enable));
}
#[no_mangle]
pub unsafe extern "C" fn wr_api_enable_multithreading(dh: &mut DocumentHandle, enable: bool) {
dh.api.send_debug_cmd(DebugCommand::EnableMultithreading(enable));
}
fn make_transaction(do_async: bool) -> Transaction {
let mut transaction = Transaction::new();
// Ensure that we either use async scene building or not based on the

Просмотреть файл

@ -79,6 +79,7 @@ pub struct Moz2dBlobImageHandler {
workers: Arc<ThreadPool>,
workers_low_priority: Arc<ThreadPool>,
blob_commands: HashMap<BlobImageKey, BlobCommand>,
enable_multithreading: bool,
}
/// Transmute some bytes into a value.
@ -507,6 +508,8 @@ struct Moz2dBlobRasterizer {
workers_low_priority: Arc<ThreadPool>,
/// Blobs to rasterize.
blob_commands: HashMap<BlobImageKey, BlobCommand>,
///
enable_multithreading: bool,
}
struct GeckoProfilerMarker {
@ -549,7 +552,9 @@ impl AsyncBlobImageRasterizer for Moz2dBlobRasterizer {
// If we don't have a lot of blobs it is probably not worth the initial cost
// of installing work on rayon's thread pool so we do it serially on this thread.
let should_parallelize = if low_priority {
let should_parallelize = if !self.enable_multithreading {
false
} else if low_priority {
requests.len() > 2
} else {
// For high priority requests we don't "risk" the potential priority inversion of
@ -663,6 +668,7 @@ impl BlobImageHandler for Moz2dBlobImageHandler {
workers: Arc::clone(&self.workers),
workers_low_priority: Arc::clone(&self.workers_low_priority),
blob_commands: self.blob_commands.clone(),
enable_multithreading: self.enable_multithreading,
})
}
@ -689,6 +695,10 @@ impl BlobImageHandler for Moz2dBlobImageHandler {
self.prepare_request(&blob, resources);
}
}
fn enable_multithreading(&mut self, enable: bool) {
self.enable_multithreading = enable;
}
}
use bindings::{WrFontKey, WrFontInstanceKey, WrIdNamespace};
@ -719,6 +729,7 @@ impl Moz2dBlobImageHandler {
blob_commands: HashMap::new(),
workers: workers,
workers_low_priority: workers_low_priority,
enable_multithreading: true,
}
}

Просмотреть файл

@ -160,6 +160,7 @@ impl api::BlobImageHandler for CheckerboardRenderer {
_requests: &[api::BlobImageParams],
) {}
fn enable_multithreading(&mut self, _: bool) {}
fn delete_font(&mut self, _font: api::FontKey) {}
fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) {}
fn clear_namespace(&mut self, _namespace: api::IdNamespace) {}

Просмотреть файл

@ -108,6 +108,10 @@ impl GlyphRasterizer {
self.request_glyphs_from_backend(font, new_glyphs);
}
pub fn enable_multithreading(&mut self, enable: bool) {
self.enable_multithreading = enable;
}
pub(in super) fn request_glyphs_from_backend(&mut self, font: FontInstance, glyphs: Vec<GlyphKey>) {
let font_contexts = Arc::clone(&self.font_contexts);
let glyph_tx = self.glyph_tx.clone();
@ -154,7 +158,7 @@ impl GlyphRasterizer {
// if the number of glyphs is small, do it inline to avoid the threading overhead;
// send the result into glyph_tx so downstream code can't tell the difference.
if glyphs.len() < 8 {
if !self.enable_multithreading || glyphs.len() < 8 {
let jobs = glyphs.iter()
.map(|key: &GlyphKey| process_glyph(key, &font_contexts, &font))
.collect();
@ -880,6 +884,9 @@ pub struct GlyphRasterizer {
#[allow(dead_code)]
next_gpu_glyph_cache_key: GpuGlyphCacheKey,
// Whether to parallelize glyph rasterization with rayon.
enable_multithreading: bool,
}
impl GlyphRasterizer {
@ -912,6 +919,7 @@ impl GlyphRasterizer {
fonts_to_remove: Vec::new(),
font_instances_to_remove: Vec::new(),
next_gpu_glyph_cache_key: GpuGlyphCacheKey(0),
enable_multithreading: true,
})
}

Просмотреть файл

@ -1254,6 +1254,10 @@ impl RenderBackend {
// We don't want to forward this message to the renderer.
return RenderBackendStatus::Continue;
}
DebugCommand::EnableMultithreading(enable) => {
self.resource_cache.enable_multithreading(enable);
return RenderBackendStatus::Continue;
}
DebugCommand::SimulateLongSceneBuild(time_ms) => {
self.scene_tx.send(SceneBuilderRequest::SimulateLongSceneBuild(time_ms)).unwrap();
return RenderBackendStatus::Continue;

Просмотреть файл

@ -2285,6 +2285,7 @@ impl Renderer {
scene_tx.clone()
};
let enable_multithreading = options.enable_multithreading;
thread::Builder::new().name(rb_thread_name.clone()).spawn(move || {
register_thread_with_profiler(rb_thread_name.clone());
if let Some(ref thread_listener) = *thread_listener_for_render_backend {
@ -2306,13 +2307,15 @@ impl Renderer {
let glyph_cache = GlyphCache::new(max_glyph_cache_size);
let resource_cache = ResourceCache::new(
let mut resource_cache = ResourceCache::new(
texture_cache,
glyph_rasterizer,
glyph_cache,
blob_image_handler,
);
resource_cache.enable_multithreading(enable_multithreading);
let mut backend = RenderBackend::new(
api_rx,
payload_rx_for_backend,
@ -2874,7 +2877,8 @@ impl Renderer {
DebugCommand::ClearCaches(_)
| DebugCommand::SimulateLongSceneBuild(_)
| DebugCommand::SimulateLongLowPrioritySceneBuild(_)
| DebugCommand::EnableNativeCompositor(_) => {}
| DebugCommand::EnableNativeCompositor(_)
| DebugCommand::EnableMultithreading(_) => {}
DebugCommand::InvalidateGpuCache => {
match self.gpu_cache_texture.bus {
GpuCacheBus::PixelBuffer { ref mut rows, .. } => {
@ -6222,6 +6226,7 @@ pub struct RendererOptions {
pub scatter_gpu_cache_updates: bool,
pub upload_method: UploadMethod,
pub workers: Option<Arc<ThreadPool>>,
pub enable_multithreading: bool,
pub blob_image_handler: Option<Box<dyn BlobImageHandler>>,
pub recorder: Option<Box<dyn ApiRecordingReceiver>>,
pub thread_listener: Option<Box<dyn ThreadListener + Send + Sync>>,
@ -6295,6 +6300,7 @@ impl Default for RendererOptions {
// but we are unable to make this decision here, so picking the reasonable medium.
upload_method: UploadMethod::PixelBuffer(VertexUsageHint::Stream),
workers: None,
enable_multithreading: true,
blob_image_handler: None,
recorder: None,
thread_listener: None,

Просмотреть файл

@ -556,6 +556,13 @@ impl ResourceCache {
self.texture_cache.max_texture_size()
}
pub fn enable_multithreading(&mut self, enable: bool) {
self.glyph_rasterizer.enable_multithreading(enable);
if let Some(ref mut handler) = self.blob_image_handler {
handler.enable_multithreading(enable);
}
}
fn should_tile(limit: i32, descriptor: &ImageDescriptor, data: &CachedImageData) -> bool {
let size_check = descriptor.size.width > limit || descriptor.size.height > limit;
match *data {

Просмотреть файл

@ -972,6 +972,8 @@ pub enum DebugCommand {
ClearCaches(ClearCache),
/// Enable/disable native compositor usage
EnableNativeCompositor(bool),
/// Enable/disable parallel job execution with rayon.
EnableMultithreading(bool),
/// Invalidate GPU cache, forcing the update from the CPU mirror.
InvalidateGpuCache,
/// Causes the scene builder to pause for a given amount of milliseconds each time it

Просмотреть файл

@ -409,6 +409,9 @@ pub trait BlobImageHandler: Send {
/// A hook to let the handler clean up any state related a given namespace before the
/// resource cache deletes them.
fn clear_namespace(&mut self, namespace: IdNamespace);
/// Whether to allow rendering blobs on multiple threads.
fn enable_multithreading(&mut self, enable: bool);
}
/// A group of rasterization requests to execute synchronously on the scene builder thread.

Просмотреть файл

@ -166,6 +166,8 @@ impl BlobImageHandler for CheckerboardRenderer {
fn create_blob_rasterizer(&mut self) -> Box<dyn AsyncBlobImageRasterizer> {
Box::new(Rasterizer { image_cmds: self.image_cmds.clone() })
}
fn enable_multithreading(&mut self, _enable: bool) {}
}
struct Command {

Просмотреть файл

@ -3846,6 +3846,11 @@
value: false
mirror: once
- name: gfx.webrender.enable-multithreading
type: bool
value: true
mirror: always
- name: gfx.webrender.compositor
type: bool
#if defined(XP_WIN) || defined(XP_MACOSX)