Skip to content

Sync changes from mozilla-central #3507

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions webrender/res/ps_text_run.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ TextRun fetch_text_run(int address) {

VertexInfo write_text_vertex(RectWithSize local_clip_rect,
float z,
bool should_snap,
Transform transform,
PictureTask task,
vec2 text_offset,
Expand All @@ -74,8 +73,13 @@ VertexInfo write_text_vertex(RectWithSize local_clip_rect,
vec2 snap_offset = vec2(0.0);
mat2 local_transform;

#ifdef WR_FEATURE_GLYPH_TRANSFORM
bool remove_subpx_offset = true;
#else
bool remove_subpx_offset = transform.is_axis_aligned;
#endif
// Compute the snapping offset only if the scroll node transform is axis-aligned.
if (should_snap) {
if (remove_subpx_offset) {
// Transform from local space to device space.
float device_scale = task.common_data.device_pixel_scale / transform.m[3].w;
mat2 device_transform = mat2(transform.m) * device_scale;
Expand Down Expand Up @@ -174,18 +178,13 @@ void main(void) {
RectWithSize glyph_rect = RectWithSize(res.offset + glyph_transform * (text.offset + glyph.offset),
res.uv_rect.zw - res.uv_rect.xy);

// Since the glyph is pre-transformed, snapping is both forced and does not depend on the transform.
bool should_snap = true;
#else
// Scale from glyph space to local space.
float scale = res.scale / task.common_data.device_pixel_scale;

// Compute the glyph rect in local space.
RectWithSize glyph_rect = RectWithSize(scale * res.offset + text.offset + glyph.offset,
scale * (res.uv_rect.zw - res.uv_rect.xy));

// Check if the primitive is actually safe to snap.
bool should_snap = ph.user_data.x != 0;
#endif

vec2 snap_bias;
Expand Down Expand Up @@ -215,7 +214,6 @@ void main(void) {

VertexInfo vi = write_text_vertex(ph.local_clip_rect,
ph.z,
should_snap,
transform,
task,
text.offset,
Expand Down
77 changes: 40 additions & 37 deletions webrender/src/batch.rs

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions webrender/src/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,21 @@ pub struct ClipChainInstance {
pub pic_clip_rect: PictureRect,
}

impl ClipChainInstance {
pub fn empty() -> Self {
ClipChainInstance {
clips_range: ClipNodeRange {
first: 0,
count: 0,
},
local_clip_rect: LayoutRect::zero(),
has_non_local_clips: false,
needs_mask: false,
pic_clip_rect: PictureRect::zero(),
}
}
}

impl ClipStore {
pub fn new() -> Self {
ClipStore {
Expand Down
49 changes: 48 additions & 1 deletion webrender/src/frame_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ pub struct FrameBuilder {
pub config: FrameBuilderConfig,
}

pub struct FrameVisibilityContext<'a> {
pub clip_scroll_tree: &'a ClipScrollTree,
pub screen_world_rect: WorldRect,
pub device_pixel_scale: DevicePixelScale,
pub surfaces: &'a [SurfaceInfo],
}

pub struct FrameVisibilityState<'a> {
pub clip_store: &'a mut ClipStore,
pub resource_cache: &'a mut ResourceCache,
pub gpu_cache: &'a mut GpuCache,
pub scratch: &'a mut PrimitiveScratchBuffer,
}

pub struct FrameBuildingContext<'a> {
pub device_pixel_scale: DevicePixelScale,
pub scene_properties: &'a SceneProperties,
Expand Down Expand Up @@ -198,6 +212,16 @@ impl FrameBuilder {
self.prim_store.destroy(
retained_tiles,
);

// In general, the pending retained tiles are consumed by the frame
// builder the first time a frame is built after a new scene has
// arrived. However, if two scenes arrive in quick succession, the
// frame builder may not have had a chance to build a frame and
// consume the pending tiles. In this case, the pending tiles will
// be lost, causing a full invalidation of the entire screen. To
// avoid this, if there are still pending tiles, include them in
// the retained tiles passed to the next frame builder.
retained_tiles.tiles.extend(self.pending_retained_tiles.tiles);
}

/// Compute the contribution (bounding rectangles, and resources) of layers and their
Expand Down Expand Up @@ -295,6 +319,30 @@ impl FrameBuilder {
scratch,
);

{
let visibility_context = FrameVisibilityContext {
device_pixel_scale,
clip_scroll_tree,
screen_world_rect,
surfaces: pic_update_state.surfaces,
};

let mut visibility_state = FrameVisibilityState {
resource_cache,
gpu_cache,
clip_store: &mut self.clip_store,
scratch,
};

self.prim_store.update_visibility(
self.root_pic_index,
ROOT_SURFACE_INDEX,
&visibility_context,
&mut visibility_state,
resources,
);
}

let mut frame_state = FrameBuildingState {
render_tasks,
profile_counters,
Expand Down Expand Up @@ -336,7 +384,6 @@ impl FrameBuilder {
prim_list,
pic_context,
pic_state,
&mut frame_state,
);

let child_tasks = frame_state
Expand Down
33 changes: 17 additions & 16 deletions webrender/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,33 @@ but it can also be used as such in a standalone application.
WebRender currently depends on [FreeType](https://www.freetype.org/)

# Api Structure
The main entry point to WebRender is the `webrender::Renderer`.
The main entry point to WebRender is the [`crate::Renderer`].

By calling `Renderer::new(...)` you get a `Renderer`, as well as a `RenderApiSender`.
Your `Renderer` is responsible to render the previously processed frames onto the screen.
By calling [`Renderer::new(...)`](crate::Renderer::new) you get a [`Renderer`], as well as
a [`RenderApiSender`](api::RenderApiSender). Your [`Renderer`] is responsible to render the
previously processed frames onto the screen.

By calling `yourRenderApiSender.create_api()`, you'll get a `RenderApi` instance,
which is responsible for managing resources and documents. A worker thread is used internally
to untie the workload from the application thread and therefore be able to make better use of
multicore systems.
By calling [`yourRenderApiSender.create_api()`](api::RenderApiSender::create_api), you'll
get a [`RenderApi`](api::RenderApi) instance, which is responsible for managing resources
and documents. A worker thread is used internally to untie the workload from the application
thread and therefore be able to make better use of multicore systems.

## Frame

What is referred to as a `frame`, is the current geometry on the screen.
A new Frame is created by calling [`set_display_list()`][newframe] on the `RenderApi`.
When the geometry is processed, the application will be informed via a `RenderNotifier`,
a callback which you employ with [set_render_notifier][notifier] on the `Renderer`
A new Frame is created by calling [`set_display_list()`](api::Transaction::set_display_list)
on the [`RenderApi`](api::RenderApi). When the geometry is processed, the application will be
informed via a [`RenderNotifier`](api::RenderNotifier), a callback which you pass to
[`Renderer::new`].
More information about [stacking contexts][stacking_contexts].

`set_display_list()` also needs to be supplied with `BuiltDisplayList`s.
These are obtained by finalizing a `DisplayListBuilder`. These are used to draw your geometry.
But it doesn't only contain trivial geometry, it can also store another StackingContext, as
they're nestable.
[`set_display_list()`](api::Transaction::set_display_list) also needs to be supplied with
[`BuiltDisplayList`](api::BuiltDisplayList)s. These are obtained by finalizing a
[`DisplayListBuilder`](api::DisplayListBuilder). These are used to draw your geometry. But it
doesn't only contain trivial geometry, it can also store another
[`StackingContext`](api::StackingContext), as they're nestable.

[stacking_contexts]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
[newframe]: ../webrender_api/struct.RenderApi.html#method.set_display_list
[notifier]: renderer/struct.Renderer.html#method.set_render_notifier
*/

// Cribbed from the |matches| crate, for simplicity.
Expand Down
Loading