mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1454623 - Update webrender to ad06d8e05e8475c9788cffa7e6cbac70acbdb399. r=jrmuizel
MozReview-Commit-ID: JFDiNyCo0W --HG-- extra : rebase_source : 99b90deb5643cc5e15cd7fbd2867943c3631edeb
This commit is contained in:
parent
eaf147ebce
commit
1abb19edf6
@ -40,6 +40,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
for _ in 0 .. self.rect_count {
|
||||
|
@ -56,6 +56,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
filters,
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let complex_clip = ComplexClipRegion {
|
||||
|
@ -198,6 +198,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let image_mask_key = api.generate_image_key();
|
||||
|
@ -215,6 +215,7 @@ impl api::BlobImageRenderer for CheckerboardRenderer {
|
||||
}
|
||||
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) {}
|
||||
}
|
||||
|
||||
struct App {}
|
||||
@ -256,6 +257,7 @@ impl Example for App {
|
||||
None,
|
||||
api::MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
api::GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let info = api::LayoutPrimitiveInfo::new((30, 30).by(500, 500));
|
||||
|
@ -119,6 +119,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
builder.push_rect(
|
||||
&LayoutPrimitiveInfo::new(local_rect),
|
||||
|
@ -107,6 +107,7 @@ impl App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
builder.push_rect(&info, ColorF::new(1.0, 1.0, 0.0, 1.0));
|
||||
@ -155,6 +156,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
builder.push_image(
|
||||
|
@ -45,6 +45,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
// green rect visible == success
|
||||
@ -71,6 +72,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
// red rect under the iframe: if this is visible, things have gone wrong
|
||||
builder.push_rect(&info, ColorF::new(1.0, 0.0, 0.0, 1.0));
|
||||
|
@ -47,6 +47,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let image_size = LayoutSize::new(100.0, 100.0);
|
||||
|
@ -187,6 +187,7 @@ impl Window {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let info = LayoutPrimitiveInfo::new(LayoutRect::new(
|
||||
|
@ -40,6 +40,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
if true {
|
||||
@ -55,6 +56,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
// set the scrolling clip
|
||||
let clip_id = builder.define_scroll_frame(
|
||||
|
@ -99,6 +99,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let x0 = 50.0;
|
||||
|
@ -94,6 +94,7 @@ impl Example for App {
|
||||
None,
|
||||
MixBlendMode::Normal,
|
||||
Vec::new(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
let yuv_chanel1 = api.generate_image_key();
|
||||
|
@ -10,7 +10,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 segment_data
|
||||
);
|
||||
|
||||
#define VECS_PER_BRUSH_PRIM 2
|
||||
@ -148,7 +149,8 @@ void main(void) {
|
||||
brush_prim.local_rect,
|
||||
brush.user_data,
|
||||
scroll_node.transform,
|
||||
pic_task
|
||||
pic_task,
|
||||
segment_data[1]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 0
|
||||
#define VECS_PER_SPECIFIC_BRUSH 2
|
||||
#define FORCE_NO_PERSPECTIVE
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
@ -23,7 +23,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 unused
|
||||
) {
|
||||
PictureTask src_task = fetch_picture_task(user_data.x);
|
||||
vec2 texture_size = vec2(textureSize(sColor0, 0).xy);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 0
|
||||
#define VECS_PER_SPECIFIC_BRUSH 2
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
||||
@ -10,34 +10,52 @@
|
||||
varying vec2 vLocalPos;
|
||||
#endif
|
||||
|
||||
// Interpolated uv coordinates in xy, and layer in z.
|
||||
varying vec3 vUv;
|
||||
// Normalized bounds of the source image in the texture.
|
||||
flat varying vec4 vUvBounds;
|
||||
// Normalized bounds of the source image in the texture, adjusted to avoid
|
||||
// sampling artifacts.
|
||||
flat varying vec4 vUvSampleBounds;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
flat varying vec2 vSelect;
|
||||
flat varying vec4 vUvClipBounds;
|
||||
flat varying vec4 vColor;
|
||||
flat varying vec2 vMaskSwizzle;
|
||||
flat varying vec2 vTileRepeat;
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
#define IMAGE_SOURCE_COLOR 0
|
||||
#define IMAGE_SOURCE_ALPHA 1
|
||||
#define IMAGE_SOURCE_MASK_FROM_COLOR 2
|
||||
#endif
|
||||
|
||||
struct ImageBrush {
|
||||
RectWithSize rendered_task_rect;
|
||||
vec2 offset;
|
||||
struct ImageBrushData {
|
||||
vec4 color;
|
||||
vec4 background_color;
|
||||
};
|
||||
|
||||
ImageBrush fetch_image_primitive(int address) {
|
||||
vec4[3] data = fetch_from_resource_cache_3(address);
|
||||
RectWithSize rendered_task_rect = RectWithSize(data[0].xy, data[0].zw);
|
||||
ImageBrush brush = ImageBrush(rendered_task_rect, data[1].xy, data[2]);
|
||||
return brush;
|
||||
ImageBrushData fetch_image_data(int address) {
|
||||
vec4[2] raw_data = fetch_from_resource_cache_2(address);
|
||||
ImageBrushData data = ImageBrushData(
|
||||
raw_data[0],
|
||||
raw_data[1]
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
struct ImageBrushExtraData {
|
||||
RectWithSize rendered_task_rect;
|
||||
vec2 offset;
|
||||
};
|
||||
|
||||
ImageBrushExtraData fetch_image_extra_data(int address) {
|
||||
vec4[2] raw_data = fetch_from_resource_cache_2(address);
|
||||
RectWithSize rendered_task_rect = RectWithSize(
|
||||
raw_data[0].xy,
|
||||
raw_data[0].zw
|
||||
);
|
||||
ImageBrushExtraData data = ImageBrushExtraData(
|
||||
rendered_task_rect,
|
||||
raw_data[1].xy
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
@ -60,7 +78,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 repeat
|
||||
) {
|
||||
// If this is in WR_FEATURE_TEXTURE_RECT mode, the rect and size use
|
||||
// non-normalized texture coordinates.
|
||||
@ -81,7 +100,7 @@ void brush_vs(
|
||||
vec2 min_uv = min(uv0, uv1);
|
||||
vec2 max_uv = max(uv0, uv1);
|
||||
|
||||
vUvBounds = vec4(
|
||||
vUvSampleBounds = vec4(
|
||||
min_uv + vec2(0.5),
|
||||
max_uv - vec2(0.5)
|
||||
) / texture_size.xyxy;
|
||||
@ -89,16 +108,16 @@ void brush_vs(
|
||||
vec2 f;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
int image_source = user_data.y >> 16;
|
||||
int color_mode = user_data.y >> 16;
|
||||
int raster_space = user_data.y & 0xffff;
|
||||
ImageBrushData image_data = fetch_image_data(prim_address);
|
||||
|
||||
// Derive the texture coordinates for this image, based on
|
||||
// whether the source image is a local-space or screen-space
|
||||
// image.
|
||||
switch (raster_space) {
|
||||
case RASTER_SCREEN: {
|
||||
ImageBrush image = fetch_image_primitive(user_data.z);
|
||||
vColor = image.color;
|
||||
ImageBrushExtraData extra_data = fetch_image_extra_data(user_data.z);
|
||||
|
||||
vec2 snapped_device_pos;
|
||||
|
||||
@ -106,9 +125,9 @@ void brush_vs(
|
||||
// in order to generate the correct screen-space UV.
|
||||
// For other effects, we can use the 1:1 mapping of
|
||||
// the vertex device position for the UV generation.
|
||||
switch (image_source) {
|
||||
case IMAGE_SOURCE_MASK_FROM_COLOR: {
|
||||
vec2 local_pos = vi.local_pos - image.offset;
|
||||
switch (color_mode) {
|
||||
case COLOR_MODE_ALPHA: {
|
||||
vec2 local_pos = vi.local_pos - extra_data.offset;
|
||||
snapped_device_pos = transform_point_snapped(
|
||||
local_pos,
|
||||
local_rect,
|
||||
@ -116,33 +135,18 @@ void brush_vs(
|
||||
);
|
||||
break;
|
||||
}
|
||||
case IMAGE_SOURCE_COLOR:
|
||||
case IMAGE_SOURCE_ALPHA:
|
||||
default:
|
||||
snapped_device_pos = vi.snapped_device_pos;
|
||||
break;
|
||||
}
|
||||
|
||||
f = (snapped_device_pos - image.rendered_task_rect.p0) / image.rendered_task_rect.size;
|
||||
f = (snapped_device_pos - extra_data.rendered_task_rect.p0) / extra_data.rendered_task_rect.size;
|
||||
|
||||
vUvClipBounds = vec4(
|
||||
min_uv,
|
||||
max_uv
|
||||
) / texture_size.xyxy;
|
||||
break;
|
||||
}
|
||||
case RASTER_LOCAL:
|
||||
default: {
|
||||
vColor = vec4(1.0);
|
||||
f = (vi.local_pos - local_rect.p0) / local_rect.size;
|
||||
|
||||
// Set the clip bounds to a value that won't have any
|
||||
// effect for local space images.
|
||||
#ifdef WR_FEATURE_TEXTURE_RECT
|
||||
vUvClipBounds = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
|
||||
#else
|
||||
vUvClipBounds = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -150,21 +154,44 @@ void brush_vs(
|
||||
f = (vi.local_pos - local_rect.p0) / local_rect.size;
|
||||
#endif
|
||||
|
||||
vUv.xy = mix(uv0, uv1, f);
|
||||
// Offset and scale vUv here to avoid doing it in the fragment shader.
|
||||
vUv.xy = mix(uv0, uv1, f) - min_uv;
|
||||
vUv.xy /= texture_size;
|
||||
vUv.xy *= repeat.xy;
|
||||
|
||||
#ifdef WR_FEATURE_TEXTURE_RECT
|
||||
vUvBounds = vec4(0.0, 0.0, vec2(textureSize(sColor0)));
|
||||
#else
|
||||
vUvBounds = vec4(min_uv, max_uv) / texture_size.xyxy;
|
||||
#endif
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
switch (image_source) {
|
||||
case IMAGE_SOURCE_ALPHA:
|
||||
vSelect = vec2(0.0, 1.0);
|
||||
vTileRepeat = repeat.xy;
|
||||
|
||||
switch (color_mode) {
|
||||
case COLOR_MODE_ALPHA:
|
||||
case COLOR_MODE_BITMAP:
|
||||
vMaskSwizzle = vec2(0.0, 1.0);
|
||||
vColor = image_data.color;
|
||||
break;
|
||||
case IMAGE_SOURCE_MASK_FROM_COLOR:
|
||||
vSelect = vec2(1.0, 1.0);
|
||||
case COLOR_MODE_SUBPX_BG_PASS2:
|
||||
case COLOR_MODE_SUBPX_DUAL_SOURCE:
|
||||
vMaskSwizzle = vec2(1.0, 0.0);
|
||||
vColor = image_data.color;
|
||||
break;
|
||||
case COLOR_MODE_SUBPX_CONST_COLOR:
|
||||
case COLOR_MODE_SUBPX_BG_PASS0:
|
||||
case COLOR_MODE_COLOR_BITMAP:
|
||||
vMaskSwizzle = vec2(1.0, 0.0);
|
||||
vColor = vec4(image_data.color.a);
|
||||
break;
|
||||
case COLOR_MODE_SUBPX_BG_PASS1:
|
||||
vMaskSwizzle = vec2(-1.0, 1.0);
|
||||
vColor = vec4(image_data.color.a) * image_data.background_color;
|
||||
break;
|
||||
case IMAGE_SOURCE_COLOR:
|
||||
default:
|
||||
vSelect = vec2(0.0, 0.0);
|
||||
break;
|
||||
vMaskSwizzle = vec2(0.0);
|
||||
vColor = vec4(1.0);
|
||||
}
|
||||
|
||||
vLocalPos = vi.local_pos;
|
||||
@ -174,17 +201,41 @@ void brush_vs(
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
vec4 brush_fs() {
|
||||
vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
|
||||
|
||||
vec2 uv_size = vUvBounds.zw - vUvBounds.xy;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
// This prevents the uv on the top and left parts of the primitive that was inflated
|
||||
// for anti-aliasing purposes from going beyound the range covered by the regular
|
||||
// (non-inflated) primitive.
|
||||
vec2 local_uv = max(vUv.xy, vec2(0.0));
|
||||
|
||||
// Handle horizontal and vertical repetitions.
|
||||
vec2 repeated_uv = mod(local_uv, uv_size) + vUvBounds.xy;
|
||||
|
||||
// This takes care of the bottom and right inflated parts.
|
||||
// We do it after the modulo because the latter wraps around the values exactly on
|
||||
// the right and bottom edges, which we do not want.
|
||||
if (local_uv.x >= vTileRepeat.x * uv_size.x) {
|
||||
repeated_uv.x = vUvBounds.z;
|
||||
}
|
||||
if (local_uv.y >= vTileRepeat.y * uv_size.y) {
|
||||
repeated_uv.y = vUvBounds.w;
|
||||
}
|
||||
#else
|
||||
// Handle horizontal and vertical repetitions.
|
||||
vec2 repeated_uv = mod(vUv.xy, uv_size) + vUvBounds.xy;
|
||||
#endif
|
||||
|
||||
// Clamp the uvs to avoid sampling artifacts.
|
||||
vec2 uv = clamp(repeated_uv, vUvSampleBounds.xy, vUvSampleBounds.zw);
|
||||
|
||||
vec4 texel = TEX_SAMPLE(sColor0, vec3(uv, vUv.z));
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vec4 mask = mix(texel.rrrr, texel.aaaa, vSelect.x);
|
||||
vec4 color = mix(texel, vColor * mask, vSelect.y) * init_transform_fs(vLocalPos);
|
||||
|
||||
// Fail-safe to ensure that we don't sample outside the rendered
|
||||
// portion of a picture source.
|
||||
color.a *= point_inside_rect(vUv.xy, vUvClipBounds.xy, vUvClipBounds.zw);
|
||||
float alpha = init_transform_fs(vLocalPos);
|
||||
texel.rgb = texel.rgb * vMaskSwizzle.x + texel.aaa * vMaskSwizzle.y;
|
||||
vec4 color = vColor * texel * alpha;
|
||||
#else
|
||||
vec4 color = texel;
|
||||
#endif
|
||||
|
@ -11,11 +11,16 @@ flat varying float vGradientRepeat;
|
||||
|
||||
flat varying vec2 vScaledDir;
|
||||
flat varying vec2 vStartPoint;
|
||||
// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
|
||||
// repetitions. Not to be confused with another kind of repetition of the pattern
|
||||
// which happens along the gradient stops.
|
||||
flat varying vec2 vRepeatedSize;
|
||||
|
||||
varying vec2 vPos;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
varying vec2 vLocalPos;
|
||||
flat varying vec2 vTileRepeat;
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
@ -36,7 +41,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 tile_repeat
|
||||
) {
|
||||
Gradient gradient = fetch_gradient(prim_address);
|
||||
|
||||
@ -49,12 +55,15 @@ void brush_vs(
|
||||
vStartPoint = start_point;
|
||||
vScaledDir = dir / dot(dir, dir);
|
||||
|
||||
vRepeatedSize = local_rect.size / tile_repeat.xy;
|
||||
|
||||
vGradientAddress = user_data.x;
|
||||
|
||||
// Whether to repeat the gradient instead of clamping.
|
||||
// Whether to repeat the gradient along the line instead of clamping.
|
||||
vGradientRepeat = float(int(gradient.extend_mode.x) != EXTEND_MODE_CLAMP);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vTileRepeat = tile_repeat.xy;
|
||||
vLocalPos = vi.local_pos;
|
||||
#endif
|
||||
}
|
||||
@ -62,7 +71,28 @@ void brush_vs(
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
vec4 brush_fs() {
|
||||
float offset = dot(vPos - vStartPoint, vScaledDir);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
// Handle top and left inflated edges (see brush_image).
|
||||
vec2 local_pos = max(vPos, vec2(0.0));
|
||||
|
||||
// Apply potential horizontal and vertical repetitions.
|
||||
vec2 pos = mod(local_pos, vRepeatedSize);
|
||||
|
||||
vec2 prim_size = vRepeatedSize * vTileRepeat;
|
||||
// Handle bottom and right inflated edges (see brush_image).
|
||||
if (local_pos.x >= prim_size.x) {
|
||||
pos.x = vRepeatedSize.x;
|
||||
}
|
||||
if (local_pos.y >= prim_size.y) {
|
||||
pos.y = vRepeatedSize.y;
|
||||
}
|
||||
#else
|
||||
// Apply potential horizontal and vertical repetitions.
|
||||
vec2 pos = mod(vPos, vRepeatedSize);
|
||||
#endif
|
||||
|
||||
float offset = dot(pos - vStartPoint, vScaledDir);
|
||||
|
||||
vec4 color = sample_gradient(vGradientAddress,
|
||||
offset,
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 0
|
||||
#define VECS_PER_SPECIFIC_BRUSH 2
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
||||
@ -18,7 +18,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 unused
|
||||
) {
|
||||
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
|
||||
vOp = user_data.x;
|
||||
|
@ -14,9 +14,11 @@ flat varying float vStartRadius;
|
||||
flat varying float vEndRadius;
|
||||
|
||||
varying vec2 vPos;
|
||||
flat varying vec2 vRepeatedSize;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
varying vec2 vLocalPos;
|
||||
flat varying vec2 vTileRepeat;
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
@ -37,7 +39,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 tile_repeat
|
||||
) {
|
||||
RadialGradient gradient = fetch_radial_gradient(prim_address);
|
||||
|
||||
@ -52,6 +55,10 @@ void brush_vs(
|
||||
float ratio_xy = gradient.ratio_xy_extend_mode.x;
|
||||
vPos.y *= ratio_xy;
|
||||
vCenter.y *= ratio_xy;
|
||||
vRepeatedSize = local_rect.size / tile_repeat.xy;
|
||||
vRepeatedSize.y *= ratio_xy;
|
||||
|
||||
vPos;
|
||||
|
||||
vGradientAddress = user_data.x;
|
||||
|
||||
@ -59,6 +66,7 @@ void brush_vs(
|
||||
vGradientRepeat = float(int(gradient.ratio_xy_extend_mode.y) != EXTEND_MODE_CLAMP);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vTileRepeat = tile_repeat.xy;
|
||||
vLocalPos = vi.local_pos;
|
||||
#endif
|
||||
}
|
||||
@ -66,7 +74,28 @@ void brush_vs(
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
vec4 brush_fs() {
|
||||
vec2 pd = vPos - vCenter;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
// Handle top and left inflated edges (see brush_image).
|
||||
vec2 local_pos = max(vPos, vec2(0.0));
|
||||
|
||||
// Apply potential horizontal and vertical repetitions.
|
||||
vec2 pos = mod(local_pos, vRepeatedSize);
|
||||
|
||||
vec2 prim_size = vRepeatedSize * vTileRepeat;
|
||||
// Handle bottom and right inflated edges (see brush_image).
|
||||
if (local_pos.x >= prim_size.x) {
|
||||
pos.x = vRepeatedSize.x;
|
||||
}
|
||||
if (local_pos.y >= prim_size.y) {
|
||||
pos.y = vRepeatedSize.y;
|
||||
}
|
||||
#else
|
||||
// Apply potential horizontal and vertical repetitions.
|
||||
vec2 pos = mod(vPos, vRepeatedSize);
|
||||
#endif
|
||||
|
||||
vec2 pd = pos - vCenter;
|
||||
float rd = vEndRadius - vStartRadius;
|
||||
|
||||
// Solve for t in length(t - pd) = vStartRadius + t * rd
|
||||
|
@ -29,7 +29,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 unused
|
||||
) {
|
||||
SolidBrush prim = fetch_solid_primitive(prim_address);
|
||||
vColor = prim.color;
|
||||
|
@ -76,7 +76,8 @@ void brush_vs(
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
mat4 transform,
|
||||
PictureTask pic_task
|
||||
PictureTask pic_task,
|
||||
vec4 unused
|
||||
) {
|
||||
vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
|
||||
|
||||
|
@ -43,6 +43,15 @@ varying vec3 vClipMaskUv;
|
||||
#define VECS_PER_TEXT_RUN 3
|
||||
#define VECS_PER_GRADIENT_STOP 2
|
||||
|
||||
#define COLOR_MODE_ALPHA 1
|
||||
#define COLOR_MODE_SUBPX_CONST_COLOR 2
|
||||
#define COLOR_MODE_SUBPX_BG_PASS0 3
|
||||
#define COLOR_MODE_SUBPX_BG_PASS1 4
|
||||
#define COLOR_MODE_SUBPX_BG_PASS2 5
|
||||
#define COLOR_MODE_SUBPX_DUAL_SOURCE 6
|
||||
#define COLOR_MODE_BITMAP 7
|
||||
#define COLOR_MODE_COLOR_BITMAP 8
|
||||
|
||||
uniform HIGHP_SAMPLER_FLOAT sampler2D sLocalClipRects;
|
||||
|
||||
// Instanced attributes
|
||||
|
@ -15,17 +15,6 @@ varying vec4 vUvClip;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
#define MODE_ALPHA 0
|
||||
#define MODE_SUBPX_CONST_COLOR 1
|
||||
#define MODE_SUBPX_PASS0 2
|
||||
#define MODE_SUBPX_PASS1 3
|
||||
#define MODE_SUBPX_BG_PASS0 4
|
||||
#define MODE_SUBPX_BG_PASS1 5
|
||||
#define MODE_SUBPX_BG_PASS2 6
|
||||
#define MODE_SUBPX_DUAL_SOURCE 7
|
||||
#define MODE_BITMAP 8
|
||||
#define MODE_COLOR_BITMAP 9
|
||||
|
||||
VertexInfo write_text_vertex(vec2 clamped_local_pos,
|
||||
RectWithSize local_clip_rect,
|
||||
float z,
|
||||
@ -135,25 +124,23 @@ void main(void) {
|
||||
write_clip(vi.screen_pos, prim.clip_area);
|
||||
|
||||
switch (uMode) {
|
||||
case MODE_ALPHA:
|
||||
case MODE_BITMAP:
|
||||
case COLOR_MODE_ALPHA:
|
||||
case COLOR_MODE_BITMAP:
|
||||
vMaskSwizzle = vec2(0.0, 1.0);
|
||||
vColor = text.color;
|
||||
break;
|
||||
case MODE_SUBPX_PASS1:
|
||||
case MODE_SUBPX_BG_PASS2:
|
||||
case MODE_SUBPX_DUAL_SOURCE:
|
||||
case COLOR_MODE_SUBPX_BG_PASS2:
|
||||
case COLOR_MODE_SUBPX_DUAL_SOURCE:
|
||||
vMaskSwizzle = vec2(1.0, 0.0);
|
||||
vColor = text.color;
|
||||
break;
|
||||
case MODE_SUBPX_CONST_COLOR:
|
||||
case MODE_SUBPX_PASS0:
|
||||
case MODE_SUBPX_BG_PASS0:
|
||||
case MODE_COLOR_BITMAP:
|
||||
case COLOR_MODE_SUBPX_CONST_COLOR:
|
||||
case COLOR_MODE_SUBPX_BG_PASS0:
|
||||
case COLOR_MODE_COLOR_BITMAP:
|
||||
vMaskSwizzle = vec2(1.0, 0.0);
|
||||
vColor = vec4(text.color.a);
|
||||
break;
|
||||
case MODE_SUBPX_BG_PASS1:
|
||||
case COLOR_MODE_SUBPX_BG_PASS1:
|
||||
vMaskSwizzle = vec2(-1.0, 1.0);
|
||||
vColor = vec4(text.color.a) * text.bg_color;
|
||||
break;
|
||||
|
@ -17,13 +17,15 @@ use gpu_types::{ClipMaskInstance, ClipScrollNodeIndex, RasterizationSpace};
|
||||
use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveInstance};
|
||||
use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture};
|
||||
use picture::{PictureCompositeMode, PicturePrimitive, PictureSurface};
|
||||
use picture::{IMAGE_BRUSH_BLOCKS, IMAGE_BRUSH_EXTRA_BLOCKS};
|
||||
use plane_split::{BspSplitter, Polygon, Splitter};
|
||||
use prim_store::{CachedGradient, ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore};
|
||||
use prim_store::{BrushPrimitive, BrushKind, DeferredResolve, EdgeAaSegmentMask, PictureIndex, PrimitiveRun};
|
||||
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKind, RenderTaskTree};
|
||||
use renderer::{BlendMode, ImageBufferKind};
|
||||
use renderer::BLOCKS_PER_UV_RECT;
|
||||
use renderer::{BLOCKS_PER_UV_RECT, ShaderColorMode};
|
||||
use resource_cache::{CacheItem, GlyphFetchResult, ImageRequest, ResourceCache};
|
||||
use scene::FilterOpHelpers;
|
||||
use std::{usize, f32, i32};
|
||||
use tiling::{RenderTargetContext};
|
||||
use util::{MatrixHelpers, TransformedRectKind};
|
||||
@ -42,15 +44,6 @@ pub enum TransformBatchKind {
|
||||
BorderEdge,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum BrushImageSourceKind {
|
||||
Color = 0,
|
||||
//Alpha = 1, // Unused for now, but left here as shaders need to match.
|
||||
ColorAlphaMask = 2,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -161,16 +154,15 @@ impl AlphaBatchList {
|
||||
) -> &mut Vec<PrimitiveInstance> {
|
||||
let mut selected_batch_index = None;
|
||||
|
||||
match (key.kind, key.blend_mode) {
|
||||
(BatchKind::Transformable(_, TransformBatchKind::TextRun(_)), BlendMode::SubpixelWithBgColor) |
|
||||
(BatchKind::Transformable(_, TransformBatchKind::TextRun(_)), BlendMode::SubpixelVariableTextColor) => {
|
||||
'outer_text: for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) {
|
||||
// Subpixel text is drawn in two passes. Because of this, we need
|
||||
match key.blend_mode {
|
||||
BlendMode::SubpixelWithBgColor => {
|
||||
'outer_multipass: for (batch_index, batch) in self.batches.iter().enumerate().rev().take(10) {
|
||||
// Some subpixel batches are drawn in two passes. Because of this, we need
|
||||
// to check for overlaps with every batch (which is a bit different
|
||||
// than the normal batching below).
|
||||
for item_rect in &self.item_rects[batch_index] {
|
||||
if item_rect.intersects(task_relative_bounding_rect) {
|
||||
break 'outer_text;
|
||||
break 'outer_multipass;
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +313,6 @@ impl BatchList {
|
||||
BlendMode::PremultipliedAlpha |
|
||||
BlendMode::PremultipliedDestOut |
|
||||
BlendMode::SubpixelConstantTextColor(..) |
|
||||
BlendMode::SubpixelVariableTextColor |
|
||||
BlendMode::SubpixelWithBgColor |
|
||||
BlendMode::SubpixelDualSource => {
|
||||
self.alpha_batch_list
|
||||
@ -598,6 +589,9 @@ impl AlphaBatchBuilder {
|
||||
) {
|
||||
let z = z_generator.next();
|
||||
let prim_metadata = ctx.prim_store.get_metadata(prim_index);
|
||||
#[cfg(debug_assertions)] //TODO: why is this needed?
|
||||
debug_assert_eq!(prim_metadata.prepared_frame_id, render_tasks.frame_id());
|
||||
|
||||
let scroll_node = &ctx.node_data[scroll_id.0 as usize];
|
||||
// TODO(gw): Calculating this for every primitive is a bit
|
||||
// wasteful. We should probably cache this in
|
||||
@ -670,6 +664,7 @@ impl AlphaBatchBuilder {
|
||||
|
||||
let add_to_parent_pic = match picture.composite_mode {
|
||||
Some(PictureCompositeMode::Filter(filter)) => {
|
||||
assert!(filter.is_visible());
|
||||
match filter {
|
||||
FilterOp::Blur(..) => {
|
||||
match picture.surface {
|
||||
@ -702,7 +697,7 @@ impl AlphaBatchBuilder {
|
||||
brush_flags: BrushFlags::empty(),
|
||||
user_data: [
|
||||
uv_rect_address.as_int(),
|
||||
(BrushImageSourceKind::Color as i32) << 16 |
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
picture.extra_gpu_data_handle.as_int(gpu_cache),
|
||||
],
|
||||
@ -755,8 +750,10 @@ impl AlphaBatchBuilder {
|
||||
|
||||
// Get the GPU cache address of the extra data handle.
|
||||
let extra_data_address = gpu_cache.get_address(&picture.extra_gpu_data_handle);
|
||||
let shadow_prim_address = extra_data_address.offset(3);
|
||||
let shadow_data_address = extra_data_address.offset(7);
|
||||
let shadow_prim_address = extra_data_address
|
||||
.offset(IMAGE_BRUSH_EXTRA_BLOCKS);
|
||||
let shadow_data_address = extra_data_address
|
||||
.offset(IMAGE_BRUSH_EXTRA_BLOCKS + IMAGE_BRUSH_BLOCKS);
|
||||
|
||||
let shadow_instance = BrushInstance {
|
||||
picture_address: task_address,
|
||||
@ -770,7 +767,7 @@ impl AlphaBatchBuilder {
|
||||
brush_flags: BrushFlags::empty(),
|
||||
user_data: [
|
||||
shadow_uv_rect_address,
|
||||
(BrushImageSourceKind::ColorAlphaMask as i32) << 16 |
|
||||
(ShaderColorMode::Alpha as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
shadow_data_address.as_int(),
|
||||
],
|
||||
@ -780,7 +777,7 @@ impl AlphaBatchBuilder {
|
||||
prim_address: prim_cache_address,
|
||||
user_data: [
|
||||
content_uv_rect_address,
|
||||
(BrushImageSourceKind::Color as i32) << 16 |
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
extra_data_address.as_int(),
|
||||
],
|
||||
@ -953,7 +950,7 @@ impl AlphaBatchBuilder {
|
||||
brush_flags: BrushFlags::empty(),
|
||||
user_data: [
|
||||
uv_rect_address,
|
||||
(BrushImageSourceKind::Color as i32) << 16 |
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
picture.extra_gpu_data_handle.as_int(gpu_cache),
|
||||
],
|
||||
@ -1336,7 +1333,7 @@ impl BrushPrimitive {
|
||||
textures,
|
||||
[
|
||||
cache_item.uv_rect_handle.as_int(gpu_cache),
|
||||
(BrushImageSourceKind::Color as i32) << 16|
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16|
|
||||
RasterizationSpace::Local as i32,
|
||||
0,
|
||||
],
|
||||
|
@ -6,7 +6,7 @@
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, ClipAndScrollInfo};
|
||||
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
|
||||
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, Epoch, ExtendMode, ExternalScrollId};
|
||||
use api::{FilterOp, FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop};
|
||||
use api::{FilterOp, FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GlyphRasterSpace, GradientStop};
|
||||
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo};
|
||||
use api::{LayerRect, LayerSize, LayerVector2D, LayoutRect, LayoutSize, LayoutTransform};
|
||||
use api::{LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId, PropertyBinding};
|
||||
@ -334,6 +334,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
true,
|
||||
root_scroll_node,
|
||||
None,
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
// For the root pipeline, there's no need to add a full screen rectangle
|
||||
@ -539,6 +540,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
false,
|
||||
final_scroll_node,
|
||||
stacking_context.clip_node_id,
|
||||
stacking_context.glyph_raster_space,
|
||||
);
|
||||
|
||||
self.flatten_items(
|
||||
@ -974,6 +976,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
is_pipeline_root: bool,
|
||||
positioning_node: ClipId,
|
||||
clipping_node: Option<ClipId>,
|
||||
glyph_raster_space: GlyphRasterSpace,
|
||||
) {
|
||||
let clip_chain_id = match clipping_node {
|
||||
Some(ref clipping_node) => self.id_to_index_mapper.get_clip_chain_index(clipping_node),
|
||||
@ -1237,6 +1240,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
allow_subpixel_aa,
|
||||
transform_style,
|
||||
rendering_context_3d_pic_index,
|
||||
glyph_raster_space,
|
||||
};
|
||||
|
||||
self.sc_stack.push(sc);
|
||||
@ -2065,19 +2069,24 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
flags |= options.flags;
|
||||
}
|
||||
|
||||
let (allow_subpixel_aa, glyph_raster_space) = match self.sc_stack.last() {
|
||||
Some(stacking_context) => {
|
||||
(stacking_context.allow_subpixel_aa, stacking_context.glyph_raster_space)
|
||||
}
|
||||
None => {
|
||||
(true, GlyphRasterSpace::Screen)
|
||||
}
|
||||
};
|
||||
|
||||
// There are some conditions under which we can't use
|
||||
// subpixel text rendering, even if enabled.
|
||||
if render_mode == FontRenderMode::Subpixel {
|
||||
if !allow_subpixel_aa {
|
||||
// text on a picture that has filters
|
||||
// (e.g. opacity) can't use sub-pixel.
|
||||
// TODO(gw): It's possible we can relax this in
|
||||
// the future, if we modify the way
|
||||
// we handle subpixel blending.
|
||||
if let Some(stacking_context) = self.sc_stack.last() {
|
||||
if !stacking_context.allow_subpixel_aa {
|
||||
render_mode = FontRenderMode::Alpha;
|
||||
}
|
||||
}
|
||||
render_mode = render_mode.limit_by(FontRenderMode::Alpha);
|
||||
}
|
||||
|
||||
let prim_font = FontInstance::new(
|
||||
@ -2098,6 +2107,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
glyph_keys: Vec::new(),
|
||||
offset: run_offset,
|
||||
shadow: false,
|
||||
glyph_raster_space,
|
||||
}
|
||||
};
|
||||
|
||||
@ -2337,6 +2347,10 @@ struct FlattenedStackingContext {
|
||||
/// on transparent stacking contexts.
|
||||
allow_subpixel_aa: bool,
|
||||
|
||||
/// The rasterization mode for any text runs that are part
|
||||
/// of this stacking context.
|
||||
glyph_raster_space: GlyphRasterSpace,
|
||||
|
||||
/// CSS transform-style property.
|
||||
transform_style: TransformStyle,
|
||||
|
||||
|
@ -558,7 +558,10 @@ impl GpuCache {
|
||||
pub fn invalidate(&mut self, handle: &GpuCacheHandle) {
|
||||
if let Some(ref location) = handle.location {
|
||||
let block = &mut self.texture.blocks[location.block_index.0];
|
||||
block.epoch.next();
|
||||
// don't invalidate blocks that are already re-assigned
|
||||
if block.epoch == location.epoch {
|
||||
block.epoch.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,9 @@ use tiling::RenderTargetKind;
|
||||
this picture (e.g. in screen space or local space).
|
||||
*/
|
||||
|
||||
pub const IMAGE_BRUSH_EXTRA_BLOCKS: usize = 2;
|
||||
pub const IMAGE_BRUSH_BLOCKS: usize = 6;
|
||||
|
||||
/// Specifies how this Picture should be composited
|
||||
/// onto the target it belongs to.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
@ -547,10 +550,9 @@ impl PicturePrimitive {
|
||||
}
|
||||
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.extra_gpu_data_handle) {
|
||||
// [GLSL ImageBrush: task_rect, offset, color]
|
||||
// [GLSL ImageBrushExtraData: task_rect, offset]
|
||||
request.push(self.task_rect.to_f32());
|
||||
request.push([0.0; 4]);
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
|
||||
// TODO(gw): It would make the shaders a bit simpler if the offset
|
||||
// was provided as part of the brush::picture instance,
|
||||
@ -563,22 +565,32 @@ impl PicturePrimitive {
|
||||
// we could consider abstracting the code in prim_store.rs
|
||||
// that writes a brush primitive header.
|
||||
|
||||
// NOTE: If any of the layout below changes, the IMAGE_BRUSH_EXTRA_BLOCKS and
|
||||
// IMAGE_BRUSH_BLOCKS fields above *must* be updated.
|
||||
|
||||
// Basic brush primitive header is (see end of prepare_prim_for_render_inner in prim_store.rs)
|
||||
// local_rect
|
||||
// clip_rect
|
||||
// [segment_rect, segment_data]
|
||||
// [brush specific data]
|
||||
// [segment_rect, (repetitions.xy, 0.0, 0.0)]
|
||||
let shadow_rect = prim_metadata.local_rect.translate(&offset);
|
||||
let shadow_clip_rect = prim_metadata.local_clip_rect.translate(&offset);
|
||||
|
||||
// local_rect, clip_rect
|
||||
request.push(shadow_rect);
|
||||
request.push(shadow_clip_rect);
|
||||
|
||||
// ImageBrush colors
|
||||
request.push(color.premultiplied());
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
|
||||
// segment rect / repetitions
|
||||
request.push(shadow_rect);
|
||||
request.push([0.0; 4]);
|
||||
request.push([1.0, 1.0, 0.0, 0.0]);
|
||||
|
||||
// Now write another GLSL ImageBrush struct, for the shadow to reference.
|
||||
request.push(self.task_rect.to_f32());
|
||||
request.push([offset.x, offset.y, 0.0, 0.0]);
|
||||
request.push(color.premultiplied());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
use api::{AlphaType, BorderRadius, BoxShadowClipMode, BuiltDisplayList, ClipMode, ColorF, ComplexClipRegion};
|
||||
use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch, ExtendMode, FontRenderMode};
|
||||
use api::{FilterOp, GlyphInstance, GlyphKey, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag};
|
||||
use api::{LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D};
|
||||
use api::{GlyphRasterSpace, LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D};
|
||||
use api::{PipelineId, PremultipliedColorF, Shadow, YuvColorSpace, YuvFormat};
|
||||
use border::{BorderCornerInstance, BorderEdgeKind};
|
||||
use box_shadow::BLUR_SAMPLE_SCALE;
|
||||
@ -20,6 +20,8 @@ use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuData
|
||||
ToGpuBlocks};
|
||||
use gpu_types::{ClipChainRectIndex};
|
||||
use picture::{PictureCompositeMode, PictureId, PicturePrimitive};
|
||||
#[cfg(debug_assertions)]
|
||||
use render_backend::FrameId;
|
||||
use render_task::{BlitSource, RenderTask, RenderTaskCacheKey};
|
||||
use render_task::{RenderTaskCacheKeyKind, RenderTaskId, RenderTaskCacheEntryHandle};
|
||||
use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
|
||||
@ -191,6 +193,11 @@ pub struct PrimitiveMetadata {
|
||||
/// A tag used to identify this primitive outside of WebRender. This is
|
||||
/// used for returning useful data during hit testing.
|
||||
pub tag: Option<ItemTag>,
|
||||
|
||||
/// The last frame ID (of the `RenderTaskTree`) this primitive
|
||||
/// was prepared for rendering in.
|
||||
#[cfg(debug_assertions)]
|
||||
pub prepared_frame_id: FrameId,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -339,9 +346,14 @@ impl BrushPrimitive {
|
||||
) {
|
||||
// has to match VECS_PER_SPECIFIC_BRUSH
|
||||
match self.kind {
|
||||
BrushKind::YuvImage { .. } => {}
|
||||
|
||||
BrushKind::Picture { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::Image { .. } => {}
|
||||
BrushKind::Image { .. } => {
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
}
|
||||
|
||||
BrushKind::Solid { color } => {
|
||||
request.push(color.premultiplied());
|
||||
}
|
||||
@ -627,6 +639,7 @@ pub struct TextRunPrimitiveCpu {
|
||||
pub glyph_keys: Vec<GlyphKey>,
|
||||
pub glyph_gpu_blocks: Vec<GpuBlockData>,
|
||||
pub shadow: bool,
|
||||
pub glyph_raster_space: GlyphRasterSpace,
|
||||
}
|
||||
|
||||
impl TextRunPrimitiveCpu {
|
||||
@ -638,7 +651,9 @@ impl TextRunPrimitiveCpu {
|
||||
let mut font = self.font.clone();
|
||||
font.size = font.size.scale_by(device_pixel_scale.0);
|
||||
if let Some(transform) = transform {
|
||||
if transform.has_perspective_component() || !transform.has_2d_inverse() {
|
||||
if transform.has_perspective_component() ||
|
||||
!transform.has_2d_inverse() ||
|
||||
self.glyph_raster_space != GlyphRasterSpace::Screen {
|
||||
font.render_mode = font.render_mode.limit_by(FontRenderMode::Alpha);
|
||||
} else {
|
||||
font.transform = FontTransform::from(&transform).quantize();
|
||||
@ -965,6 +980,7 @@ impl PrimitiveContainer {
|
||||
glyph_keys: info.glyph_keys.clone(),
|
||||
glyph_gpu_blocks: Vec::new(),
|
||||
shadow: true,
|
||||
glyph_raster_space: info.glyph_raster_space,
|
||||
})
|
||||
}
|
||||
PrimitiveContainer::Brush(ref brush) => {
|
||||
@ -1083,6 +1099,8 @@ impl PrimitiveStore {
|
||||
opacity: PrimitiveOpacity::translucent(),
|
||||
prim_kind: PrimitiveKind::Brush,
|
||||
cpu_prim_index: SpecificPrimitiveIndex(0),
|
||||
#[cfg(debug_assertions)]
|
||||
prepared_frame_id: FrameId(0),
|
||||
};
|
||||
|
||||
let metadata = match container {
|
||||
@ -1167,6 +1185,11 @@ impl PrimitiveStore {
|
||||
frame_state: &mut FrameBuildingState,
|
||||
) {
|
||||
let metadata = &mut self.cpu_metadata[prim_index.0];
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
metadata.prepared_frame_id = frame_state.render_tasks.frame_id();
|
||||
}
|
||||
|
||||
match metadata.prim_kind {
|
||||
PrimitiveKind::Border => {}
|
||||
PrimitiveKind::TextRun => {
|
||||
@ -1958,7 +1981,13 @@ impl PrimitiveStore {
|
||||
pic.runs = pic_context_for_children.prim_runs;
|
||||
|
||||
let metadata = &mut self.cpu_metadata[prim_index.0];
|
||||
metadata.local_rect = pic.update_local_rect(result);
|
||||
|
||||
let new_local_rect = pic.update_local_rect(result);
|
||||
|
||||
if new_local_rect != metadata.local_rect {
|
||||
metadata.local_rect = new_local_rect;
|
||||
frame_state.gpu_cache.invalidate(&mut metadata.gpu_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2243,8 +2272,8 @@ impl<'a> GpuDataRequest<'a> {
|
||||
) {
|
||||
self.push(local_rect);
|
||||
self.push([
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0
|
||||
]);
|
||||
|
@ -142,6 +142,11 @@ impl RenderTaskTree {
|
||||
self.next_saved.0 += 1;
|
||||
id
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn frame_id(&self) -> FrameId {
|
||||
self.frame_id
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<RenderTaskId> for RenderTaskTree {
|
||||
|
@ -268,28 +268,26 @@ fn flag_changed(before: DebugFlags, after: DebugFlags, select: DebugFlags) -> Op
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum TextShaderMode {
|
||||
Alpha = 0,
|
||||
SubpixelConstantTextColor = 1,
|
||||
SubpixelPass0 = 2,
|
||||
SubpixelPass1 = 3,
|
||||
SubpixelWithBgColorPass0 = 4,
|
||||
SubpixelWithBgColorPass1 = 5,
|
||||
SubpixelWithBgColorPass2 = 6,
|
||||
SubpixelDualSource = 7,
|
||||
Bitmap = 8,
|
||||
ColorBitmap = 9,
|
||||
pub enum ShaderColorMode {
|
||||
Alpha = 1,
|
||||
SubpixelConstantTextColor = 2,
|
||||
SubpixelWithBgColorPass0 = 3,
|
||||
SubpixelWithBgColorPass1 = 4,
|
||||
SubpixelWithBgColorPass2 = 5,
|
||||
SubpixelDualSource = 6,
|
||||
Bitmap = 7,
|
||||
ColorBitmap = 8,
|
||||
}
|
||||
|
||||
impl From<GlyphFormat> for TextShaderMode {
|
||||
fn from(format: GlyphFormat) -> TextShaderMode {
|
||||
impl From<GlyphFormat> for ShaderColorMode {
|
||||
fn from(format: GlyphFormat) -> ShaderColorMode {
|
||||
match format {
|
||||
GlyphFormat::Alpha | GlyphFormat::TransformedAlpha => TextShaderMode::Alpha,
|
||||
GlyphFormat::Alpha | GlyphFormat::TransformedAlpha => ShaderColorMode::Alpha,
|
||||
GlyphFormat::Subpixel | GlyphFormat::TransformedSubpixel => {
|
||||
panic!("Subpixel glyph formats must be handled separately.");
|
||||
}
|
||||
GlyphFormat::Bitmap => TextShaderMode::Bitmap,
|
||||
GlyphFormat::ColorBitmap => TextShaderMode::ColorBitmap,
|
||||
GlyphFormat::Bitmap => ShaderColorMode::Bitmap,
|
||||
GlyphFormat::ColorBitmap => ShaderColorMode::ColorBitmap,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -839,7 +837,6 @@ impl SourceTextureResolver {
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[allow(dead_code)] // SubpixelVariableTextColor is not used at the moment.
|
||||
pub enum BlendMode {
|
||||
None,
|
||||
Alpha,
|
||||
@ -848,7 +845,6 @@ pub enum BlendMode {
|
||||
SubpixelDualSource,
|
||||
SubpixelConstantTextColor(ColorF),
|
||||
SubpixelWithBgColor,
|
||||
SubpixelVariableTextColor,
|
||||
}
|
||||
|
||||
// Tracks the state of each row in the GPU cache texture.
|
||||
@ -2912,7 +2908,7 @@ impl Renderer {
|
||||
BlendMode::Alpha => panic!("Attempt to composite non-premultiplied text primitives."),
|
||||
BlendMode::PremultipliedAlpha => {
|
||||
self.device.set_blend_mode_premultiplied_alpha();
|
||||
self.device.switch_mode(TextShaderMode::from(glyph_format) as _);
|
||||
self.device.switch_mode(ShaderColorMode::from(glyph_format) as _);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&batch.instances,
|
||||
@ -2923,7 +2919,7 @@ impl Renderer {
|
||||
}
|
||||
BlendMode::SubpixelDualSource => {
|
||||
self.device.set_blend_mode_subpixel_dual_source();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelDualSource as _);
|
||||
self.device.switch_mode(ShaderColorMode::SubpixelDualSource as _);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&batch.instances,
|
||||
@ -2934,7 +2930,7 @@ impl Renderer {
|
||||
}
|
||||
BlendMode::SubpixelConstantTextColor(color) => {
|
||||
self.device.set_blend_mode_subpixel_constant_text_color(color);
|
||||
self.device.switch_mode(TextShaderMode::SubpixelConstantTextColor as _);
|
||||
self.device.switch_mode(ShaderColorMode::SubpixelConstantTextColor as _);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&batch.instances,
|
||||
@ -2943,31 +2939,6 @@ impl Renderer {
|
||||
stats,
|
||||
);
|
||||
}
|
||||
BlendMode::SubpixelVariableTextColor => {
|
||||
// Using the two pass component alpha rendering technique:
|
||||
//
|
||||
// http://anholt.livejournal.com/32058.html
|
||||
//
|
||||
self.device.set_blend_mode_subpixel_pass0();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelPass0 as _);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&batch.instances,
|
||||
VertexArrayKind::Primitive,
|
||||
&batch.key.textures,
|
||||
stats,
|
||||
);
|
||||
|
||||
self.device.set_blend_mode_subpixel_pass1();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelPass1 as _);
|
||||
|
||||
// When drawing the 2nd pass, we know that the VAO, textures etc
|
||||
// are all set up from the previous draw_instanced_batch call,
|
||||
// so just issue a draw call here to avoid re-uploading the
|
||||
// instances and re-binding textures etc.
|
||||
self.device
|
||||
.draw_indexed_triangles_instanced_u16(6, batch.instances.len() as i32);
|
||||
}
|
||||
BlendMode::SubpixelWithBgColor => {
|
||||
// Using the three pass "component alpha with font smoothing
|
||||
// background color" rendering technique:
|
||||
@ -2975,7 +2946,7 @@ impl Renderer {
|
||||
// /webrender/doc/text-rendering.md
|
||||
//
|
||||
self.device.set_blend_mode_subpixel_with_bg_color_pass0();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelWithBgColorPass0 as _);
|
||||
self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass0 as _);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&batch.instances,
|
||||
@ -2985,7 +2956,7 @@ impl Renderer {
|
||||
);
|
||||
|
||||
self.device.set_blend_mode_subpixel_with_bg_color_pass1();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelWithBgColorPass1 as _);
|
||||
self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass1 as _);
|
||||
|
||||
// When drawing the 2nd and 3rd passes, we know that the VAO, textures etc
|
||||
// are all set up from the previous draw_instanced_batch call,
|
||||
@ -2995,7 +2966,7 @@ impl Renderer {
|
||||
.draw_indexed_triangles_instanced_u16(6, batch.instances.len() as i32);
|
||||
|
||||
self.device.set_blend_mode_subpixel_with_bg_color_pass2();
|
||||
self.device.switch_mode(TextShaderMode::SubpixelWithBgColorPass2 as _);
|
||||
self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass2 as _);
|
||||
|
||||
self.device
|
||||
.draw_indexed_triangles_instanced_u16(6, batch.instances.len() as i32);
|
||||
@ -3027,7 +2998,6 @@ impl Renderer {
|
||||
self.device.set_blend_mode_premultiplied_dest_out();
|
||||
}
|
||||
BlendMode::SubpixelConstantTextColor(..) |
|
||||
BlendMode::SubpixelVariableTextColor |
|
||||
BlendMode::SubpixelWithBgColor |
|
||||
BlendMode::SubpixelDualSource => {
|
||||
unreachable!("bug: subpx text handled earlier");
|
||||
|
@ -1105,6 +1105,10 @@ impl ResourceCache {
|
||||
.retain(|key, _| key.0 != namespace);
|
||||
self.cached_glyphs
|
||||
.clear_fonts(|font| font.font_key.0 == namespace);
|
||||
|
||||
if let Some(ref mut r) = self.blob_image_renderer {
|
||||
r.clear_namespace(namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,6 @@ impl BrushShader {
|
||||
BlendMode::PremultipliedDestOut |
|
||||
BlendMode::SubpixelDualSource |
|
||||
BlendMode::SubpixelConstantTextColor(..) |
|
||||
BlendMode::SubpixelVariableTextColor |
|
||||
BlendMode::SubpixelWithBgColor => &mut self.alpha,
|
||||
}
|
||||
}
|
||||
|
@ -452,6 +452,7 @@ pub struct StackingContext {
|
||||
pub mix_blend_mode: MixBlendMode,
|
||||
pub reference_frame_id: Option<ClipId>,
|
||||
pub clip_node_id: Option<ClipId>,
|
||||
pub glyph_raster_space: GlyphRasterSpace,
|
||||
} // IMPLICIT: filters: Vec<FilterOp>
|
||||
|
||||
#[repr(u32)]
|
||||
@ -468,6 +469,23 @@ pub enum TransformStyle {
|
||||
Preserve3D = 1,
|
||||
}
|
||||
|
||||
// TODO(gw): In the future, we may modify this to apply to all elements
|
||||
// within a stacking context, rather than just the glyphs. If
|
||||
// this change occurs, we'll update the naming of this.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[repr(C, u8)]
|
||||
pub enum GlyphRasterSpace {
|
||||
// Rasterize glyphs in local-space, applying supplied scale to glyph sizes.
|
||||
// Best performance, but lower quality.
|
||||
Local(f32),
|
||||
|
||||
// Rasterize the glyphs in screen-space, including rotation / skew etc in
|
||||
// the rasterized glyph. Best quality, but slower performance. Note that
|
||||
// any stacking context with a perspective transform will be rasterized
|
||||
// in local-space, even if this is set.
|
||||
Screen,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum MixBlendMode {
|
||||
|
@ -16,7 +16,7 @@ use time::precise_time_ns;
|
||||
use {AlphaType, BorderDetails, BorderDisplayItem, BorderRadius, BorderWidths, BoxShadowClipMode};
|
||||
use {BoxShadowDisplayItem, ClipAndScrollInfo, ClipChainId, ClipChainItem, ClipDisplayItem, ClipId};
|
||||
use {ColorF, ComplexClipRegion, DisplayItem, ExtendMode, ExternalScrollId, FilterOp};
|
||||
use {FontInstanceKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, GradientStop};
|
||||
use {FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, Gradient, GradientDisplayItem, GradientStop};
|
||||
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo};
|
||||
use {LayoutPoint, LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
|
||||
use {LineDisplayItem, LineOrientation, LineStyle, MixBlendMode, PipelineId, PropertyBinding};
|
||||
@ -1276,6 +1276,7 @@ impl DisplayListBuilder {
|
||||
perspective: Option<LayoutTransform>,
|
||||
mix_blend_mode: MixBlendMode,
|
||||
filters: Vec<FilterOp>,
|
||||
glyph_raster_space: GlyphRasterSpace,
|
||||
) {
|
||||
let reference_frame_id = if transform.is_some() || perspective.is_some() {
|
||||
Some(self.generate_clip_id())
|
||||
@ -1292,6 +1293,7 @@ impl DisplayListBuilder {
|
||||
mix_blend_mode,
|
||||
reference_frame_id,
|
||||
clip_node_id,
|
||||
glyph_raster_space,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -191,6 +191,8 @@ pub trait BlobImageRenderer: Send {
|
||||
fn delete_font(&mut self, key: FontKey);
|
||||
|
||||
fn delete_font_instance(&mut self, key: FontInstanceKey);
|
||||
|
||||
fn clear_namespace(&mut self, namespace: IdNamespace);
|
||||
}
|
||||
|
||||
pub type BlobImageData = Vec<u8>;
|
||||
|
@ -1 +1 @@
|
||||
5bcb7f46c6931633fd20813c46cd69af164effe7
|
||||
ad06d8e05e8475c9788cffa7e6cbac70acbdb399
|
||||
|
@ -164,4 +164,6 @@ impl BlobImageRenderer for CheckerboardRenderer {
|
||||
fn delete_font(&mut self, _key: FontKey) {}
|
||||
|
||||
fn delete_font_instance(&mut self, _key: FontInstanceKey) {}
|
||||
|
||||
fn clear_namespace(&mut self, _namespace: IdNamespace) {}
|
||||
}
|
||||
|
@ -1534,6 +1534,9 @@ impl YamlFrameReader {
|
||||
let scroll_policy = yaml["scroll-policy"]
|
||||
.as_scroll_policy()
|
||||
.unwrap_or(ScrollPolicy::Scrollable);
|
||||
let glyph_raster_space = yaml["glyph-raster-space"]
|
||||
.as_glyph_raster_space()
|
||||
.unwrap_or(GlyphRasterSpace::Screen);
|
||||
|
||||
if is_root {
|
||||
if let Some(size) = yaml["scroll-offset"].as_point() {
|
||||
@ -1555,6 +1558,7 @@ impl YamlFrameReader {
|
||||
perspective,
|
||||
mix_blend_mode,
|
||||
filters,
|
||||
glyph_raster_space,
|
||||
);
|
||||
|
||||
if !yaml["items"].is_badvalue() {
|
||||
|
@ -191,6 +191,16 @@ fn write_stacking_context(
|
||||
|
||||
enum_node(parent, "transform-style", sc.transform_style);
|
||||
|
||||
let glyph_raster_space = match sc.glyph_raster_space {
|
||||
GlyphRasterSpace::Local(scale) => {
|
||||
format!("local({})", scale)
|
||||
}
|
||||
GlyphRasterSpace::Screen => {
|
||||
"screen".to_owned()
|
||||
}
|
||||
};
|
||||
str_node(parent, "glyph-raster-space", &glyph_raster_space);
|
||||
|
||||
if let Some(clip_node_id) = sc.clip_node_id {
|
||||
yaml_node(parent, "clip-node", Yaml::Integer(clip_id_mapper.map_id(&clip_node_id) as i64));
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ pub trait YamlHelper {
|
||||
fn as_border_radius_component(&self) -> LayoutSize;
|
||||
fn as_border_radius(&self) -> Option<BorderRadius>;
|
||||
fn as_transform_style(&self) -> Option<TransformStyle>;
|
||||
fn as_glyph_raster_space(&self) -> Option<GlyphRasterSpace>;
|
||||
fn as_clip_mode(&self) -> Option<ClipMode>;
|
||||
fn as_mix_blend_mode(&self) -> Option<MixBlendMode>;
|
||||
fn as_scroll_policy(&self) -> Option<ScrollPolicy>;
|
||||
@ -519,6 +520,22 @@ impl YamlHelper for Yaml {
|
||||
self.as_str().and_then(|x| StringEnum::from_str(x))
|
||||
}
|
||||
|
||||
fn as_glyph_raster_space(&self) -> Option<GlyphRasterSpace> {
|
||||
self.as_str().and_then(|s| {
|
||||
match parse_function(s) {
|
||||
("screen", _, _) => {
|
||||
Some(GlyphRasterSpace::Screen)
|
||||
}
|
||||
("local", ref args, _) if args.len() == 1 => {
|
||||
Some(GlyphRasterSpace::Local(args[0].parse().unwrap()))
|
||||
}
|
||||
f => {
|
||||
panic!("error parsing glyph raster space {:?}", f);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn as_mix_blend_mode(&self) -> Option<MixBlendMode> {
|
||||
self.as_str().and_then(|x| StringEnum::from_str(x))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user