Skip to content

Pass device pixel scale via picture render task data. #3150

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 3 commits into from
Oct 3, 2018
Merged
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
18 changes: 2 additions & 16 deletions webrender/res/brush_image.glsl
Original file line number Diff line number Diff line change
@@ -42,20 +42,6 @@ ImageBrushData fetch_image_data(int address) {
return data;
}

#ifdef WR_FEATURE_ALPHA_PASS
vec2 transform_point_snapped(
vec2 local_pos,
RectWithSize local_rect,
mat4 transform
) {
vec2 snap_offset = compute_snap_offset(local_pos, transform, local_rect);
vec4 world_pos = transform * vec4(local_pos, 0.0, 1.0);
vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;

return device_pos + snap_offset;
}
#endif

void brush_vs(
VertexInfo vi,
int prim_address,
@@ -95,10 +81,10 @@ void brush_vs(
// works. That assumption may not hold if this
// is used for other purposes in the future.
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) {
stretch_size.x = (texel_rect.z - texel_rect.x) / uDevicePixelRatio;
stretch_size.x = (texel_rect.z - texel_rect.x) / pic_task.common_data.device_pixel_scale;
}
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) {
stretch_size.y = (texel_rect.w - texel_rect.y) / uDevicePixelRatio;
stretch_size.y = (texel_rect.w - texel_rect.y) / pic_task.common_data.device_pixel_scale;
}

uv0 = res.uv_rect.p0 + texel_rect.xy;
7 changes: 6 additions & 1 deletion webrender/res/brush_mix_blend.glsl
Original file line number Diff line number Diff line change
@@ -12,6 +12,11 @@ flat varying int vOp;

#ifdef WR_VERTEX_SHADER

//Note: this function is unsafe for `vi.world_pos.w <= 0.0`
vec2 snap_device_pos(VertexInfo vi, float device_pixel_scale) {
return vi.world_pos.xy * device_pixel_scale / max(0.0, vi.world_pos.w) + vi.snap_offset;
}

