зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1604615 - Use optimized shader source in webrender. r=jrmuizel
Add a gecko pref "gfx.webrender.use-optimized-shaders". If enabled, then when attempting to compile a webrender shader first look for the optimized source. If the optimized source is not present, emit a warning and fall back to the unoptimized source. Use the optimized source by default in wrench, and add the flag "--use-unoptimized-shaders" to override this. Differential Revision: https://phabricator.services.mozilla.com/D70033
This commit is contained in:
Родитель
f548e9a284
Коммит
d9a1b3bbde
|
@ -45,6 +45,7 @@ class gfxVarReceiver;
|
||||||
_(UseWebRenderTripleBufferingWin, bool, false) \
|
_(UseWebRenderTripleBufferingWin, bool, false) \
|
||||||
_(UseWebRenderCompositor, bool, false) \
|
_(UseWebRenderCompositor, bool, false) \
|
||||||
_(UseWebRenderProgramBinaryDisk, bool, false) \
|
_(UseWebRenderProgramBinaryDisk, bool, false) \
|
||||||
|
_(UseWebRenderOptimizedShaders, bool, false) \
|
||||||
_(UseWebRenderMultithreading, bool, false) \
|
_(UseWebRenderMultithreading, bool, false) \
|
||||||
_(WebRenderMaxPartialPresentRects, int32_t, 0) \
|
_(WebRenderMaxPartialPresentRects, int32_t, 0) \
|
||||||
_(WebRenderDebugFlags, int32_t, 0) \
|
_(WebRenderDebugFlags, int32_t, 0) \
|
||||||
|
|
|
@ -125,6 +125,10 @@ const char* gfx_wr_resource_path_override() {
|
||||||
return resourcePath;
|
return resourcePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gfx_wr_use_optimized_shaders() {
|
||||||
|
return mozilla::gfx::gfxVars::UseWebRenderOptimizedShaders();
|
||||||
|
}
|
||||||
|
|
||||||
void gfx_critical_note(const char* msg) { gfxCriticalNote << msg; }
|
void gfx_critical_note(const char* msg) { gfxCriticalNote << msg; }
|
||||||
|
|
||||||
void gfx_critical_error(const char* msg) { gfxCriticalError() << msg; }
|
void gfx_critical_error(const char* msg) { gfxCriticalError() << msg; }
|
||||||
|
|
|
@ -3032,6 +3032,10 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||||
gfxConfig::IsEnabled(Feature::WEBRENDER));
|
gfxConfig::IsEnabled(Feature::WEBRENDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StaticPrefs::gfx_webrender_use_optimized_shaders_AtStartup()) {
|
||||||
|
gfxVars::SetUseWebRenderOptimizedShaders(gfxConfig::IsEnabled(Feature::WEBRENDER));
|
||||||
|
}
|
||||||
|
|
||||||
if (Preferences::GetBool("gfx.webrender.software", false)) {
|
if (Preferences::GetBool("gfx.webrender.software", false)) {
|
||||||
gfxVars::SetUseSoftwareWebRender(gfxConfig::IsEnabled(Feature::WEBRENDER));
|
gfxVars::SetUseSoftwareWebRender(gfxConfig::IsEnabled(Feature::WEBRENDER));
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,6 +510,7 @@ extern "C" {
|
||||||
// by commenting out the path that adds an external image ID
|
// by commenting out the path that adds an external image ID
|
||||||
fn gfx_use_wrench() -> bool;
|
fn gfx_use_wrench() -> bool;
|
||||||
fn gfx_wr_resource_path_override() -> *const c_char;
|
fn gfx_wr_resource_path_override() -> *const c_char;
|
||||||
|
fn gfx_wr_use_optimized_shaders() -> bool;
|
||||||
// TODO: make gfx_critical_error() work.
|
// TODO: make gfx_critical_error() work.
|
||||||
// We still have problem to pass the error message from render/render_backend
|
// We still have problem to pass the error message from render/render_backend
|
||||||
// thread to main thread now.
|
// thread to main thread now.
|
||||||
|
@ -1142,6 +1143,8 @@ fn wr_device_new(gl_context: *mut c_void, pc: Option<&mut WrProgramCache>) -> De
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let use_optimized_shaders = unsafe { gfx_wr_use_optimized_shaders() };
|
||||||
|
|
||||||
let cached_programs = match pc {
|
let cached_programs = match pc {
|
||||||
Some(cached_programs) => Some(Rc::clone(cached_programs.rc_get())),
|
Some(cached_programs) => Some(Rc::clone(cached_programs.rc_get())),
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -1150,6 +1153,7 @@ fn wr_device_new(gl_context: *mut c_void, pc: Option<&mut WrProgramCache>) -> De
|
||||||
Device::new(
|
Device::new(
|
||||||
gl,
|
gl,
|
||||||
resource_override_path,
|
resource_override_path,
|
||||||
|
use_optimized_shaders,
|
||||||
upload_method,
|
upload_method,
|
||||||
cached_programs,
|
cached_programs,
|
||||||
false,
|
false,
|
||||||
|
@ -1427,6 +1431,7 @@ pub extern "C" fn wr_window_new(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
use_optimized_shaders: unsafe { gfx_wr_use_optimized_shaders() },
|
||||||
renderer_id: Some(window_id.0),
|
renderer_id: Some(window_id.0),
|
||||||
upload_method,
|
upload_method,
|
||||||
scene_builder_hooks: Some(Box::new(APZCallbacks::new(window_id))),
|
scene_builder_hooks: Some(Box::new(APZCallbacks::new(window_id))),
|
||||||
|
|
|
@ -23,6 +23,7 @@ bool is_glcontext_gles(void* glcontext_ptr);
|
||||||
bool is_glcontext_angle(void* glcontext_ptr);
|
bool is_glcontext_angle(void* glcontext_ptr);
|
||||||
bool gfx_use_wrench();
|
bool gfx_use_wrench();
|
||||||
const char* gfx_wr_resource_path_override();
|
const char* gfx_wr_resource_path_override();
|
||||||
|
bool gfx_wr_use_optimized_shaders();
|
||||||
void gfx_critical_note(const char* msg);
|
void gfx_critical_note(const char* msg);
|
||||||
void gfx_critical_error(const char* msg);
|
void gfx_critical_error(const char* msg);
|
||||||
void gecko_printf_stderr_output(const char* msg);
|
void gecko_printf_stderr_output(const char* msg);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use super::super::shader_source::UNOPTIMIZED_SHADERS;
|
use super::super::shader_source::{OPTIMIZED_SHADERS, UNOPTIMIZED_SHADERS};
|
||||||
use api::{ColorF, ImageDescriptor, ImageFormat, MemoryReport};
|
use api::{ColorF, ImageDescriptor, ImageFormat, MemoryReport};
|
||||||
use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
|
use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
|
||||||
use api::units::*;
|
use api::units::*;
|
||||||
|
@ -662,10 +662,17 @@ pub struct VBOId(gl::GLuint);
|
||||||
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
|
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
|
||||||
struct IBOId(gl::GLuint);
|
struct IBOId(gl::GLuint);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
enum ProgramSourceType {
|
||||||
|
Unoptimized,
|
||||||
|
Optimized(ShaderVersion),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct ProgramSourceInfo {
|
pub struct ProgramSourceInfo {
|
||||||
base_filename: &'static str,
|
base_filename: &'static str,
|
||||||
features: Vec<&'static str>,
|
features: Vec<&'static str>,
|
||||||
|
source_type: ProgramSourceType,
|
||||||
digest: ProgramSourceDigest,
|
digest: ProgramSourceDigest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,72 +684,131 @@ impl ProgramSourceInfo {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
||||||
// Compute the digest. Assuming the device has a `ProgramCache`, this
|
// Compute the digest. Assuming the device has a `ProgramCache`, this
|
||||||
// will always be needed, whereas the source is rarely needed. As such,
|
// will always be needed, whereas the source is rarely needed.
|
||||||
// we compute the hash by walking the static strings in the same order
|
|
||||||
// as we would when concatenating the source, to avoid heap-allocating
|
|
||||||
// in the common case.
|
|
||||||
//
|
|
||||||
// Note that we cheat a bit to make the hashing more efficient. First,
|
|
||||||
// the only difference between the vertex and fragment shader is a
|
|
||||||
// single deterministic define, so we don't need to hash both. Second,
|
|
||||||
// we precompute the digest of the expanded source file at build time,
|
|
||||||
// and then just hash that digest here.
|
|
||||||
|
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
|
|
||||||
// Setup.
|
// Setup.
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
let version = get_shader_version(&*device.gl());
|
let gl_version = get_shader_version(&*device.gl());
|
||||||
let override_path = device.resource_override_path.as_ref();
|
|
||||||
let source_and_digest = UNOPTIMIZED_SHADERS.get(&name).expect("Shader not found");
|
|
||||||
|
|
||||||
// Hash the renderer name.
|
// Hash the renderer name.
|
||||||
hasher.write(device.capabilities.renderer_name.as_bytes());
|
hasher.write(device.capabilities.renderer_name.as_bytes());
|
||||||
|
|
||||||
// Hash the prefix string.
|
let full_name = &Self::full_name(name, features);
|
||||||
build_shader_prefix_string(
|
|
||||||
version,
|
|
||||||
&features,
|
|
||||||
ShaderKind::Vertex,
|
|
||||||
&name,
|
|
||||||
&mut |s| hasher.write(s.as_bytes()),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Hash the shader file contents. We use a precomputed digest, and
|
let optimized_source = if device.use_optimized_shaders {
|
||||||
// verify it in debug builds.
|
OPTIMIZED_SHADERS.get(&(gl_version, full_name)).or_else(|| {
|
||||||
if override_path.is_some() || cfg!(debug_assertions) {
|
warn!("Missing optimized shader source for {}", full_name);
|
||||||
let mut h = DefaultHasher::new();
|
None
|
||||||
build_shader_main_string(
|
})
|
||||||
&name,
|
|
||||||
&|f| get_unoptimized_shader_source(f, override_path),
|
|
||||||
&mut |s| h.write(s.as_bytes())
|
|
||||||
);
|
|
||||||
let d: ProgramSourceDigest = h.into();
|
|
||||||
let digest = format!("{}", d);
|
|
||||||
debug_assert!(override_path.is_some() || digest == source_and_digest.digest);
|
|
||||||
hasher.write(digest.as_bytes());
|
|
||||||
} else {
|
} else {
|
||||||
hasher.write(source_and_digest.digest.as_bytes());
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let source_type = match optimized_source {
|
||||||
|
Some(source_and_digest) => {
|
||||||
|
// Optimized shader sources are used as-is, without any run-time processing.
|
||||||
|
// The vertex and fragment shaders are different, so must both be hashed.
|
||||||
|
// We use the hashes that were computed at build time, and verify it in debug builds.
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
let mut h = DefaultHasher::new();
|
||||||
|
h.write(source_and_digest.vert_source.as_bytes());
|
||||||
|
h.write(source_and_digest.frag_source.as_bytes());
|
||||||
|
let d: ProgramSourceDigest = h.into();
|
||||||
|
let digest = d.to_string();
|
||||||
|
debug_assert_eq!(digest, source_and_digest.digest);
|
||||||
|
hasher.write(digest.as_bytes());
|
||||||
|
} else {
|
||||||
|
hasher.write(source_and_digest.digest.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramSourceType::Optimized(gl_version)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// For non-optimized sources we compute the hash by walking the static strings
|
||||||
|
// in the same order as we would when concatenating the source, to avoid
|
||||||
|
// heap-allocating in the common case.
|
||||||
|
//
|
||||||
|
// Note that we cheat a bit to make the hashing more efficient. First, the only
|
||||||
|
// difference between the vertex and fragment shader is a single deterministic
|
||||||
|
// define, so we don't need to hash both. Second, we precompute the digest of the
|
||||||
|
// expanded source file at build time, and then just hash that digest here.
|
||||||
|
let override_path = device.resource_override_path.as_ref();
|
||||||
|
let source_and_digest = UNOPTIMIZED_SHADERS.get(&name).expect("Shader not found");
|
||||||
|
|
||||||
|
// Hash the prefix string.
|
||||||
|
build_shader_prefix_string(
|
||||||
|
gl_version,
|
||||||
|
&features,
|
||||||
|
ShaderKind::Vertex,
|
||||||
|
&name,
|
||||||
|
&mut |s| hasher.write(s.as_bytes()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hash the shader file contents. We use a precomputed digest, and
|
||||||
|
// verify it in debug builds.
|
||||||
|
if override_path.is_some() || cfg!(debug_assertions) {
|
||||||
|
let mut h = DefaultHasher::new();
|
||||||
|
build_shader_main_string(
|
||||||
|
&name,
|
||||||
|
&|f| get_unoptimized_shader_source(f, override_path),
|
||||||
|
&mut |s| h.write(s.as_bytes())
|
||||||
|
);
|
||||||
|
let d: ProgramSourceDigest = h.into();
|
||||||
|
let digest = format!("{}", d);
|
||||||
|
debug_assert!(override_path.is_some() || digest == source_and_digest.digest);
|
||||||
|
hasher.write(digest.as_bytes());
|
||||||
|
} else {
|
||||||
|
hasher.write(source_and_digest.digest.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramSourceType::Unoptimized
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Finish.
|
// Finish.
|
||||||
ProgramSourceInfo {
|
ProgramSourceInfo {
|
||||||
base_filename: name,
|
base_filename: name,
|
||||||
features: features.to_vec(),
|
features: features.to_vec(),
|
||||||
|
source_type,
|
||||||
digest: hasher.into(),
|
digest: hasher.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_source(&self, device: &Device, kind: ShaderKind) -> String {
|
fn compute_source(&self, device: &Device, kind: ShaderKind) -> String {
|
||||||
let mut src = String::new();
|
let full_name = Self::full_name(self.base_filename, &self.features);
|
||||||
device.build_shader_string(
|
match self.source_type {
|
||||||
&self.features,
|
ProgramSourceType::Optimized(gl_version) => {
|
||||||
kind,
|
let shader = OPTIMIZED_SHADERS
|
||||||
self.base_filename,
|
.get(&(gl_version, &full_name))
|
||||||
|s| src.push_str(s),
|
.unwrap_or_else(|| panic!("Missing optimized shader source for {}", full_name));
|
||||||
);
|
|
||||||
src
|
match kind {
|
||||||
|
ShaderKind::Vertex => shader.vert_source.to_string(),
|
||||||
|
ShaderKind::Fragment => shader.frag_source.to_string(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ProgramSourceType::Unoptimized => {
|
||||||
|
let mut src = String::new();
|
||||||
|
device.build_shader_string(
|
||||||
|
&self.features,
|
||||||
|
kind,
|
||||||
|
self.base_filename,
|
||||||
|
|s| src.push_str(s),
|
||||||
|
);
|
||||||
|
src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_name(base_filename: &'static str, features: &[&'static str]) -> String {
|
||||||
|
if features.is_empty() {
|
||||||
|
base_filename.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}_{}", base_filename, features.join("_"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1081,9 @@ pub struct Device {
|
||||||
// resources
|
// resources
|
||||||
resource_override_path: Option<PathBuf>,
|
resource_override_path: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Whether to use shaders that have been optimized at build time.
|
||||||
|
use_optimized_shaders: bool,
|
||||||
|
|
||||||
max_texture_size: i32,
|
max_texture_size: i32,
|
||||||
max_texture_layers: u32,
|
max_texture_layers: u32,
|
||||||
cached_programs: Option<Rc<ProgramCache>>,
|
cached_programs: Option<Rc<ProgramCache>>,
|
||||||
|
@ -1250,6 +1319,7 @@ impl Device {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut gl: Rc<dyn gl::Gl>,
|
mut gl: Rc<dyn gl::Gl>,
|
||||||
resource_override_path: Option<PathBuf>,
|
resource_override_path: Option<PathBuf>,
|
||||||
|
use_optimized_shaders: bool,
|
||||||
upload_method: UploadMethod,
|
upload_method: UploadMethod,
|
||||||
cached_programs: Option<Rc<ProgramCache>>,
|
cached_programs: Option<Rc<ProgramCache>>,
|
||||||
allow_pixel_local_storage_support: bool,
|
allow_pixel_local_storage_support: bool,
|
||||||
|
@ -1408,7 +1478,8 @@ impl Device {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (depth_format, upload_method) = if renderer_name.starts_with("Software WebRender") {
|
let is_software_webrender = renderer_name.starts_with("Software WebRender");
|
||||||
|
let (depth_format, upload_method) = if is_software_webrender {
|
||||||
(gl::DEPTH_COMPONENT16, UploadMethod::Immediate)
|
(gl::DEPTH_COMPONENT16, UploadMethod::Immediate)
|
||||||
} else {
|
} else {
|
||||||
(gl::DEPTH_COMPONENT24, upload_method)
|
(gl::DEPTH_COMPONENT24, upload_method)
|
||||||
|
@ -1449,6 +1520,9 @@ impl Device {
|
||||||
gl::GlType::Gles => supports_extension(&extensions,"GL_EXT_blend_func_extended"),
|
gl::GlType::Gles => supports_extension(&extensions,"GL_EXT_blend_func_extended"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Software webrender relies on the unoptimized shader source.
|
||||||
|
let use_optimized_shaders = use_optimized_shaders && !is_software_webrender;
|
||||||
|
|
||||||
// On the android emulator, glShaderSource can crash if the source
|
// On the android emulator, glShaderSource can crash if the source
|
||||||
// strings are not null-terminated. See bug 1591945.
|
// strings are not null-terminated. See bug 1591945.
|
||||||
let requires_null_terminated_shader_source = is_emulator;
|
let requires_null_terminated_shader_source = is_emulator;
|
||||||
|
@ -1479,6 +1553,7 @@ impl Device {
|
||||||
gl,
|
gl,
|
||||||
base_gl: None,
|
base_gl: None,
|
||||||
resource_override_path,
|
resource_override_path,
|
||||||
|
use_optimized_shaders,
|
||||||
upload_method,
|
upload_method,
|
||||||
inside_frame: false,
|
inside_frame: false,
|
||||||
|
|
||||||
|
|
|
@ -2192,6 +2192,7 @@ impl Renderer {
|
||||||
let mut device = Device::new(
|
let mut device = Device::new(
|
||||||
gl,
|
gl,
|
||||||
options.resource_override_path.clone(),
|
options.resource_override_path.clone(),
|
||||||
|
options.use_optimized_shaders,
|
||||||
options.upload_method.clone(),
|
options.upload_method.clone(),
|
||||||
options.cached_programs.take(),
|
options.cached_programs.take(),
|
||||||
options.allow_pixel_local_storage_support,
|
options.allow_pixel_local_storage_support,
|
||||||
|
@ -6713,6 +6714,8 @@ bitflags! {
|
||||||
pub struct RendererOptions {
|
pub struct RendererOptions {
|
||||||
pub device_pixel_ratio: f32,
|
pub device_pixel_ratio: f32,
|
||||||
pub resource_override_path: Option<PathBuf>,
|
pub resource_override_path: Option<PathBuf>,
|
||||||
|
/// Whether to use shaders that have been optimized at build time.
|
||||||
|
pub use_optimized_shaders: bool,
|
||||||
pub enable_aa: bool,
|
pub enable_aa: bool,
|
||||||
pub enable_dithering: bool,
|
pub enable_dithering: bool,
|
||||||
pub max_recorded_profiles: usize,
|
pub max_recorded_profiles: usize,
|
||||||
|
@ -6783,6 +6786,7 @@ impl Default for RendererOptions {
|
||||||
RendererOptions {
|
RendererOptions {
|
||||||
device_pixel_ratio: 1.0,
|
device_pixel_ratio: 1.0,
|
||||||
resource_override_path: None,
|
resource_override_path: None,
|
||||||
|
use_optimized_shaders: false,
|
||||||
enable_aa: true,
|
enable_aa: true,
|
||||||
enable_dithering: false,
|
enable_dithering: false,
|
||||||
debug_flags: DebugFlags::empty(),
|
debug_flags: DebugFlags::empty(),
|
||||||
|
|
|
@ -21,6 +21,9 @@ args:
|
||||||
long: shaders
|
long: shaders
|
||||||
help: Override path for shaders
|
help: Override path for shaders
|
||||||
takes_value: true
|
takes_value: true
|
||||||
|
- use_unoptimized_shaders:
|
||||||
|
long: use-unoptimized-shaders
|
||||||
|
help: Use unoptimized shaders rather than the shaders optimized at build-time
|
||||||
- rebuild:
|
- rebuild:
|
||||||
short: r
|
short: r
|
||||||
long: rebuild
|
long: rebuild
|
||||||
|
|
|
@ -657,6 +657,7 @@ fn main() {
|
||||||
&mut window,
|
&mut window,
|
||||||
events_loop.as_mut().map(|el| el.create_proxy()),
|
events_loop.as_mut().map(|el| el.create_proxy()),
|
||||||
res_path,
|
res_path,
|
||||||
|
!args.is_present("use_unoptimized_shaders"),
|
||||||
dp_ratio,
|
dp_ratio,
|
||||||
save_type,
|
save_type,
|
||||||
dim,
|
dim,
|
||||||
|
|
|
@ -232,6 +232,7 @@ impl Wrench {
|
||||||
window: &mut WindowWrapper,
|
window: &mut WindowWrapper,
|
||||||
proxy: Option<EventsLoopProxy>,
|
proxy: Option<EventsLoopProxy>,
|
||||||
shader_override_path: Option<PathBuf>,
|
shader_override_path: Option<PathBuf>,
|
||||||
|
use_optimized_shaders: bool,
|
||||||
dp_ratio: f32,
|
dp_ratio: f32,
|
||||||
save_type: Option<SaveType>,
|
save_type: Option<SaveType>,
|
||||||
size: DeviceIntSize,
|
size: DeviceIntSize,
|
||||||
|
@ -274,6 +275,7 @@ impl Wrench {
|
||||||
let opts = webrender::RendererOptions {
|
let opts = webrender::RendererOptions {
|
||||||
device_pixel_ratio: dp_ratio,
|
device_pixel_ratio: dp_ratio,
|
||||||
resource_override_path: shader_override_path,
|
resource_override_path: shader_override_path,
|
||||||
|
use_optimized_shaders,
|
||||||
recorder,
|
recorder,
|
||||||
enable_subpixel_aa: !no_subpixel_aa,
|
enable_subpixel_aa: !no_subpixel_aa,
|
||||||
debug_flags,
|
debug_flags,
|
||||||
|
|
|
@ -4151,6 +4151,11 @@
|
||||||
value: @IS_NIGHTLY_BUILD@
|
value: @IS_NIGHTLY_BUILD@
|
||||||
mirror: once
|
mirror: once
|
||||||
|
|
||||||
|
- name: gfx.webrender.use-optimized-shaders
|
||||||
|
type: bool
|
||||||
|
value: true
|
||||||
|
mirror: once
|
||||||
|
|
||||||
#ifdef NIGHTLY_BUILD
|
#ifdef NIGHTLY_BUILD
|
||||||
# Keep this pref hidden on non-nightly builds to avoid people accidentally
|
# Keep this pref hidden on non-nightly builds to avoid people accidentally
|
||||||
# turning it on.
|
# turning it on.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче