Skip to content

Commit

Permalink
Add a new TEXTURE_RECT_FEATURE feature in image shader for external i…
Browse files Browse the repository at this point in the history
…mage TextureRectHandle.
  • Loading branch information
JerryShih committed Mar 30, 2017
1 parent 1305f38 commit dec3102
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 9 deletions.
7 changes: 5 additions & 2 deletions webrender/res/ps_image.fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ void main(void) {
// account the spacing in between tiles. We only paint if our fragment does
// not fall into that spacing.
vec2 position_in_tile = mod(relative_pos_in_rect, vStretchSize + vTileSpacing);
// We clamp the texture coordinates to the half-pixel offset from the borders
// in order to avoid sampling outside of the texture area.
vec2 st = vTextureOffset + ((position_in_tile / vStretchSize) * vTextureSize);
st = clamp(st, vStRect.xy, vStRect.zw);

alpha = alpha * float(all(bvec2(step(position_in_tile, vStretchSize))));

#ifdef WR_FEATURE_TEXTURE_RECT
// textureLod doesn't support sampler2DRect. Use texture() instead.
oFragColor = vec4(alpha) * texture(sColor0, st);
#else
oFragColor = vec4(alpha) * textureLod(sColor0, st, 0.0);
#endif
}
5 changes: 4 additions & 1 deletion webrender/res/ps_image.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
* 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/. */

// If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use non-normalized
// texture coordinates. Otherwise, it uses normalized texture coordinates. Please
// check GL_TEXTURE_RECTANGLE.
flat varying vec2 vTextureOffset; // Offset of this image into the texture atlas.
flat varying vec2 vTextureSize; // Size of the image in the texture atlas.
flat varying vec2 vTileSpacing; // Amount of space between tiled instances of this image.
flat varying vec4 vStRect; // Rectangle of valid texture rect, in st-space.
flat varying vec4 vStRect; // Rectangle of valid texture rect.

#ifdef WR_FEATURE_TRANSFORM
varying vec3 vLocalPos;
Expand Down
20 changes: 16 additions & 4 deletions webrender/res/ps_image.vs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,28 @@ void main(void) {

write_clip(vi.screen_pos, prim.clip_area);

vTileSpacing = image.stretch_size_and_tile_spacing.zw;
vStretchSize = image.stretch_size_and_tile_spacing.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_normalization_factor = vec2(1, 1);
#else
vec2 texture_size_normalization_factor = vec2(textureSize(sColor0, 0));
#endif

// vUv will contain how many times this image has wrapped around the image size.
vec2 texture_size = vec2(textureSize(sColor0, 0));
vec2 st0 = res.uv_rect.xy / texture_size;
vec2 st1 = res.uv_rect.zw / texture_size;
vec2 st0 = res.uv_rect.xy / texture_size_normalization_factor;
vec2 st1 = res.uv_rect.zw / texture_size_normalization_factor;

vTextureSize = st1 - st0;
vTextureOffset = st0;
vTileSpacing = image.stretch_size_and_tile_spacing.zw;
vStretchSize = image.stretch_size_and_tile_spacing.xy;

vec2 half_texel = vec2(0.5) / texture_size;
// We clamp the texture coordinates to the half-pixel offset from the borders
// in order to avoid sampling outside of the texture area.
vec2 half_texel = vec2(0.5) / texture_size_normalization_factor;
vStRect = vec4(min(st0, st1) + half_texel, max(st0, st1) - half_texel);
}
6 changes: 6 additions & 0 deletions webrender/res/shared.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@
//======================================================================================
// Shared shader uniforms
//======================================================================================
#ifndef WR_FEATURE_TEXTURE_RECT
uniform sampler2D sColor0;
uniform sampler2D sColor1;
uniform sampler2D sColor2;
#else
uniform sampler2DRect sColor0;
uniform sampler2DRect sColor1;
uniform sampler2DRect sColor2;
#endif
uniform sampler2D sDither;
uniform sampler2D sMask;

