Skip to content
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

Port intermediate blits to brush_image, remove another ps_hw_composite case. #2510

Merged
merged 3 commits into from Mar 14, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -35,32 +35,33 @@ void brush_vs(
vec2 uv1 = uv0 + src_task.common_data.task_rect.size;
vUvClipBounds = vec4(uv0, uv1) / texture_size.xyxy;

vOp = user_data.y;

float lumR = 0.2126;
float lumG = 0.7152;
float lumB = 0.0722;
float oneMinusLumR = 1.0 - lumR;
float oneMinusLumG = 1.0 - lumG;
float oneMinusLumB = 1.0 - lumB;

vec4 amount = fetch_from_resource_cache_1(prim_address);
vAmount = amount.x;
float amount = float(user_data.z) / 65536.0;
float invAmount = 1.0 - amount;

vOp = user_data.y;
vAmount = amount;

switch (vOp) {
case 2: {
// Grayscale
vColorMat = mat4(vec4(lumR + oneMinusLumR * amount.y, lumR - lumR * amount.y, lumR - lumR * amount.y, 0.0),
vec4(lumG - lumG * amount.y, lumG + oneMinusLumG * amount.y, lumG - lumG * amount.y, 0.0),
vec4(lumB - lumB * amount.y, lumB - lumB * amount.y, lumB + oneMinusLumB * amount.y, 0.0),
vColorMat = mat4(vec4(lumR + oneMinusLumR * invAmount, lumR - lumR * invAmount, lumR - lumR * invAmount, 0.0),
vec4(lumG - lumG * invAmount, lumG + oneMinusLumG * invAmount, lumG - lumG * invAmount, 0.0),
vec4(lumB - lumB * invAmount, lumB - lumB * invAmount, lumB + oneMinusLumB * invAmount, 0.0),
vec4(0.0, 0.0, 0.0, 1.0));
vColorOffset = vec4(0.0);
break;
}
case 3: {
// HueRotate
float c = cos(amount.x);
float s = sin(amount.x);
float c = cos(amount);
float s = sin(amount);
vColorMat = mat4(vec4(lumR + oneMinusLumR * c - lumR * s, lumR - lumR * c + 0.143 * s, lumR - lumR * c - oneMinusLumR * s, 0.0),
vec4(lumG - lumG * c - lumG * s, lumG + oneMinusLumG * c + 0.140 * s, lumG - lumG * c + lumG * s, 0.0),
vec4(lumB - lumB * c + oneMinusLumB * s, lumB - lumB * c - 0.283 * s, lumB + oneMinusLumB * c + lumB * s, 0.0),
@@ -70,18 +71,18 @@ void brush_vs(
}
case 5: {
// Saturate
vColorMat = mat4(vec4(amount.y * lumR + amount.x, amount.y * lumR, amount.y * lumR, 0.0),
vec4(amount.y * lumG, amount.y * lumG + amount.x, amount.y * lumG, 0.0),
vec4(amount.y * lumB, amount.y * lumB, amount.y * lumB + amount.x, 0.0),
vColorMat = mat4(vec4(invAmount * lumR + amount, invAmount * lumR, invAmount * lumR, 0.0),
vec4(invAmount * lumG, invAmount * lumG + amount, invAmount * lumG, 0.0),
vec4(invAmount * lumB, invAmount * lumB, invAmount * lumB + amount, 0.0),
vec4(0.0, 0.0, 0.0, 1.0));
vColorOffset = vec4(0.0);
break;
}
case 6: {
// Sepia
vColorMat = mat4(vec4(0.393 + 0.607 * amount.y, 0.349 - 0.349 * amount.y, 0.272 - 0.272 * amount.y, 0.0),
vec4(0.769 - 0.769 * amount.y, 0.686 + 0.314 * amount.y, 0.534 - 0.534 * amount.y, 0.0),
vec4(0.189 - 0.189 * amount.y, 0.168 - 0.168 * amount.y, 0.131 + 0.869 * amount.y, 0.0),
vColorMat = mat4(vec4(0.393 + 0.607 * invAmount, 0.349 - 0.349 * invAmount, 0.272 - 0.272 * invAmount, 0.0),
vec4(0.769 - 0.769 * invAmount, 0.686 + 0.314 * invAmount, 0.534 - 0.534 * invAmount, 0.0),
vec4(0.189 - 0.189 * invAmount, 0.168 - 0.168 * invAmount, 0.131 + 0.869 * invAmount, 0.0),
vec4(0.0, 0.0, 0.0, 1.0));
vColorOffset = vec4(0.0);
break;
@@ -1072,19 +1072,40 @@ impl AlphaBatchBuilder {
BatchTextures::render_target_cache(),
);

let (filter_mode, extra_cache_address) = match filter {
FilterOp::Blur(..) => (0, 0),
FilterOp::Contrast(..) => (1, 0),
FilterOp::Grayscale(..) => (2, 0),
FilterOp::HueRotate(..) => (3, 0),
FilterOp::Invert(..) => (4, 0),
FilterOp::Saturate(..) => (5, 0),
FilterOp::Sepia(..) => (6, 0),
FilterOp::Brightness(..) => (7, 0),
FilterOp::Opacity(..) => (8, 0),
FilterOp::DropShadow(..) => (9, 0),
FilterOp::ColorMatrix(..) => {
(10, extra_gpu_data_handle.as_int(gpu_cache))
let filter_mode = match filter {
FilterOp::Blur(..) => 0,
FilterOp::Contrast(..) => 1,
FilterOp::Grayscale(..) => 2,
FilterOp::HueRotate(..) => 3,
FilterOp::Invert(..) => 4,
FilterOp::Saturate(..) => 5,
FilterOp::Sepia(..) => 6,
FilterOp::Brightness(..) => 7,
FilterOp::Opacity(..) => 8,
FilterOp::DropShadow(..) => 9,
FilterOp::ColorMatrix(..) => 10,
};

let user_data = match filter {
FilterOp::Contrast(amount) |
FilterOp::Grayscale(amount) |
FilterOp::Invert(amount) |
FilterOp::Saturate(amount) |
FilterOp::Sepia(amount) |
FilterOp::Brightness(amount) |
FilterOp::Opacity(_, amount) => {
(amount * 65536.0) as i32
}
FilterOp::HueRotate(angle) => {
(0.01745329251 * angle * 65536.0) as i32
}
// Go through different paths
FilterOp::Blur(..) |
FilterOp::DropShadow(..) => {
unreachable!();
}
FilterOp::ColorMatrix(_) => {
extra_gpu_data_handle.as_int(gpu_cache)
}
};

@@ -1101,7 +1122,7 @@ impl AlphaBatchBuilder {
user_data: [
cache_task_address.0 as i32,
filter_mode,
extra_cache_address,
user_data,
],
};

@@ -1148,25 +1169,32 @@ impl AlphaBatchBuilder {
batch.push(PrimitiveInstance::from(instance));
}
PictureCompositeMode::Blit => {
let src_task_address = render_tasks.get_task_address(source_id);
let key = BatchKey::new(
BatchKind::HardwareComposite,
BlendMode::PremultipliedAlpha,
BatchTextures::render_target_cache(),
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
);
let key = BatchKey::new(kind, non_segmented_blend_mode, textures);
let batch = self.batch_list.get_suitable_batch(key, &task_relative_bounding_rect);
let item_bounding_rect = prim_metadata.screen_rect.expect("bug!!").clipped;
let instance = CompositePrimitiveInstance::new(
task_address,
src_task_address,
RenderTaskAddress(0),
item_bounding_rect.origin.x,
item_bounding_rect.origin.y,
z,
item_bounding_rect.size.width,
item_bounding_rect.size.height,
);

let uv_rect_address = render_tasks[cache_task_id]
.get_texture_handle()
.as_int(gpu_cache);

let instance = BrushInstance {
picture_address: task_address,
prim_address: prim_cache_address,
clip_chain_rect_index,
scroll_id,
clip_task_address,
z,
segment_index: 0,
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: [
uv_rect_address,
BrushImageSourceKind::Color as i32,
RasterizationSpace::Screen as i32,
],
};
batch.push(PrimitiveInstance::from(instance));
}
}
@@ -272,13 +272,15 @@ impl PicturePrimitive {
composite_mode,
..
} => {
match composite_mode {
let device_rect = match composite_mode {
Some(PictureCompositeMode::Filter(FilterOp::Blur(blur_radius))) => {
// If blur radius is 0, we can skip drawing this an an
// intermediate surface.
if blur_radius == 0.0 {
pic_state.tasks.extend(pic_state_for_children.tasks);
self.surface = None;

DeviceIntRect::zero()
} else {
let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0;
let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
@@ -297,15 +299,6 @@ impl PicturePrimitive {
.intersection(&prim_screen_rect.unclipped)
.unwrap();

// If scrolling or property animation has resulted in the task
// rect being different than last time, invalidate the GPU
// cache entry for this picture to ensure that the correct
// task rect is provided to the image shader.
if *task_rect != device_rect {
frame_state.gpu_cache.invalidate(&prim_metadata.gpu_location);
*task_rect = device_rect;
}

let content_origin = ContentOrigin::Screen(device_rect.origin);

let picture_task = RenderTask::new_picture(
@@ -333,6 +326,8 @@ impl PicturePrimitive {
let render_task_id = frame_state.render_tasks.add(blur_render_task);
pic_state.tasks.push(render_task_id);
self.surface = Some(render_task_id);

device_rect
}
}
Some(PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color))) => {
@@ -368,6 +363,8 @@ impl PicturePrimitive {
let render_task_id = frame_state.render_tasks.add(blur_render_task);
pic_state.tasks.push(render_task_id);
self.surface = Some(render_task_id);

rect
}
Some(PictureCompositeMode::MixBlend(..)) => {
let content_origin = ContentOrigin::Screen(prim_screen_rect.clipped.origin);
@@ -393,6 +390,8 @@ impl PicturePrimitive {
let render_task_id = frame_state.render_tasks.add(picture_task);
pic_state.tasks.push(render_task_id);
self.surface = Some(render_task_id);

prim_screen_rect.clipped
}
Some(PictureCompositeMode::Filter(filter)) => {
let content_origin = ContentOrigin::Screen(prim_screen_rect.clipped.origin);
@@ -430,6 +429,8 @@ impl PicturePrimitive {
pic_state.tasks.push(render_task_id);
self.surface = Some(render_task_id);
}

prim_screen_rect.clipped
}
Some(PictureCompositeMode::Blit) => {
let content_origin = ContentOrigin::Screen(prim_screen_rect.clipped.origin);
@@ -448,11 +449,24 @@ impl PicturePrimitive {
let render_task_id = frame_state.render_tasks.add(picture_task);
pic_state.tasks.push(render_task_id);
self.surface = Some(render_task_id);

prim_screen_rect.clipped
}
None => {
pic_state.tasks.extend(pic_state_for_children.tasks);
self.surface = None;

DeviceIntRect::zero()
}
};

// If scrolling or property animation has resulted in the task
// rect being different than last time, invalidate the GPU
// cache entry for this picture to ensure that the correct
// task rect is provided to the image shader.
if *task_rect != device_rect {
frame_state.gpu_cache.invalidate(&prim_metadata.gpu_location);
*task_rect = device_rect;
}
}
PictureKind::TextShadow { blur_radius, color, content_rect, .. } => {
@@ -498,50 +512,12 @@ impl PicturePrimitive {
}

pub fn write_gpu_blocks(&self, request: &mut GpuDataRequest) {
// TODO(gw): It's unfortunate that we pay a fixed cost
// of 5 GPU blocks / picture, just due to the size
// of the color matrix. There aren't typically very
// many pictures in a scene, but we should consider
// making this more efficient for the common case.
match self.kind {
PictureKind::TextShadow { .. } => {
request.push([0.0; 4]);
}
PictureKind::Image { composite_mode, task_rect, .. } => {
match composite_mode {
Some(PictureCompositeMode::Filter(filter)) => {
let amount = match filter {
FilterOp::Contrast(amount) => amount,
FilterOp::Grayscale(amount) => amount,
FilterOp::HueRotate(angle) => 0.01745329251 * angle,
FilterOp::Invert(amount) => amount,
FilterOp::Saturate(amount) => amount,
FilterOp::Sepia(amount) => amount,
FilterOp::Brightness(amount) => amount,
FilterOp::Opacity(_, amount) => amount,

// Go through different paths
FilterOp::Blur(..) |
FilterOp::DropShadow(..) |
FilterOp::ColorMatrix(_) => {
// TODO(gw): The data for blur (and drop-shadows in the future)
// doesn't match how the brush_blend shader uses this
// data for other filter types (see below). We should
// update the brush_blend and brush_mix_blend shaders
// to do screen-space UV calculation the same way that
// the brush_image shader does, and move the amount
// storage into the extra gpu data or instance data.
request.push(task_rect.to_f32());
return;
}
};

request.push([amount, 1.0 - amount, 0.0, 0.0]);
}
_ => {
request.push([0.0; 4]);
}
}
PictureKind::Image { task_rect, .. } => {
request.push(task_rect.to_f32());
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.