Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support all image sampler kinds with brush_image implementation. #2412

Merged
merged 1 commit into from Feb 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions webrender/res/brush_image.glsl
Expand Up @@ -22,7 +22,13 @@ void brush_vs(
ivec2 user_data,
PictureTask pic_task
) {
vec2 texture_size = vec2(textureSize(sColor0, 0).xy);
// If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
// non-normalized texture coordinates.
#ifdef WR_FEATURE_TEXTURE_RECT
vec2 texture_size = vec2(1, 1);
#else
vec2 texture_size = vec2(textureSize(sColor0, 0));
#endif

ImageResource res = fetch_image_resource(user_data.x);
vec2 uv0 = res.uv_rect.p0;
Expand All @@ -46,7 +52,7 @@ void brush_vs(
vec4 brush_fs() {
vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);

vec4 color = texture(sColor0, vec3(uv, vUv.z));
vec4 color = TEX_SAMPLE(sColor0, vec3(uv, vUv.z));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this would be incorrect, given that we want to use the mipmaps, and this macro always picks lod of 0.0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed.


#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(vLocalPos);
Expand Down
2 changes: 1 addition & 1 deletion webrender/res/shared.glsl
Expand Up @@ -24,7 +24,7 @@
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
#else
// In normal case, we use textureLod(). We haven't used the lod yet. So, we always pass 0.0 now.
#define TEX_SAMPLE(sampler, tex_coord) textureLod(sampler, tex_coord, 0.0)
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord)
#endif

//======================================================================================
Expand Down
46 changes: 23 additions & 23 deletions webrender/src/batch.rs
Expand Up @@ -73,7 +73,7 @@ pub enum BrushBatchKind {
Picture(BrushImageSourceKind),
Solid,
Line,
Image,
Image(ImageBufferKind),
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
Expand Down Expand Up @@ -607,24 +607,6 @@ impl AlphaBatchBuilder {
}
}

fn get_buffer_kind(texture: SourceTexture) -> ImageBufferKind {
match texture {
SourceTexture::External(ext_image) => {
match ext_image.image_type {
ExternalImageType::TextureHandle(target) => {
target.into()
}
ExternalImageType::Buffer => {
// The ExternalImageType::Buffer should be handled by resource_cache.
// It should go through the non-external case.
panic!("Unexpected non-texture handle type");
}
}
}
_ => ImageBufferKind::Texture2DArray,
}
}

// Adds a primitive to a batch.
// It can recursively call itself in some situations, for
// example if it encounters a picture where the items
Expand Down Expand Up @@ -809,7 +791,7 @@ impl AlphaBatchBuilder {
return;
}

let batch_kind = TransformBatchKind::Image(Self::get_buffer_kind(cache_item.texture_id));
let batch_kind = TransformBatchKind::Image(get_buffer_kind(cache_item.texture_id));
let key = BatchKey::new(
BatchKind::Transformable(transform_kind, batch_kind),
non_segmented_blend_mode,
Expand Down Expand Up @@ -1278,11 +1260,11 @@ impl AlphaBatchBuilder {
}

// All yuv textures should be the same type.
let buffer_kind = Self::get_buffer_kind(textures.colors[0]);
let buffer_kind = get_buffer_kind(textures.colors[0]);
assert!(
textures.colors[1 .. image_yuv_cpu.format.get_plane_num()]
.iter()
.all(|&tid| buffer_kind == Self::get_buffer_kind(tid))
.all(|&tid| buffer_kind == get_buffer_kind(tid))
);

let kind = BatchKind::Transformable(
Expand Down Expand Up @@ -1427,7 +1409,7 @@ impl BrushPrimitive {
let textures = BatchTextures::color(cache_item.texture_id);

Some((
BrushBatchKind::Image,
BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)),
textures,
[cache_item.uv_rect_handle.as_int(gpu_cache), 0],
))
Expand Down Expand Up @@ -1697,3 +1679,21 @@ impl ClipBatcher {
}
}
}

fn get_buffer_kind(texture: SourceTexture) -> ImageBufferKind {
match texture {
SourceTexture::External(ext_image) => {
match ext_image.image_type {
ExternalImageType::TextureHandle(target) => {
target.into()
}
ExternalImageType::Buffer => {
// The ExternalImageType::Buffer should be handled by resource_cache.
// It should go through the non-external case.
panic!("Unexpected non-texture handle type");
}
}
}
_ => ImageBufferKind::Texture2DArray,
}
}
50 changes: 30 additions & 20 deletions webrender/src/renderer.rs
Expand Up @@ -236,7 +236,7 @@ impl BatchKind {
BrushBatchKind::Picture(..) => "Brush (Picture)",
BrushBatchKind::Solid => "Brush (Solid)",
BrushBatchKind::Line => "Brush (Line)",
BrushBatchKind::Image => "Brush (Image)",
BrushBatchKind::Image(..) => "Brush (Image)",
}
}
BatchKind::Transformable(_, batch_kind) => batch_kind.debug_name(),
Expand All @@ -254,7 +254,7 @@ impl BatchKind {
BrushBatchKind::Picture(..) => GPU_TAG_BRUSH_PICTURE,
BrushBatchKind::Solid => GPU_TAG_BRUSH_SOLID,
BrushBatchKind::Line => GPU_TAG_BRUSH_LINE,
BrushBatchKind::Image => GPU_TAG_BRUSH_IMAGE,
BrushBatchKind::Image(..) => GPU_TAG_BRUSH_IMAGE,
}
}
BatchKind::Transformable(_, batch_kind) => batch_kind.gpu_sampler_tag(),
Expand Down Expand Up @@ -1602,7 +1602,7 @@ pub struct Renderer {
brush_picture_a8: BrushShader,
brush_solid: BrushShader,
brush_line: BrushShader,
brush_image: BrushShader,
brush_image: Vec<Option<BrushShader>>,

/// These are "cache clip shaders". These shaders are used to
/// draw clip instances into the cached clip mask. The results
Expand Down Expand Up @@ -1819,13 +1819,6 @@ impl Renderer {
options.precache_shaders)
};

let brush_image = try!{
BrushShader::new("brush_image",
&mut device,
&[],
options.precache_shaders)
};

let brush_line = try!{
BrushShader::new("brush_line",
&mut device,
Expand Down Expand Up @@ -1910,10 +1903,12 @@ impl Renderer {

// All image configuration.
let mut image_features = Vec::new();
let mut ps_image: Vec<Option<PrimitiveShader>> = Vec::new();
let mut ps_image = Vec::new();
let mut brush_image = Vec::new();
// PrimitiveShader is not clonable. Use push() to initialize the vec.
for _ in 0 .. IMAGE_BUFFER_KINDS.len() {
ps_image.push(None);
brush_image.push(None);
}
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
if IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) {
Expand All @@ -1928,6 +1923,14 @@ impl Renderer {
options.precache_shaders)
};
ps_image[buffer_kind] = Some(shader);

let shader = try!{
BrushShader::new("brush_image",
&mut device,
&image_features,
options.precache_shaders)
};
brush_image[buffer_kind] = Some(shader);
}
image_features.clear();
}
Expand Down Expand Up @@ -3209,14 +3212,17 @@ impl Renderer {
&mut self.renderer_errors,
);
}
BrushBatchKind::Image => {
self.brush_image.bind(
&mut self.device,
key.blend_mode,
projection,
0,
&mut self.renderer_errors,
);
BrushBatchKind::Image(image_buffer_kind) => {
self.brush_image[image_buffer_kind as usize]
.as_mut()
.expect("Unsupported image shader kind")
.bind(
&mut self.device,
key.blend_mode,
projection,
0,
&mut self.renderer_errors,
);
}
BrushBatchKind::Picture(target_kind) => {
let shader = match target_kind {
Expand Down Expand Up @@ -4732,12 +4738,16 @@ impl Renderer {
self.brush_picture_a8.deinit(&mut self.device);
self.brush_solid.deinit(&mut self.device);
self.brush_line.deinit(&mut self.device);
self.brush_image.deinit(&mut self.device);
self.cs_clip_rectangle.deinit(&mut self.device);
self.cs_clip_image.deinit(&mut self.device);
self.cs_clip_border.deinit(&mut self.device);
self.ps_text_run.deinit(&mut self.device);
self.ps_text_run_dual_source.deinit(&mut self.device);
for shader in self.brush_image {
if let Some(shader) = shader {
shader.deinit(&mut self.device);
}
}
for shader in self.ps_image {
if let Some(shader) = shader {
shader.deinit(&mut self.device);
Expand Down