Bug 1454623 - Update webrender to ad06d8e05e8475c9788cffa7e6cbac70acbdb399. r=jrmuizel

MozReview-Commit-ID: JFDiNyCo0W

--HG--
extra : rebase_source : 99b90deb5643cc5e15cd7fbd2867943c3631edeb
This commit is contained in:
Kartikaya Gupta 2018-04-23 09:38:09 -04:00
parent eaf147ebce
commit 1abb19edf6
39 changed files with 404 additions and 188 deletions

View File

@ -40,6 +40,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
for _ in 0 .. self.rect_count {

View File

@ -56,6 +56,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
filters,
GlyphRasterSpace::Screen,
);
let complex_clip = ComplexClipRegion {

View File

@ -198,6 +198,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
let image_mask_key = api.generate_image_key();

View File

@ -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));

View File

@ -119,6 +119,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
builder.push_rect(
&LayoutPrimitiveInfo::new(local_rect),

View File

@ -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(

View File

@ -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));

View File

@ -47,6 +47,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
let image_size = LayoutSize::new(100.0, 100.0);

View File

@ -187,6 +187,7 @@ impl Window {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
let info = LayoutPrimitiveInfo::new(LayoutRect::new(

View File

@ -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(

View File

@ -99,6 +99,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
let x0 = 50.0;

View File

@ -94,6 +94,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
let yuv_chanel1 = api.generate_image_key();

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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,
],

View File

@ -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,

View File

@ -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();
}
}
}

View File

@ -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());
}
}
}

View File

@ -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
]);

View File

@ -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 {

View File

@ -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");

View File

@ -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);
}
}
}

View File

@ -220,7 +220,6 @@ impl BrushShader {
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelDualSource |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelVariableTextColor |
BlendMode::SubpixelWithBgColor => &mut self.alpha,
}
}

View File

@ -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 {

View File

@ -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,
},
});

View File

@ -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>;

View File

@ -1 +1 @@
5bcb7f46c6931633fd20813c46cd69af164effe7
ad06d8e05e8475c9788cffa7e6cbac70acbdb399

View File

@ -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) {}
}

View File

@ -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() {

View File

@ -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));
}

View File

@ -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))
}