void brush_vs(
VertexInfo vi,
int prim_address,
@@ -23,7 +28,7 @@ void brush_vs(
int brush_flags,
vec4 unused
) {
vec2 snapped_device_pos = snap_device_pos(vi);
vec2 snapped_device_pos = snap_device_pos(vi, pic_task.common_data.device_pixel_scale);
vec2 texture_size = vec2(textureSize(sPrevPassColor, 0));
vOp = user_data.x;

5 changes: 3 additions & 2 deletions webrender/res/clip_shared.glsl
Original file line number Diff line number Diff line change
@@ -63,7 +63,8 @@ ClipVertexInfo write_clip_tile_vertex(RectWithSize local_clip_rect,
mat4 snap_mat = clip_transform.m * prim_transform.inv_m;
vec4 snap_positions = compute_snap_positions(
snap_mat,
local_clip_rect
local_clip_rect,
area.common_data.device_pixel_scale
);

vec2 snap_offsets = compute_snap_offset_impl(
@@ -77,7 +78,7 @@ ClipVertexInfo write_clip_tile_vertex(RectWithSize local_clip_rect,
device_pos -= snap_offsets;
}

vec2 world_pos = device_pos / uDevicePixelRatio;
vec2 world_pos = device_pos / area.common_data.device_pixel_scale;

vec4 pos = prim_transform.m * vec4(world_pos, 0.0, 1.0);
pos.xyz /= pos.w;
2 changes: 1 addition & 1 deletion webrender/res/cs_blur.glsl
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ BlurTask fetch_blur_task(int address) {

BlurTask task = BlurTask(
task_data.common_data,
task_data.data1.x
task_data.user_data.x
);

return task;
2 changes: 1 addition & 1 deletion webrender/res/debug_color.glsl
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ in vec4 aColor;
void main(void) {
vColor = vec4(aColor.rgb * aColor.a, aColor.a);
vec4 pos = vec4(aPosition, 1.0);
pos.xy = floor(pos.xy * uDevicePixelRatio + 0.5) / uDevicePixelRatio;
pos.xy = floor(pos.xy + 0.5);
gl_Position = uTransform * pos;
}
#endif
2 changes: 1 addition & 1 deletion webrender/res/debug_font.glsl
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ void main(void) {
vColor = aColor;
vColorTexCoord = aColorTexCoord;
vec4 pos = vec4(aPosition, 1.0);
pos.xy = floor(pos.xy * uDevicePixelRatio + 0.5) / uDevicePixelRatio;
pos.xy = floor(pos.xy + 0.5);
gl_Position = uTransform * pos;
}
#endif
14 changes: 5 additions & 9 deletions webrender/res/prim_shared.glsl
Original file line number Diff line number Diff line change
@@ -89,11 +89,6 @@ struct VertexInfo {
vec4 world_pos;
};

//Note: this function is unsafe for `vi.world_pos.w <= 0.0`
vec2 snap_device_pos(VertexInfo vi) {
return vi.world_pos.xy * uDevicePixelRatio / max(0.0, vi.world_pos.w) + vi.snap_offset;
}

VertexInfo write_vertex(RectWithSize instance_rect,
RectWithSize local_clip_rect,
float z,
@@ -111,14 +106,15 @@ VertexInfo write_vertex(RectWithSize instance_rect,
vec2 snap_offset = compute_snap_offset(
clamped_local_pos,
transform.m,
snap_rect
snap_rect,
task.common_data.device_pixel_scale
);

// Transform the current vertex to world space.
vec4 world_pos = transform.m * vec4(clamped_local_pos, 0.0, 1.0);

// Convert the world positions to device pixel space.
vec2 device_pos = world_pos.xy * uDevicePixelRatio;
vec2 device_pos = world_pos.xy * task.common_data.device_pixel_scale;

// Apply offsets for the render task to get correct screen location.
vec2 final_offset = snap_offset - task.content_origin + task.common_data.task_rect.p0;
@@ -195,7 +191,7 @@ VertexInfo write_transform_vertex(RectWithSize local_segment_rect,
// Transform the current vertex to the world cpace.
vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);
vec4 final_pos = vec4(
world_pos.xy * uDevicePixelRatio + task_offset * world_pos.w,
world_pos.xy * task.common_data.device_pixel_scale + task_offset * world_pos.w,
z * world_pos.w,
world_pos.w
);
@@ -218,7 +214,7 @@ VertexInfo write_transform_vertex(RectWithSize local_segment_rect,
}

void write_clip(vec4 world_pos, vec2 snap_offset, ClipArea area) {
vec2 uv = world_pos.xy * uDevicePixelRatio +
vec2 uv = world_pos.xy * area.common_data.device_pixel_scale +
world_pos.w * (snap_offset + area.common_data.task_rect.p0 - area.screen_origin);
vClipMaskUvBounds = vec4(
area.common_data.task_rect.p0,
2 changes: 1 addition & 1 deletion webrender/res/ps_split_composite.glsl
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ void main(void) {
vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);

vec4 final_pos = vec4(
dest_origin * world_pos.w + world_pos.xy * uDevicePixelRatio,
dest_origin * world_pos.w + world_pos.xy * dest_task.common_data.device_pixel_scale,
world_pos.w * ci.z,
world_pos.w
);
8 changes: 4 additions & 4 deletions webrender/res/ps_text_run.glsl
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ VertexInfo write_text_vertex(RectWithSize local_clip_rect,
// Compute the snapping offset only if the scroll node transform is axis-aligned.
if (remove_subpx_offset) {
// Transform from local space to device space.
float device_scale = uDevicePixelRatio / transform.m[3].w;
float device_scale = task.common_data.device_pixel_scale / transform.m[3].w;
mat2 device_transform = mat2(transform.m) * device_scale;

// Ensure the transformed text offset does not contain a subpixel translation
@@ -130,7 +130,7 @@ VertexInfo write_text_vertex(RectWithSize local_clip_rect,

// Map the clamped local space corner into device space.
vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);
vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;
vec2 device_pos = world_pos.xy / world_pos.w * task.common_data.device_pixel_scale;

// Apply offsets for the render task to get correct screen location.
vec2 final_pos = device_pos -
@@ -172,15 +172,15 @@ void main(void) {

#ifdef WR_FEATURE_GLYPH_TRANSFORM
// Transform from local space to glyph space.
mat2 glyph_transform = mat2(transform.m) * uDevicePixelRatio;
mat2 glyph_transform = mat2(transform.m) * task.common_data.device_pixel_scale;

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

#else
// Scale from glyph space to local space.
float scale = res.scale / uDevicePixelRatio;
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,
20 changes: 10 additions & 10 deletions webrender/res/render_task.glsl
Original file line number Diff line number Diff line change
@@ -11,11 +11,12 @@ uniform HIGHP_SAMPLER_FLOAT sampler2D sRenderTasks;
struct RenderTaskCommonData {
RectWithSize task_rect;
float texture_layer_index;
float device_pixel_scale;
};

struct RenderTaskData {
RenderTaskCommonData common_data;
vec3 data1;
vec2 user_data;
};

RenderTaskData fetch_render_task_data(int index) {
@@ -31,12 +32,13 @@ RenderTaskData fetch_render_task_data(int index) {

RenderTaskCommonData common_data = RenderTaskCommonData(
task_rect,
texel1.x
texel1.x,
texel1.y
);

RenderTaskData data = RenderTaskData(
common_data,
texel1.yzw
texel1.zw
);

return data;
@@ -55,7 +57,8 @@ RenderTaskCommonData fetch_render_task_common_data(int index) {

RenderTaskCommonData data = RenderTaskCommonData(
task_rect,
texel1.x
texel1.x,
texel1.y
);

return data;
@@ -79,7 +82,7 @@ PictureTask fetch_picture_task(int address) {

PictureTask task = PictureTask(
task_data.common_data,
task_data.data1.xy
task_data.user_data
);

return task;
@@ -90,7 +93,6 @@ PictureTask fetch_picture_task(int address) {
struct ClipArea {
RenderTaskCommonData common_data;
vec2 screen_origin;
bool local_space;
};

ClipArea fetch_clip_area(int index) {
@@ -99,15 +101,13 @@ ClipArea fetch_clip_area(int index) {
if (index >= CLIP_TASK_EMPTY) {
RectWithSize rect = RectWithSize(vec2(0.0), vec2(0.0));

area.common_data = RenderTaskCommonData(rect, 0.0);
area.common_data = RenderTaskCommonData(rect, 0.0, 1.0);
area.screen_origin = vec2(0.0);
area.local_space = false;
} else {
RenderTaskData task_data = fetch_render_task_data(index);

area.common_data = task_data.common_data;
area.screen_origin = task_data.data1.xy;
area.local_space = task_data.data1.z == 0.0;
area.screen_origin = task_data.user_data;
}

return area;
1 change: 0 additions & 1 deletion webrender/res/shared.glsl
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@

// Uniform inputs
uniform mat4 uTransform; // Orthographic projection
uniform float uDevicePixelRatio;

// Attribute inputs
in vec3 aPosition;
18 changes: 12 additions & 6 deletions webrender/res/snap.glsl
Original file line number Diff line number Diff line change
@@ -4,21 +4,25 @@

#ifdef WR_VERTEX_SHADER

vec4 compute_snap_positions(mat4 transform, RectWithSize snap_rect) {
vec4 compute_snap_positions(
mat4 transform,
RectWithSize snap_rect,
float device_pixel_scale
) {
// Ensure that the snap rect is at *least* one device pixel in size.
// TODO(gw): It's not clear to me that this is "correct". Specifically,
// how should it interact with sub-pixel snap rects when there
// is a transform with scale present? But it does fix
// the test cases we have in Servo that are failing without it
// and seem better than not having this at all.
snap_rect.size = max(snap_rect.size, vec2(1.0 / uDevicePixelRatio));
snap_rect.size = max(snap_rect.size, vec2(1.0 / device_pixel_scale));

// Transform the snap corners to the world space.
vec4 world_snap_p0 = transform * vec4(snap_rect.p0, 0.0, 1.0);
vec4 world_snap_p1 = transform * vec4(snap_rect.p0 + snap_rect.size, 0.0, 1.0);
// Snap bounds in world coordinates, adjusted for pixel ratio. XY = top left, ZW = bottom right
vec4 world_snap = uDevicePixelRatio * vec4(world_snap_p0.xy, world_snap_p1.xy) /
vec4(world_snap_p0.ww, world_snap_p1.ww);
vec4 world_snap = device_pixel_scale * vec4(world_snap_p0.xy, world_snap_p1.xy) /
vec4(world_snap_p0.ww, world_snap_p1.ww);
return world_snap;
}

@@ -43,10 +47,12 @@ vec2 compute_snap_offset_impl(
// given local position on the transform and a snap rectangle.
vec2 compute_snap_offset(vec2 local_pos,
mat4 transform,
RectWithSize snap_rect) {
RectWithSize snap_rect,
float device_pixel_scale) {
vec4 snap_positions = compute_snap_positions(
transform,
snap_rect
snap_rect,
device_pixel_scale
);

vec2 snap_offsets = compute_snap_offset_impl(
5 changes: 0 additions & 5 deletions webrender/src/device/gl.rs
Original file line number Diff line number Diff line change
@@ -529,7 +529,6 @@ impl Drop for Texture {
pub struct Program {
id: gl::GLuint,
u_transform: gl::GLint,
u_device_pixel_ratio: gl::GLint,
u_mode: gl::GLint,
}

@@ -1559,13 +1558,11 @@ impl Device {
}

let u_transform = self.gl.get_uniform_location(pid, "uTransform");
let u_device_pixel_ratio = self.gl.get_uniform_location(pid, "uDevicePixelRatio");
let u_mode = self.gl.get_uniform_location(pid, "uMode");

let program = Program {
id: pid,
u_transform,
u_device_pixel_ratio,
u_mode,
};

@@ -1601,8 +1598,6 @@ impl Device {
debug_assert!(self.inside_frame);
self.gl
.uniform_matrix_4fv(program.u_transform, false, &transform.to_row_major_array());
self.gl
.uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio);
}

pub fn switch_mode(&self, mode: i32) {
2 changes: 1 addition & 1 deletion webrender/src/frame_builder.rs
Original file line number Diff line number Diff line change
@@ -399,7 +399,7 @@ impl FrameBuilder {

let gpu_cache_frame_id = gpu_cache.end_frame(gpu_cache_profile);

render_tasks.write_task_data();
render_tasks.write_task_data(device_pixel_scale);

resource_cache.end_frame();

28 changes: 10 additions & 18 deletions webrender/src/render_task.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@
* 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/. */

use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceSize, DeviceIntSideOffsets, ImageDescriptor, ImageFormat};
use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceSize, DeviceIntSideOffsets};
use api::{DevicePixelScale, ImageDescriptor, ImageFormat};
#[cfg(feature = "pathfinder")]
use api::FontRenderMode;
use border::BorderCacheKey;
@@ -15,7 +16,7 @@ use euclid::{TypedPoint2D, TypedVector2D};
use freelist::{FreeList, FreeListHandle, WeakFreeListHandle};
use glyph_rasterizer::GpuGlyphCacheKey;
use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
use gpu_types::{BorderInstance, ImageSource, RasterizationSpace, UvRectKind};
use gpu_types::{BorderInstance, ImageSource, UvRectKind};
use internal_types::{CacheTextureId, FastHashMap, SavedTargetIndex};
#[cfg(feature = "pathfinder")]
use pathfinder_partitioner::mesh::Mesh;
@@ -131,9 +132,9 @@ impl RenderTaskTree {
RenderTaskAddress(id.0)
}

pub fn write_task_data(&mut self) {
pub fn write_task_data(&mut self, device_pixel_scale: DevicePixelScale) {
for task in &self.tasks {
self.task_data.push(task.write_task_data());
self.task_data.push(task.write_task_data(device_pixel_scale));
}
}

@@ -709,7 +710,7 @@ impl RenderTask {
// Write (up to) 8 floats of data specific to the type
// of render task that is provided to the GPU shaders
// via a vertex texture.
pub fn write_task_data(&self) -> RenderTaskData {
pub fn write_task_data(&self, device_pixel_scale: DevicePixelScale) -> RenderTaskData {
// NOTE: The ordering and layout of these structures are
// required to match both the GPU structures declared
// in prim_shared.glsl, and also the uses in submit_batch()
@@ -724,39 +725,30 @@ impl RenderTask {
[
task.content_origin.x as f32,
task.content_origin.y as f32,
0.0,
]
}
RenderTaskKind::CacheMask(ref task) => {
[
task.actual_rect.origin.x as f32,
task.actual_rect.origin.y as f32,
RasterizationSpace::Screen as i32 as f32,
]
}
RenderTaskKind::ClipRegion(..) => {
[
0.0,
0.0,
RasterizationSpace::Local as i32 as f32,
]
}
RenderTaskKind::VerticalBlur(ref task) |
RenderTaskKind::HorizontalBlur(ref task) => {
[
task.blur_std_deviation,
0.0,
0.0,
]
}
RenderTaskKind::Glyph(_) => {
[1.0, 0.0, 0.0]
[1.0, 0.0]
}
RenderTaskKind::ClipRegion(..) |
RenderTaskKind::Readback(..) |
RenderTaskKind::Scaling(..) |
RenderTaskKind::Border(..) |
RenderTaskKind::Blit(..) => {
[0.0; 3]
[0.0; 2]
}
};

@@ -775,9 +767,9 @@ impl RenderTask {
target_rect.size.width as f32,
target_rect.size.height as f32,
target_index.0 as f32,
device_pixel_scale.0,
data[0],
data[1],
data[2],
]
}
}