зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
29f4461ccd
Коммит
4269e36963
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче