Bug 1525420 - Use KHR_blend_equation_advanced for mix-blend mode implementation r=gw

Use natively supported mix-blend modes, where appropriate. Disabled by default.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dzmitry Malyshau 2019-05-01 20:45:22 +00:00
parent 546a095298
commit 0302456bb8
18 changed files with 182 additions and 71 deletions

8
Cargo.lock generated
View File

@ -1287,7 +1287,7 @@ dependencies = [
[[package]]
name = "gleam"
version = "0.6.16"
version = "0.6.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3360,7 +3360,7 @@ dependencies = [
"dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3415,7 +3415,7 @@ dependencies = [
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"nsstring 0.1.0",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3707,7 +3707,7 @@ dependencies = [
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
"checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd"
"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"
"checksum gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7f46fd8874e043ffac0d638ed1567a2584f7814f6d72b4db37ab1689004a26c4"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2"
"checksum guid_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87261686cc5e35b6584f4c2a430c2b153d8a92ab1ef820c16be34c1df8f5f58b"

14
gfx/wr/Cargo.lock generated
View File

@ -143,7 +143,7 @@ name = "cgl"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -370,7 +370,7 @@ name = "direct-composition"
version = "0.1.0"
dependencies = [
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender 0.60.0",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -569,7 +569,7 @@ dependencies = [
[[package]]
name = "gleam"
version = "0.6.16"
version = "0.6.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1645,7 +1645,7 @@ dependencies = [
"dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1682,7 +1682,7 @@ dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender 0.60.0",
@ -1799,7 +1799,7 @@ dependencies = [
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1946,7 +1946,7 @@ dependencies = [
"checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c"
"checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd"
"checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"
"checksum gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7f46fd8874e043ffac0d638ed1567a2584f7814f6d72b4db37ab1689004a26c4"
"checksum glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70c5fe78efbd5a3b243a804ea1032053c584510f8822819f94cfb29b2100317"
"checksum half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d5c5f71a723d10dfc58927cbed37c3071a50afc7f073d86fd7d3e5727db890f"
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"

View File

@ -30,7 +30,7 @@ byteorder = "1.0"
cfg-if = "0.1.2"
cstr = "0.1.2"
fxhash = "0.2.1"
gleam = "0.6.16"
gleam = "0.6.17"
image = { optional = true, version = "0.21", default-features = false, features = ["png_codec"] }
lazy_static = "1"
log = "0.4"

View File

@ -138,15 +138,17 @@ pub struct AlphaBatchList {
pub item_rects: Vec<Vec<PictureRect>>,
current_batch_index: usize,
current_z_id: ZBufferId,
break_advanced_blend_batches: bool,
}
impl AlphaBatchList {
fn new() -> Self {
fn new(break_advanced_blend_batches: bool) -> Self {
AlphaBatchList {
batches: Vec::new(),
item_rects: Vec::new(),
current_z_id: ZBufferId::invalid(),
current_batch_index: usize::MAX,
break_advanced_blend_batches,
}
}
@ -180,6 +182,9 @@ impl AlphaBatchList {
}
}
}
BlendMode::Advanced(_) if self.break_advanced_blend_batches => {
// don't try to find a batch
}
_ => {
'outer_default: for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) {
// For normal batches, we only need to check for overlaps for batches
@ -301,13 +306,14 @@ impl BatchList {
screen_size: DeviceIntSize,
regions: Vec<DeviceIntRect>,
tile_blits: Vec<TileBlit>,
break_advanced_blend_batches: bool,
) -> Self {
// The threshold for creating a new batch is
// one quarter the screen size.
let batch_area_threshold = (screen_size.width * screen_size.height) as f32 / 4.0;
BatchList {
alpha_batch_list: AlphaBatchList::new(),
alpha_batch_list: AlphaBatchList::new(break_advanced_blend_batches),
opaque_batch_list: OpaqueBatchList::new(batch_area_threshold),
regions,
tile_blits,
@ -321,23 +327,8 @@ impl BatchList {
z_id: ZBufferId,
instance: PrimitiveInstanceData,
) {
match key.blend_mode {
BlendMode::None => {
self.opaque_batch_list
.set_params_and_get_batch(key, bounding_rect)
.push(instance);
}
BlendMode::Alpha |
BlendMode::PremultipliedAlpha |
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor |
BlendMode::SubpixelDualSource => {
self.alpha_batch_list
.set_params_and_get_batch(key, bounding_rect, z_id)
.push(instance);
}
}
self.set_params_and_get_batch(key, bounding_rect, z_id)
.push(instance);
}
pub fn set_params_and_get_batch(
@ -356,7 +347,8 @@ impl BatchList {
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor |
BlendMode::SubpixelDualSource => {
BlendMode::SubpixelDualSource |
BlendMode::Advanced(_) => {
self.alpha_batch_list
.set_params_and_get_batch(key, bounding_rect, z_id)
}
@ -475,18 +467,21 @@ pub struct AlphaBatchBuilder {
screen_size: DeviceIntSize,
task_scissor_rect: Option<DeviceIntRect>,
glyph_fetch_buffer: Vec<GlyphFetchResult>,
break_advanced_blend_batches: bool,
}
impl AlphaBatchBuilder {
pub fn new(
screen_size: DeviceIntSize,
task_scissor_rect: Option<DeviceIntRect>,
break_advanced_blend_batches: bool,
) -> Self {
let batch_lists = vec![
BatchList::new(
screen_size,
Vec::new(),
Vec::new(),
break_advanced_blend_batches,
),
];
@ -495,6 +490,7 @@ impl AlphaBatchBuilder {
task_scissor_rect,
screen_size,
glyph_fetch_buffer: Vec::new(),
break_advanced_blend_batches,
}
}
@ -507,6 +503,7 @@ impl AlphaBatchBuilder {
self.screen_size,
regions,
tile_blits,
self.break_advanced_blend_batches,
));
}
@ -1102,6 +1099,10 @@ impl AlphaBatchBuilder {
render_tasks,
).unwrap_or(OPAQUE_TASK_ADDRESS);
let surface = ctx.surfaces[raster_config.surface_index.0]
.surface
.as_ref();
match raster_config.composite_mode {
PictureCompositeMode::TileCache { .. } => {
let tile_cache = picture.tile_cache.as_ref().unwrap();
@ -1256,10 +1257,6 @@ impl AlphaBatchBuilder {
}
}
PictureCompositeMode::Filter(ref filter) => {
let surface = ctx.surfaces[raster_config.surface_index.0]
.surface
.as_ref()
.expect("bug: surface must be allocated by now");
assert!(filter.is_visible());
match filter {
FilterOp::Blur(..) => {
@ -1267,6 +1264,7 @@ impl AlphaBatchBuilder {
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
);
let (uv_rect_address, textures) = surface
.expect("bug: surface must be allocated by now")
.resolve(
render_tasks,
ctx.resource_cache,
@ -1329,7 +1327,9 @@ impl AlphaBatchBuilder {
let content_key = BatchKey::new(kind, non_segmented_blend_mode, content_textures);
// Retrieve the UV rect addresses for shadow/content.
let cache_task_id = surface.resolve_render_task_id();
let cache_task_id = surface
.expect("bug: surface must be allocated by now")
.resolve_render_task_id();
let shadow_uv_rect_address = render_tasks[cache_task_id]
.get_texture_address(gpu_cache)
.as_int();
@ -1443,6 +1443,7 @@ impl AlphaBatchBuilder {
};
let (uv_rect_address, textures) = surface
.expect("bug: surface must be allocated by now")
.resolve(
render_tasks,
ctx.resource_cache,
@ -1484,12 +1485,6 @@ impl AlphaBatchBuilder {
// This is basically the same as the general filter case above
// except we store a little more data in the filter mode and
// a gpu cache handle in the user data.
let surface = ctx.surfaces[raster_config.surface_index.0]
.surface
.as_ref()
.expect("bug: surface must be allocated by now");
let filter_data = &ctx.data_stores.filter_data[handle];
let filter_mode : i32 = 13 |
((filter_data.data.r_func.to_int() << 28 |
@ -1500,6 +1495,7 @@ impl AlphaBatchBuilder {
let user_data = filter_data.gpu_cache_handle.as_int(gpu_cache);
let (uv_rect_address, textures) = surface
.expect("bug: surface must be allocated by now")
.resolve(
render_tasks,
ctx.resource_cache,
@ -1535,12 +1531,48 @@ impl AlphaBatchBuilder {
PrimitiveInstanceData::from(instance),
);
}
PictureCompositeMode::MixBlend(mode) if ctx.use_advanced_blending => {
let (uv_rect_address, textures) = surface
.expect("bug: surface must be allocated by now")
.resolve(
render_tasks,
ctx.resource_cache,
gpu_cache,
);
let key = BatchKey::new(
BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray),
),
BlendMode::Advanced(mode),
textures,
);
let prim_header_index = prim_headers.push(&prim_header, z_id, [
ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
RasterizationSpace::Local as i32,
get_shader_opacity(1.0),
0,
]);
let instance = BrushInstance {
prim_header_index,
clip_task_address,
segment_index: INVALID_SEGMENT_INDEX,
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags,
user_data: uv_rect_address.as_int(),
};
self.current_batch_list().push_single_instance(
key,
bounding_rect,
z_id,
PrimitiveInstanceData::from(instance),
);
}
PictureCompositeMode::MixBlend(mode) => {
let surface = ctx.surfaces[raster_config.surface_index.0]
.surface
.as_ref()
.expect("bug: surface must be allocated by now");
let cache_task_id = surface.resolve_render_task_id();
let cache_task_id = surface
.expect("bug: surface must be allocated by now")
.resolve_render_task_id();
let backdrop_id = picture.secondary_render_task_id.expect("no backdrop!?");
let key = BatchKey::new(
@ -1580,11 +1612,9 @@ impl AlphaBatchBuilder {
);
}
PictureCompositeMode::Blit(_) => {
let surface = ctx.surfaces[raster_config.surface_index.0]
.surface
.as_ref()
.expect("bug: surface must be allocated by now");
let cache_task_id = surface.resolve_render_task_id();
let cache_task_id = surface
.expect("bug: surface must be allocated by now")
.resolve_render_task_id();
let uv_rect_address = render_tasks[cache_task_id]
.get_texture_address(gpu_cache)
.as_int();

View File

@ -4,7 +4,7 @@
use super::super::shader_source::SHADERS;
use api::{ColorF, ImageDescriptor, ImageFormat, MemoryReport};
use api::{TextureTarget, VoidPtrToSizeFn};
use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
use api::units::*;
use euclid::Transform3D;
use gleam::gl;
@ -3052,6 +3052,31 @@ impl Device {
self.gl.blend_equation(gl::FUNC_ADD);
}
pub fn set_blend_mode_advanced(&self, mode: MixBlendMode) {
self.gl.blend_equation(match mode {
MixBlendMode::Normal => {
// blend factor only make sense for the normal mode
self.gl.blend_func_separate(gl::ZERO, gl::SRC_COLOR, gl::ZERO, gl::SRC_ALPHA);
gl::FUNC_ADD
},
MixBlendMode::Multiply => gl::MULTIPLY_KHR,
MixBlendMode::Screen => gl::SCREEN_KHR,
MixBlendMode::Overlay => gl::OVERLAY_KHR,
MixBlendMode::Darken => gl::DARKEN_KHR,
MixBlendMode::Lighten => gl::LIGHTEN_KHR,
MixBlendMode::ColorDodge => gl::COLORDODGE_KHR,
MixBlendMode::ColorBurn => gl::COLORBURN_KHR,
MixBlendMode::HardLight => gl::HARDLIGHT_KHR,
MixBlendMode::SoftLight => gl::SOFTLIGHT_KHR,
MixBlendMode::Difference => gl::DIFFERENCE_KHR,
MixBlendMode::Exclusion => gl::EXCLUSION_KHR,
MixBlendMode::Hue => gl::HSL_HUE_KHR,
MixBlendMode::Saturation => gl::HSL_SATURATION_KHR,
MixBlendMode::Color => gl::HSL_COLOR_KHR,
MixBlendMode::Luminosity => gl::HSL_LUMINOSITY_KHR,
});
}
pub fn supports_extension(&self, extension: &str) -> bool {
supports_extension(&self.extensions, extension)
}

View File

@ -46,7 +46,7 @@ impl Default for ChasePrimitive {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct FrameBuilderConfig {
@ -58,6 +58,8 @@ pub struct FrameBuilderConfig {
/// True if we're running tests (i.e. via wrench).
pub testing: bool,
pub gpu_supports_fast_clears: bool,
pub gpu_supports_advanced_blend: bool,
pub advanced_blend_is_coherent: bool,
}
/// A set of common / global resources that are retained between
@ -221,6 +223,8 @@ impl FrameBuilder {
enable_picture_caching: false,
testing: false,
gpu_supports_fast_clears: false,
gpu_supports_advanced_blend: false,
advanced_blend_is_coherent: false,
},
}
}
@ -584,6 +588,8 @@ impl FrameBuilder {
prim_store: &self.prim_store,
resource_cache,
use_dual_source_blending,
use_advanced_blending: self.config.gpu_supports_advanced_blend,
break_advanced_blend_batches: !self.config.advanced_blend_is_coherent,
clip_scroll_tree,
data_stores,
surfaces: &surfaces,

View File

@ -3103,7 +3103,7 @@ impl PicturePrimitive {
PictureSurface::RenderTask(render_task_id)
}
PictureCompositeMode::MixBlend(..) => {
PictureCompositeMode::MixBlend(..) if !frame_context.fb_config.gpu_supports_advanced_blend => {
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
@ -3193,6 +3193,7 @@ impl PicturePrimitive {
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
PictureSurface::RenderTask(render_task_id)
}
PictureCompositeMode::MixBlend(..) |
PictureCompositeMode::Blit(_) => {
// The SplitComposite shader used for 3d contexts doesn't snap
// to pixels, so we shouldn't snap our uv coordinates either.

View File

@ -34,7 +34,7 @@
//! up the scissor, are accepting already transformed coordinates, which we can get by
//! calling `DrawTarget::to_framebuffer_rect`
use api::{ApiMsg, BlobImageHandler, ColorF, ColorU};
use api::{ApiMsg, BlobImageHandler, ColorF, ColorU, MixBlendMode};
use api::{DocumentId, Epoch, ExternalImageId};
use api::{ExternalImageType, FontRenderMode, FrameMsg, ImageFormat, PipelineId};
use api::{ImageRendering, Checkpoint, NotificationRequest};
@ -1114,6 +1114,7 @@ pub enum BlendMode {
SubpixelDualSource,
SubpixelConstantTextColor(ColorF),
SubpixelWithBgColor,
Advanced(MixBlendMode),
}
/// Tracks the state of each row in the GPU cache texture.
@ -1864,6 +1865,8 @@ pub struct Renderer {
clear_color: Option<ColorF>,
enable_clear_scissor: bool,
enable_advanced_blend_barriers: bool,
debug: LazyInitializedDebugRenderer,
debug_flags: DebugFlags,
backend_profile_counters: BackendProfileCounters,
@ -2022,10 +2025,15 @@ impl Renderer {
};
let use_dual_source_blending =
supports_dual_source_blending &&
!options.disable_dual_source_blending &&
options.allow_dual_source_blending &&
// If using pixel local storage, subpixel AA isn't supported (we disable it on all
// mobile devices explicitly anyway).
!device.get_capabilities().supports_pixel_local_storage;
let ext_blend_equation_advanced =
options.allow_advanced_blend_equation &&
device.supports_extension("GL_KHR_blend_equation_advanced");
let ext_blend_equation_advanced_coherent =
device.supports_extension("GL_KHR_blend_equation_advanced_coherent");
// 512 is the minimum that the texture cache can work with.
const MIN_TEXTURE_SIZE: i32 = 512;
@ -2201,7 +2209,10 @@ impl Renderer {
enable_picture_caching: options.enable_picture_caching,
testing: options.testing,
gpu_supports_fast_clears: options.gpu_supports_fast_clears,
gpu_supports_advanced_blend: ext_blend_equation_advanced,
advanced_blend_is_coherent: ext_blend_equation_advanced_coherent,
};
info!("WR {:?}", config);
let device_pixel_ratio = options.device_pixel_ratio;
let debug_flags = options.debug_flags;
@ -2377,6 +2388,7 @@ impl Renderer {
max_recorded_profiles: options.max_recorded_profiles,
clear_color: options.clear_color,
enable_clear_scissor: options.enable_clear_scissor,
enable_advanced_blend_barriers: !ext_blend_equation_advanced_coherent,
last_time: 0,
gpu_profile,
gpu_glyph_renderer,
@ -3899,6 +3911,12 @@ impl Renderer {
self.device.set_blend_mode_subpixel_with_bg_color_pass0();
self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass0 as _);
}
BlendMode::Advanced(mode) => {
if self.enable_advanced_blend_barriers {
self.device.gl().blend_barrier_khr();
}
self.device.set_blend_mode_advanced(mode);
}
}
prev_blend_mode = batch.key.blend_mode;
}
@ -5602,7 +5620,6 @@ pub struct RendererOptions {
pub cached_programs: Option<Rc<ProgramCache>>,
pub debug_flags: DebugFlags,
pub renderer_id: Option<u64>,
pub disable_dual_source_blending: bool,
pub scene_builder_hooks: Option<Box<SceneBuilderHooks + Send>>,
pub sampler: Option<Box<AsyncPropertySampler + Send>>,
pub chase_primitive: ChasePrimitive,
@ -5615,6 +5632,8 @@ pub struct RendererOptions {
/// it is a performance win. The default is false, which tends to be best
/// performance on lower end / integrated GPUs.
pub gpu_supports_fast_clears: bool,
pub allow_dual_source_blending: bool,
pub allow_advanced_blend_equation: bool,
/// If true, allow WR to use pixel local storage if the device supports it.
/// For now, this defaults to false since the code is still experimental
/// and not complete. This option will probably be removed once support is
@ -5652,7 +5671,6 @@ impl Default for RendererOptions {
enclosing_size_of_op: None,
renderer_id: None,
cached_programs: None,
disable_dual_source_blending: false,
scene_builder_hooks: None,
sampler: None,
chase_primitive: ChasePrimitive::Nothing,
@ -5661,6 +5679,8 @@ impl Default for RendererOptions {
enable_picture_caching: false,
testing: false,
gpu_supports_fast_clears: false,
allow_dual_source_blending: false,
allow_advanced_blend_equation: false,
allow_pixel_local_storage_support: false,
// For backwards compatibility we set this to true by default, so
// that if the debugger feature is enabled, the debug server will

View File

@ -341,7 +341,8 @@ impl BrushShader {
BlendMode::PremultipliedAlpha |
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor => &mut self.alpha,
BlendMode::SubpixelWithBgColor |
BlendMode::Advanced(_) => &mut self.alpha,
BlendMode::SubpixelDualSource => {
self.dual_source
.as_mut()
@ -681,10 +682,10 @@ impl Shaders {
options.precache_flags,
)?;
let dual_source_precache_flags = if options.disable_dual_source_blending {
ShaderPrecacheFlags::empty()
} else {
let dual_source_precache_flags = if options.allow_dual_source_blending {
options.precache_flags
} else {
ShaderPrecacheFlags::empty()
};
let ps_text_run_dual_source = TextShader::new("ps_text_run",
@ -719,7 +720,7 @@ impl Shaders {
device,
&image_features,
options.precache_flags,
!options.disable_dual_source_blending,
options.allow_dual_source_blending,
use_pixel_local_storage,
)?);
}

View File

@ -56,6 +56,8 @@ pub struct RenderTargetContext<'a, 'rc> {
pub prim_store: &'a PrimitiveStore,
pub resource_cache: &'rc mut ResourceCache,
pub use_dual_source_blending: bool,
pub use_advanced_blending: bool,
pub break_advanced_blend_batches: bool,
pub clip_scroll_tree: &'a ClipScrollTree,
pub data_stores: &'a DataStores,
pub surfaces: &'a [SurfaceInfo],
@ -432,6 +434,7 @@ impl RenderTarget for ColorRenderTarget {
let mut batch_builder = AlphaBatchBuilder::new(
self.screen_size,
scisor_rect,
ctx.break_advanced_blend_batches,
);
batch_builder.add_pic_to_batch(

View File

@ -2,7 +2,7 @@
== multiply-2.yaml multiply-2-ref.yaml
== color_targets(3) alpha_targets(0) multiply-3.yaml multiply-2-ref.yaml
== difference.yaml difference-ref.yaml
fuzzy(1,10000) == difference-transparent.yaml difference-transparent-ref.yaml
fuzzy(1,30000) == difference-transparent.yaml difference-transparent-ref.yaml
== darken.yaml darken-ref.yaml
== lighten.yaml lighten-ref.yaml

View File

@ -218,11 +218,12 @@ impl Wrench {
max_recorded_profiles: 16,
precache_flags,
blob_image_handler: Some(Box::new(blob::CheckerboardRenderer::new(callbacks.clone()))),
disable_dual_source_blending,
chase_primitive,
enable_picture_caching: true,
testing: true,
max_texture_size: Some(8196), // Needed for rawtest::test_resize_image.
allow_dual_source_blending: !disable_dual_source_blending,
allow_advanced_blend_equation: true,
..Default::default()
};

View File

@ -1 +1 @@
{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"6bf850af90d5a3828cf26170a161f2ed06fa3cf3783dce79d28fe6444654408e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"6ee689b1edfcd469dea669b0dc11ca89e0172c3b58bb82ff7a58acc94e1f7e88","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"2663b598573f7521d06f878229eee65434c831cf9fd4b543b4fcdd3bb1b281aa","src/gl_fns.rs":"239ace5607ee8dd4bcad35db0c4908469d7deb4841c162f736e404e1403980f7","src/gles_fns.rs":"51f25388f092242fb25bfe4861e70690006f4ac28e854d709ebb440cbef3df03","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"}
{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"40dda1b03ff20d8a3b4b544683f37a8d2b2137cfbb4d545122167352690d6b16","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"2d3833a24fee9d1f669f4cd7347b4ca8444a138d473ab9188f4d65f6981c4191","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"b7791f77dbbea690a7a0d33e3c083337a6b04a233a192dc8c96d4fe481a4a7ed","src/gl_fns.rs":"f88cd940691e0fca169cabbe2a95418300d09392d91a020079cfbdd5bacd753b","src/gles_fns.rs":"3766f2b76aa4038774a4754ce89cdcbb50286ab5bcf07cb0bb6e88f0de31f96f","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"7f46fd8874e043ffac0d638ed1567a2584f7814f6d72b4db37ab1689004a26c4"}

View File

@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
@ -12,7 +12,7 @@
[package]
name = "gleam"
version = "0.6.16"
version = "0.6.17"
authors = ["The Servo Project Developers"]
build = "build.rs"
description = "Generated OpenGL bindings and wrapper for Servo."

View File

@ -26,6 +26,8 @@ fn main() {
"GL_EXT_debug_marker",
"GL_EXT_texture_filter_anisotropic",
"GL_KHR_debug",
"GL_KHR_blend_equation_advanced",
"GL_KHR_blend_equation_advanced_coherent",
];
let gl_reg = Registry::new(
Api::Gl,
@ -47,12 +49,14 @@ fn main() {
"GL_EXT_texture_filter_anisotropic",
"GL_EXT_texture_format_BGRA8888",
"GL_EXT_texture_storage",
"GL_KHR_debug",
"GL_OES_EGL_image_external",
"GL_OES_EGL_image",
"GL_OES_texture_half_float",
"GL_EXT_shader_pixel_local_storage",
"GL_ANGLE_provoking_vertex",
"GL_KHR_debug",
"GL_KHR_blend_equation_advanced",
"GL_KHR_blend_equation_advanced_coherent",
];
let gles_reg = Registry::new(
Api::Gles2,

View File

@ -568,6 +568,8 @@ declare_gl_apis! {
fn test_fence_apple(&self, fence: GLuint);
fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean;
fn finish_object_apple(&self, object: GLenum, name: GLuint);
// GL_KHR_blend_equation_advanced
fn blend_barrier_khr(&self);
// GL_ARB_blend_func_extended
fn bind_frag_data_location_indexed(

View File

@ -2144,4 +2144,13 @@ impl Gl for GlFns {
fn provoking_vertex_angle(&self, _mode: GLenum) {
unimplemented!("This extension is GLES only");
}
// GL_KHR_blend_equation_advanced
fn blend_barrier_khr(&self) {
if self.ffi_gl_.BlendBarrierKHR.is_loaded() {
unsafe {
self.ffi_gl_.BlendBarrierKHR();
}
}
}
}

View File

@ -2111,4 +2111,13 @@ impl Gl for GlesFns {
self.ffi_gl_.ProvokingVertexANGLE(mode);
}
}
// GL_KHR_blend_equation_advanced
fn blend_barrier_khr(&self) {
if self.ffi_gl_.BlendBarrierKHR.is_loaded() {
unsafe {
self.ffi_gl_.BlendBarrierKHR();
}
}
}
}