Expand Down
15 changes: 15 additions & 0 deletions webrender/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const GPU_TAG_INIT: GpuProfileTag = GpuProfileTag { label: "Init", color: debug_
const GPU_TAG_SETUP_TARGET: GpuProfileTag = GpuProfileTag { label: "Target", color: debug_colors::SLATEGREY };
const GPU_TAG_PRIM_RECT: GpuProfileTag = GpuProfileTag { label: "Rect", color: debug_colors::RED };
const GPU_TAG_PRIM_IMAGE: GpuProfileTag = GpuProfileTag { label: "Image", color: debug_colors::GREEN };
const GPU_TAG_PRIM_IMAGE_RECT: GpuProfileTag = GpuProfileTag { label: "ImageRect", color: debug_colors::GREENYELLOW };
const GPU_TAG_PRIM_YUV_IMAGE: GpuProfileTag = GpuProfileTag { label: "YuvImage", color: debug_colors::DARKGREEN };
const GPU_TAG_PRIM_BLEND: GpuProfileTag = GpuProfileTag { label: "Blend", color: debug_colors::LIGHTBLUE };
const GPU_TAG_PRIM_HW_COMPOSITE: GpuProfileTag = GpuProfileTag { label: "HwComposite", color: debug_colors::DODGERBLUE };
Expand Down Expand Up @@ -223,6 +224,7 @@ pub type GradientDataStore = GpuStore<GradientData, GradientDataTextureLayout>;
const TRANSFORM_FEATURE: &'static str = "TRANSFORM";
const SUBPIXEL_AA_FEATURE: &'static str = "SUBPIXEL_AA";
const CLIP_FEATURE: &'static str = "CLIP";
const TEXTURE_RECT_FEATURE: &'static str = "TEXTURE_RECT";

enum ShaderKind {
Primitive,
Expand Down Expand Up @@ -465,6 +467,7 @@ pub struct Renderer {
ps_text_run: PrimitiveShader,
ps_text_run_subpixel: PrimitiveShader,
ps_image: PrimitiveShader,
ps_image_rect: PrimitiveShader,
ps_yuv_image: PrimitiveShader,
ps_border: PrimitiveShader,
ps_gradient: PrimitiveShader,
Expand Down Expand Up @@ -670,6 +673,13 @@ impl Renderer {
options.precache_shaders)
};

let ps_image_rect = try!{
PrimitiveShader::new("ps_image",
&mut device,
&[ TEXTURE_RECT_FEATURE ],
options.precache_shaders)
};

let ps_yuv_image = try!{
PrimitiveShader::new("ps_yuv_image",
&mut device,
Expand Down Expand Up @@ -912,6 +922,7 @@ impl Renderer {
ps_text_run: ps_text_run,
ps_text_run_subpixel: ps_text_run_subpixel,
ps_image: ps_image,
ps_image_rect: ps_image_rect,
ps_yuv_image: ps_yuv_image,
ps_border: ps_border,
ps_box_shadow: ps_box_shadow,
Expand Down Expand Up @@ -1346,6 +1357,10 @@ impl Renderer {
let shader = self.ps_image.get(&mut self.device, transform_kind);
(GPU_TAG_PRIM_IMAGE, shader)
}
AlphaBatchKind::ImageRect => {
let shader = self.ps_image_rect.get(&mut self.device, transform_kind);
(GPU_TAG_PRIM_IMAGE_RECT, shader)
}
AlphaBatchKind::YuvImage => {
let shader = self.ps_yuv_image.get(&mut self.device, transform_kind);
(GPU_TAG_PRIM_YUV_IMAGE, shader)
Expand Down
25 changes: 23 additions & 2 deletions webrender/src/tiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use webrender_traits::{DeviceIntSize, DeviceUintPoint};
use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerPoint, LayerRect};
use webrender_traits::{LayerToWorldTransform, MixBlendMode, PipelineId, ScrollLayerId};
use webrender_traits::{WorldPoint4D, WorldToLayerTransform};
use webrender_traits::{ExternalImageType};

// Special sentinel value recognized by the shader. It is considered to be
// a dummy task that doesn't mask out anything.
Expand Down Expand Up @@ -70,7 +71,24 @@ impl AlphaBatchHelpers for PrimitiveStore {
let batch_kind = match metadata.prim_kind {
PrimitiveKind::Border => AlphaBatchKind::Border,
PrimitiveKind::BoxShadow => AlphaBatchKind::BoxShadow,
PrimitiveKind::Image => AlphaBatchKind::Image,
PrimitiveKind::Image => {
let image_cpu = &self.cpu_images[metadata.cpu_prim_index.0];

match image_cpu.color_texture_id {
SourceTexture::External(ext_image) => {
match ext_image.image_type {
ExternalImageType::Texture2DHandle => AlphaBatchKind::Image,
ExternalImageType::TextureRectHandle => AlphaBatchKind::ImageRect,
_ => {
panic!("Non-texture handle type should be handled in other way.");
}
}
}
_ => {
AlphaBatchKind::Image
}
}
}
PrimitiveKind::YuvImage => AlphaBatchKind::YuvImage,
PrimitiveKind::Rectangle => AlphaBatchKind::Rectangle,
PrimitiveKind::AlignedGradient => AlphaBatchKind::AlignedGradient,
Expand Down Expand Up @@ -274,7 +292,8 @@ impl AlphaBatchHelpers for PrimitiveStore {
});
}
}
AlphaBatchKind::Image => {
AlphaBatchKind::Image |
AlphaBatchKind::ImageRect => {
let image_cpu = &self.cpu_images[metadata.cpu_prim_index.0];

data.push(PrimitiveInstance {
Expand Down Expand Up @@ -1311,6 +1330,7 @@ pub enum AlphaBatchKind {
Rectangle,
TextRun,
Image,
ImageRect,
YuvImage,
Border,
AlignedGradient,
Expand Down Expand Up @@ -1441,6 +1461,7 @@ impl PrimitiveBatch {
AlphaBatchKind::Rectangle |
AlphaBatchKind::TextRun |
AlphaBatchKind::Image |
AlphaBatchKind::ImageRect |
AlphaBatchKind::YuvImage |
AlphaBatchKind::Border |
AlphaBatchKind::AlignedGradient |
Expand Down

0 comments on commit dec3102

Please sign in to comment.