Merge pull request #317 from pcwalton/four-at-a-time

Use all four channels in the mask texture.
This commit is contained in:
Patrick Walton 2020-05-07 09:55:30 -07:00 committed by GitHub
commit cfc1d44638
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 276 additions and 201 deletions

View File

@ -14,7 +14,7 @@ use crate::{BackgroundColor, Options};
use pathfinder_color::ColorU; use pathfinder_color::ColorU;
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::{Vector2I, vec2i}; use pathfinder_geometry::vector::{Vector2I, vec2i};
use pathfinder_gpu::Device; use pathfinder_gpu::{Device, TextureFormat};
use pathfinder_renderer::gpu::debug::DebugUIPresenter; use pathfinder_renderer::gpu::debug::DebugUIPresenter;
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING}; use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING};
@ -121,15 +121,30 @@ where
D: Device, D: Device,
{ {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter<D> { pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter<D> {
let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME); let effects_texture = device.create_texture_from_png(resources,
let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME); EFFECTS_PNG_NAME,
let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME); TextureFormat::R8);
let zoom_in_texture = device.create_texture_from_png(resources, ZOOM_IN_PNG_NAME); let open_texture = device.create_texture_from_png(resources,
OPEN_PNG_NAME,
TextureFormat::R8);
let rotate_texture = device.create_texture_from_png(resources,
ROTATE_PNG_NAME,
TextureFormat::R8);
let zoom_in_texture = device.create_texture_from_png(resources,
ZOOM_IN_PNG_NAME,
TextureFormat::R8);
let zoom_actual_size_texture = device.create_texture_from_png(resources, let zoom_actual_size_texture = device.create_texture_from_png(resources,
ZOOM_ACTUAL_SIZE_PNG_NAME); ZOOM_ACTUAL_SIZE_PNG_NAME,
let zoom_out_texture = device.create_texture_from_png(resources, ZOOM_OUT_PNG_NAME); TextureFormat::R8);
let background_texture = device.create_texture_from_png(resources, BACKGROUND_PNG_NAME); let zoom_out_texture = device.create_texture_from_png(resources,
let screenshot_texture = device.create_texture_from_png(resources, SCREENSHOT_PNG_NAME); ZOOM_OUT_PNG_NAME,
TextureFormat::R8);
let background_texture = device.create_texture_from_png(resources,
BACKGROUND_PNG_NAME,
TextureFormat::R8);
let screenshot_texture = device.create_texture_from_png(resources,
SCREENSHOT_PNG_NAME,
TextureFormat::R8);
DemoUIPresenter { DemoUIPresenter {
effects_texture, effects_texture,

View File

@ -104,13 +104,26 @@ pub trait Device: Sized {
fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option<TextureData>; fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option<TextureData>;
fn recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> TextureData; fn recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> TextureData;
fn create_texture_from_png(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Texture { fn create_texture_from_png(&self,
resources: &dyn ResourceLoader,
name: &str,
format: TextureFormat)
-> Self::Texture {
let data = resources.slurp(&format!("textures/{}.png", name)).unwrap(); let data = resources.slurp(&format!("textures/{}.png", name)).unwrap();
let image = image::load_from_memory_with_format(&data, ImageFormat::Png) let image = image::load_from_memory_with_format(&data, ImageFormat::Png).unwrap();
.unwrap() match format {
.to_luma(); TextureFormat::R8 => {
let size = vec2i(image.width() as i32, image.height() as i32); let image = image.to_luma();
self.create_texture_from_data(TextureFormat::R8, size, TextureDataRef::U8(&image)) let size = vec2i(image.width() as i32, image.height() as i32);
self.create_texture_from_data(format, size, TextureDataRef::U8(&image))
}
TextureFormat::RGBA8 => {
let image = image.to_rgba();
let size = vec2i(image.width() as i32, image.height() as i32);
self.create_texture_from_data(format, size, TextureDataRef::U8(&image))
}
_ => unimplemented!(),
}
} }
fn create_program_from_shader_names( fn create_program_from_shader_names(

View File

@ -65,8 +65,8 @@ const TEXTURE_METADATA_TEXTURE_WIDTH: i32 = TEXTURE_METADATA_ENTRIES_PER_ROW *
const TEXTURE_METADATA_TEXTURE_HEIGHT: i32 = 65536 / TEXTURE_METADATA_ENTRIES_PER_ROW; const TEXTURE_METADATA_TEXTURE_HEIGHT: i32 = 65536 / TEXTURE_METADATA_ENTRIES_PER_ROW;
// FIXME(pcwalton): Shrink this again! // FIXME(pcwalton): Shrink this again!
const MASK_FRAMEBUFFER_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS as i32; const MASK_FRAMEBUFFER_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS as i32;
const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 * MASK_TILES_DOWN as i32; const MASK_FRAMEBUFFER_HEIGHT: i32 = TILE_HEIGHT as i32 / 4 * MASK_TILES_DOWN as i32;
const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1; const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1;
const COMBINER_CTRL_COLOR_COMBINE_DEST_IN: i32 = 0x2; const COMBINER_CTRL_COLOR_COMBINE_DEST_IN: i32 = 0x2;
@ -170,8 +170,10 @@ impl<D> Renderer<D> where D: Device {
let stencil_program = StencilProgram::new(&device, resources); let stencil_program = StencilProgram::new(&device, resources);
let reprojection_program = ReprojectionProgram::new(&device, resources); let reprojection_program = ReprojectionProgram::new(&device, resources);
let area_lut_texture = device.create_texture_from_png(resources, "area-lut"); let area_lut_texture =
let gamma_lut_texture = device.create_texture_from_png(resources, "gamma-lut"); device.create_texture_from_png(resources, "area-lut", TextureFormat::RGBA8);
let gamma_lut_texture =
device.create_texture_from_png(resources, "gamma-lut", TextureFormat::R8);
let quad_vertex_positions_buffer = device.create_buffer(BufferUploadMode::Static); let quad_vertex_positions_buffer = device.create_buffer(BufferUploadMode::Static);
device.allocate_buffer(&quad_vertex_positions_buffer, device.allocate_buffer(&quad_vertex_positions_buffer,
@ -906,7 +908,10 @@ impl<D> Renderer<D> where D: Device {
if let Some(alpha_tile_page) = self.back_frame.alpha_tile_pages.get(&tile_page) { if let Some(alpha_tile_page) = self.back_frame.alpha_tile_pages.get(&tile_page) {
uniforms.push((&self.tile_program.mask_texture_0_uniform, uniforms.push((&self.tile_program.mask_texture_0_uniform,
UniformData::TextureUnit(textures.len() as u32))); UniformData::TextureUnit(textures.len() as u32)));
uniforms.push((&self.tile_program.mask_texture_size_0_uniform,
UniformData::Vec2(F32x2::new(MASK_FRAMEBUFFER_WIDTH as f32,
MASK_FRAMEBUFFER_HEIGHT as f32))));
textures.push(self.device.framebuffer_texture(&alpha_tile_page.framebuffer)); textures.push(self.device.framebuffer_texture(&alpha_tile_page.framebuffer));
} }
@ -919,16 +924,16 @@ impl<D> Renderer<D> where D: Device {
self.device.set_texture_sampling_mode(color_texture_page, self.device.set_texture_sampling_mode(color_texture_page,
color_texture.sampling_flags); color_texture.sampling_flags);
uniforms.push((&self.tile_program.color_texture_0_uniform, uniforms.push((&self.tile_program.color_texture_0_uniform,
UniformData::TextureUnit(textures.len() as u32))); UniformData::TextureUnit(textures.len() as u32)));
uniforms.push((&self.tile_program.color_texture_0_size_uniform, uniforms.push((&self.tile_program.color_texture_size_0_uniform,
UniformData::Vec2(color_texture_size.0))); UniformData::Vec2(color_texture_size.0)));
textures.push(color_texture_page); textures.push(color_texture_page);
ctrl |= color_texture.composite_op.to_combine_mode() << ctrl |= color_texture.composite_op.to_combine_mode() <<
COMBINER_CTRL_COLOR_COMBINE_SHIFT; COMBINER_CTRL_COLOR_COMBINE_SHIFT;
} }
None => { None => {
uniforms.push((&self.tile_program.color_texture_0_size_uniform, uniforms.push((&self.tile_program.color_texture_size_0_uniform,
UniformData::Vec2(F32x2::default()))); UniformData::Vec2(F32x2::default())));
} }
} }
@ -1913,7 +1918,7 @@ struct AlphaTilePage<D> where D: Device {
impl<D> AlphaTilePage<D> where D: Device { impl<D> AlphaTilePage<D> where D: Device {
fn new(device: &mut D) -> AlphaTilePage<D> { fn new(device: &mut D) -> AlphaTilePage<D> {
let framebuffer_size = vec2i(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT); let framebuffer_size = vec2i(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT);
let framebuffer_texture = device.create_texture(TextureFormat::R16F, framebuffer_size); let framebuffer_texture = device.create_texture(TextureFormat::RGBA16F, framebuffer_size);
let framebuffer = device.create_framebuffer(framebuffer_texture); let framebuffer = device.create_framebuffer(framebuffer_texture);
AlphaTilePage { AlphaTilePage {
buffered_fills: vec![], buffered_fills: vec![],

View File

@ -388,7 +388,7 @@ pub struct FillComputeProgram<D> where D: Device {
impl<D> FillComputeProgram<D> where D: Device { impl<D> FillComputeProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram<D> { pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram<D> {
let mut program = device.create_compute_program(resources, "fill"); let mut program = device.create_compute_program(resources, "fill");
let local_size = ComputeDimensions { x: TILE_WIDTH, y: TILE_HEIGHT, z: 1 }; let local_size = ComputeDimensions { x: TILE_WIDTH, y: TILE_HEIGHT / 4, z: 1 };
device.set_compute_program_local_size(&mut program, local_size); device.set_compute_program_local_size(&mut program, local_size);
let dest_uniform = device.get_uniform(&program, "Dest"); let dest_uniform = device.get_uniform(&program, "Dest");
@ -418,10 +418,11 @@ pub struct TileProgram<D> where D: Device {
pub texture_metadata_size_uniform: D::Uniform, pub texture_metadata_size_uniform: D::Uniform,
pub dest_texture_uniform: D::Uniform, pub dest_texture_uniform: D::Uniform,
pub color_texture_0_uniform: D::Uniform, pub color_texture_0_uniform: D::Uniform,
pub color_texture_size_0_uniform: D::Uniform,
pub color_texture_1_uniform: D::Uniform, pub color_texture_1_uniform: D::Uniform,
pub mask_texture_0_uniform: D::Uniform, pub mask_texture_0_uniform: D::Uniform,
pub mask_texture_size_0_uniform: D::Uniform,
pub gamma_lut_uniform: D::Uniform, pub gamma_lut_uniform: D::Uniform,
pub color_texture_0_size_uniform: D::Uniform,
pub filter_params_0_uniform: D::Uniform, pub filter_params_0_uniform: D::Uniform,
pub filter_params_1_uniform: D::Uniform, pub filter_params_1_uniform: D::Uniform,
pub filter_params_2_uniform: D::Uniform, pub filter_params_2_uniform: D::Uniform,
@ -438,10 +439,11 @@ impl<D> TileProgram<D> where D: Device {
let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize"); let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize");
let dest_texture_uniform = device.get_uniform(&program, "DestTexture"); let dest_texture_uniform = device.get_uniform(&program, "DestTexture");
let color_texture_0_uniform = device.get_uniform(&program, "ColorTexture0"); let color_texture_0_uniform = device.get_uniform(&program, "ColorTexture0");
let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0");
let color_texture_1_uniform = device.get_uniform(&program, "ColorTexture1"); let color_texture_1_uniform = device.get_uniform(&program, "ColorTexture1");
let mask_texture_0_uniform = device.get_uniform(&program, "MaskTexture0"); let mask_texture_0_uniform = device.get_uniform(&program, "MaskTexture0");
let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0");
let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT"); let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT");
let color_texture_0_size_uniform = device.get_uniform(&program, "ColorTexture0Size");
let filter_params_0_uniform = device.get_uniform(&program, "FilterParams0"); let filter_params_0_uniform = device.get_uniform(&program, "FilterParams0");
let filter_params_1_uniform = device.get_uniform(&program, "FilterParams1"); let filter_params_1_uniform = device.get_uniform(&program, "FilterParams1");
let filter_params_2_uniform = device.get_uniform(&program, "FilterParams2"); let filter_params_2_uniform = device.get_uniform(&program, "FilterParams2");
@ -455,10 +457,11 @@ impl<D> TileProgram<D> where D: Device {
texture_metadata_size_uniform, texture_metadata_size_uniform,
dest_texture_uniform, dest_texture_uniform,
color_texture_0_uniform, color_texture_0_uniform,
color_texture_size_0_uniform,
color_texture_1_uniform, color_texture_1_uniform,
mask_texture_0_uniform, mask_texture_0_uniform,
mask_texture_size_0_uniform,
gamma_lut_uniform, gamma_lut_uniform,
color_texture_0_size_uniform,
filter_params_0_uniform, filter_params_0_uniform,
filter_params_1_uniform, filter_params_1_uniform,
filter_params_2_uniform, filter_params_2_uniform,

View File

@ -28,7 +28,7 @@ precision highp sampler2D;
float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){ vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){
vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from; vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from;
@ -43,7 +43,7 @@ float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){
float dX = window . x - window . y; float dX = window . x - window . y;
return texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0). r * dX; return texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0)* dX;
} }
@ -55,6 +55,6 @@ in vec2 vTo;
out vec4 oFragColor; out vec4 oFragColor;
void main(){ void main(){
oFragColor = vec4(computeCoverage(vFrom, vTo, uAreaLUT)); oFragColor = computeCoverage(vFrom, vTo, uAreaLUT);
} }

View File

@ -31,7 +31,7 @@ out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x); uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset)* uTileSize; return vec2(tileOffset)* uTileSize * vec2(1.0, 0.25);
} }
void main(){ void main(){
@ -49,9 +49,15 @@ void main(){
position . y = floor(min(from . y, to . y)); position . y = floor(min(from . y, to . y));
else else
position . y = uTileSize . y; position . y = uTileSize . y;
position . y = floor(position . y * 0.25);
vFrom = from - position;
vTo = to - position;
vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0);
vFrom = from + offset;
vTo = to + offset;
vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0; vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0;

View File

@ -84,11 +84,12 @@ uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0; uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture; uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT; uniform sampler2D uGammaLUT;
uniform vec2 uColorTextureSize0;
uniform vec2 uMaskTextureSize0;
uniform vec4 uFilterParams0; uniform vec4 uFilterParams0;
uniform vec4 uFilterParams1; uniform vec4 uFilterParams1;
uniform vec4 uFilterParams2; uniform vec4 uFilterParams2;
uniform vec2 uFramebufferSize; uniform vec2 uFramebufferSize;
uniform vec2 uColorTexture0Size;
uniform int uCtrl; uniform int uCtrl;
in vec3 vMaskTexCoord0; in vec3 vMaskTexCoord0;
@ -544,11 +545,16 @@ vec4 composite(vec4 srcColor,
float sampleMask(float maskAlpha, float sampleMask(float maskAlpha,
sampler2D maskTexture, sampler2D maskTexture,
vec2 maskTextureSize,
vec3 maskTexCoord, vec3 maskTexCoord,
int maskCtrl){ int maskCtrl){
if(maskCtrl == 0) if(maskCtrl == 0)
return maskAlpha; return maskAlpha;
float coverage = texture(maskTexture, maskTexCoord . xy). r + maskTexCoord . z;
ivec2 maskTexCoordI = ivec2(floor(maskTexCoord . xy));
vec4 texel = texture(maskTexture,(vec2(maskTexCoordI / ivec2(1, 4))+ 0.5)/ maskTextureSize);
float coverage = texel[maskTexCoordI . y % 4]+ maskTexCoord . z;
if((maskCtrl & 0x1)!= 0) if((maskCtrl & 0x1)!= 0)
coverage = abs(coverage); coverage = abs(coverage);
else else
@ -562,7 +568,7 @@ void calculateColor(int tileCtrl, int ctrl){
int maskCtrl0 =(tileCtrl >> 0)& 0x3; int maskCtrl0 =(tileCtrl >> 0)& 0x3;
float maskAlpha = 1.0; float maskAlpha = 1.0;
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, vMaskTexCoord0, maskCtrl0); maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
vec4 color = vBaseColor; vec4 color = vBaseColor;
@ -573,7 +579,7 @@ void calculateColor(int tileCtrl, int ctrl){
vec4 color0 = filterColor(vColorTexCoord0, vec4 color0 = filterColor(vColorTexCoord0,
uColorTexture0, uColorTexture0,
uGammaLUT, uGammaLUT,
uColorTexture0Size, uColorTextureSize0,
gl_FragCoord . xy, gl_FragCoord . xy,
uFramebufferSize, uFramebufferSize,
uFilterParams0, uFilterParams0,

View File

@ -36,7 +36,7 @@ void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize; vec2 position =(tileOrigin + tileOffset)* uTileSize;
vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)/ 256.0; vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)* uTileSize;
vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize); vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);

View File

@ -23,7 +23,6 @@ in float vBackdrop;
out vec4 oFragColor; out vec4 oFragColor;
void main(){ void main(){
float alpha = clamp(abs(texture(uSrc, vTexCoord). r + vBackdrop), 0.0, 1.0); oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0);
oFragColor = vec4(alpha, 0.0, 0.0, 1.0);
} }

View File

@ -21,10 +21,10 @@ struct bNextFills
int iNextFills[1]; int iNextFills[1];
}; };
constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(16u, 16u, 1u); constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(16u, 4u, 1u);
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
float computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d<float> areaLUT, thread const sampler areaLUTSmplr) float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d<float> areaLUT, thread const sampler areaLUTSmplr)
{ {
float2 left = select(to, from, bool2(from.x < to.x)); float2 left = select(to, from, bool2(from.x < to.x));
float2 right = select(from, to, bool2(from.x < to.x)); float2 right = select(from, to, bool2(from.x < to.x));
@ -34,34 +34,32 @@ float computeCoverage(thread const float2& from, thread const float2& to, thread
float y = mix(left.y, right.y, t); float y = mix(left.y, right.y, t);
float d = (right.y - left.y) / (right.x - left.x); float d = (right.y - left.y) / (right.x - left.x);
float dX = window.x - window.y; float dX = window.x - window.y;
return areaLUT.sample(areaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0)), level(0.0)).x * dX; return areaLUT.sample(areaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0)), level(0.0)) * dX;
} }
kernel void main0(constant int& uFirstTileIndex [[buffer(0)]], const device bFillTileMap& _165 [[buffer(1)]], const device bFills& _186 [[buffer(2)]], const device bNextFills& _269 [[buffer(3)]], texture2d<float> uAreaLUT [[texture(0)]], texture2d<float, access::write> uDest [[texture(1)]], sampler uAreaLUTSmplr [[sampler(0)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) kernel void main0(constant int& uFirstTileIndex [[buffer(0)]], const device bFillTileMap& _150 [[buffer(1)]], const device bFills& _173 [[buffer(2)]], const device bNextFills& _256 [[buffer(3)]], texture2d<float> uAreaLUT [[texture(0)]], texture2d<float, access::write> uDest [[texture(1)]], sampler uAreaLUTSmplr [[sampler(0)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]])
{ {
int2 tileSubCoord = int2(gl_LocalInvocationID.xy); int2 tileSubCoord = int2(gl_LocalInvocationID.xy) * int2(1, 4);
uint tileIndexOffset = gl_WorkGroupID.z; uint tileIndexOffset = gl_WorkGroupID.z;
uint tileIndex = tileIndexOffset + uint(uFirstTileIndex); uint tileIndex = tileIndexOffset + uint(uFirstTileIndex);
int2 tileOrigin = int2(int(tileIndex & 255u), int((tileIndex >> 8u) & 255u)) * int2(16); int fillIndex = _150.iFillTileMap[tileIndex];
int2 destCoord = tileOrigin + tileSubCoord;
int fillIndex = _165.iFillTileMap[tileIndex];
if (fillIndex < 0) if (fillIndex < 0)
{ {
return; return;
} }
float coverage = 0.0; float4 coverages = float4(0.0);
do do
{ {
uint2 fill = _186.iFills[fillIndex]; uint2 fill = _173.iFills[fillIndex];
float2 from = float2(float(fill.y & 15u), float((fill.y >> 4u) & 15u)) + (float2(float(fill.x & 255u), float((fill.x >> 8u) & 255u)) / float2(256.0)); float2 from = float2(float(fill.y & 15u), float((fill.y >> 4u) & 15u)) + (float2(float(fill.x & 255u), float((fill.x >> 8u) & 255u)) / float2(256.0));
float2 to = float2(float((fill.y >> 8u) & 15u), float((fill.y >> 12u) & 15u)) + (float2(float((fill.x >> 16u) & 255u), float((fill.x >> 24u) & 255u)) / float2(256.0)); float2 to = float2(float((fill.y >> 8u) & 15u), float((fill.y >> 12u) & 15u)) + (float2(float((fill.x >> 16u) & 255u), float((fill.x >> 24u) & 255u)) / float2(256.0));
from -= (float2(tileSubCoord) + float2(0.5)); float2 param = from - (float2(tileSubCoord) + float2(0.5));
to -= (float2(tileSubCoord) + float2(0.5)); float2 param_1 = to - (float2(tileSubCoord) + float2(0.5));
float2 param = from; coverages += computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr);
float2 param_1 = to; fillIndex = _256.iNextFills[fillIndex];
coverage += computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr);
fillIndex = _269.iNextFills[fillIndex];
} while (fillIndex >= 0); } while (fillIndex >= 0);
uDest.write(float4(coverage), uint2(destCoord)); int2 tileOrigin = int2(int(tileIndex & 255u), int((tileIndex >> 8u) & 255u)) * int2(16, 4);
int2 destCoord = tileOrigin + int2(gl_LocalInvocationID.xy);
uDest.write(coverages, uint2(destCoord));
} }

View File

@ -18,7 +18,7 @@ struct main0_in
}; };
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
float computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d<float> areaLUT, thread const sampler areaLUTSmplr) float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d<float> areaLUT, thread const sampler areaLUTSmplr)
{ {
float2 left = select(to, from, bool2(from.x < to.x)); float2 left = select(to, from, bool2(from.x < to.x));
float2 right = select(from, to, bool2(from.x < to.x)); float2 right = select(from, to, bool2(from.x < to.x));
@ -28,7 +28,7 @@ float computeCoverage(thread const float2& from, thread const float2& to, thread
float y = mix(left.y, right.y, t); float y = mix(left.y, right.y, t);
float d = (right.y - left.y) / (right.x - left.x); float d = (right.y - left.y) / (right.x - left.x);
float dX = window.x - window.y; float dX = window.x - window.y;
return areaLUT.sample(areaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))).x * dX; return areaLUT.sample(areaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))) * dX;
} }
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[texture(0)]], sampler uAreaLUTSmplr [[sampler(0)]]) fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[texture(0)]], sampler uAreaLUTSmplr [[sampler(0)]])
@ -36,7 +36,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[t
main0_out out = {}; main0_out out = {};
float2 param = in.vFrom; float2 param = in.vFrom;
float2 param_1 = in.vTo; float2 param_1 = in.vTo;
out.oFragColor = float4(computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr)); out.oFragColor = computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr);
return out; return out;
} }

View File

@ -28,7 +28,7 @@ float2 computeTileOffset(thread const uint& tileIndex, thread const float& stenc
{ {
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return float2(tileOffset) * uTileSize; return (float2(tileOffset) * uTileSize) * float2(1.0, 0.25);
} }
vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]]) vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]])
@ -56,8 +56,10 @@ vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[bu
{ {
position.y = uTileSize.y; position.y = uTileSize.y;
} }
out.vFrom = from - position; position.y = floor(position.y * 0.25);
out.vTo = to - position; float2 offset = float2(0.0, 1.5) - (position * float2(1.0, 4.0));
out.vFrom = from + offset;
out.vTo = to + offset;
float2 globalPosition = (((tileOrigin + position) / uFramebufferSize) * 2.0) - float2(1.0); float2 globalPosition = (((tileOrigin + position) / uFramebufferSize) * 2.0) - float2(1.0);
globalPosition.y = -globalPosition.y; globalPosition.y = -globalPosition.y;
out.gl_Position = float4(globalPosition, 0.0, 1.0); out.gl_Position = float4(globalPosition, 0.0, 1.0);

View File

@ -6,7 +6,7 @@
using namespace metal; using namespace metal;
constant float3 _1041 = {}; constant float3 _1042 = {};
struct main0_out struct main0_out
{ {
@ -29,13 +29,15 @@ inline Tx mod(Tx x, Ty y)
} }
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
float sampleMask(thread const float& maskAlpha, thread const texture2d<float> maskTexture, thread const sampler maskTextureSmplr, thread const float3& maskTexCoord, thread const int& maskCtrl) float sampleMask(thread const float& maskAlpha, thread const texture2d<float> maskTexture, thread const sampler maskTextureSmplr, thread const float2& maskTextureSize, thread const float3& maskTexCoord, thread const int& maskCtrl)
{ {
if (maskCtrl == 0) if (maskCtrl == 0)
{ {
return maskAlpha; return maskAlpha;
} }
float coverage = maskTexture.sample(maskTextureSmplr, maskTexCoord.xy).x + maskTexCoord.z; int2 maskTexCoordI = int2(floor(maskTexCoord.xy));
float4 texel = maskTexture.sample(maskTextureSmplr, ((float2(maskTexCoordI / int2(1, 4)) + float2(0.5)) / maskTextureSize));
float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z;
if ((maskCtrl & 1) != 0) if ((maskCtrl & 1) != 0)
{ {
coverage = abs(coverage); coverage = abs(coverage);
@ -69,16 +71,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex
{ {
ts = ts.yx; ts = ts.yx;
} }
float _554; float _555;
if (ts.x >= 0.0) if (ts.x >= 0.0)
{ {
_554 = ts.x; _555 = ts.x;
} }
else else
{ {
_554 = ts.y; _555 = ts.y;
} }
float t = _554; float t = _555;
color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0))); color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0)));
} }
return color; return color;
@ -92,19 +94,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d<flo
float3 gaussCoeff = filterParams1.xyz; float3 gaussCoeff = filterParams1.xyz;
float gaussSum = gaussCoeff.x; float gaussSum = gaussCoeff.x;
float4 color = colorTexture.sample(colorTextureSmplr, colorTexCoord) * gaussCoeff.x; float4 color = colorTexture.sample(colorTextureSmplr, colorTexCoord) * gaussCoeff.x;
float2 _599 = gaussCoeff.xy * gaussCoeff.yz; float2 _600 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_599.x, _599.y, gaussCoeff.z); gaussCoeff = float3(_600.x, _600.y, gaussCoeff.z);
for (int i = 1; i <= support; i += 2) for (int i = 1; i <= support; i += 2)
{ {
float gaussPartialSum = gaussCoeff.x; float gaussPartialSum = gaussCoeff.x;
float2 _619 = gaussCoeff.xy * gaussCoeff.yz; float2 _620 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_619.x, _619.y, gaussCoeff.z); gaussCoeff = float3(_620.x, _620.y, gaussCoeff.z);
gaussPartialSum += gaussCoeff.x; gaussPartialSum += gaussCoeff.x;
float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum)); float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum));
color += ((colorTexture.sample(colorTextureSmplr, (colorTexCoord - srcOffset)) + colorTexture.sample(colorTextureSmplr, (colorTexCoord + srcOffset))) * gaussPartialSum); color += ((colorTexture.sample(colorTextureSmplr, (colorTexCoord - srcOffset)) + colorTexture.sample(colorTextureSmplr, (colorTexCoord + srcOffset))) * gaussPartialSum);
gaussSum += (2.0 * gaussPartialSum); gaussSum += (2.0 * gaussPartialSum);
float2 _659 = gaussCoeff.xy * gaussCoeff.yz; float2 _660 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_659.x, _659.y, gaussCoeff.z); gaussCoeff = float3(_660.x, _660.y, gaussCoeff.z);
} }
return color / float4(gaussSum); return color / float4(gaussSum);
} }
@ -119,16 +121,16 @@ static inline __attribute__((always_inline))
void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCenter, thread float4& outAlphaRight, thread const texture2d<float> colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel) void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCenter, thread float4& outAlphaRight, thread const texture2d<float> colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel)
{ {
bool wide = kernel0.x > 0.0; bool wide = kernel0.x > 0.0;
float _235; float _236;
if (wide) if (wide)
{ {
float param = (-4.0) * onePixel; float param = (-4.0) * onePixel;
float2 param_1 = colorTexCoord; float2 param_1 = colorTexCoord;
_235 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); _236 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1);
} }
else else
{ {
_235 = 0.0; _236 = 0.0;
} }
float param_2 = (-3.0) * onePixel; float param_2 = (-3.0) * onePixel;
float2 param_3 = colorTexCoord; float2 param_3 = colorTexCoord;
@ -136,7 +138,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen
float2 param_5 = colorTexCoord; float2 param_5 = colorTexCoord;
float param_6 = (-1.0) * onePixel; float param_6 = (-1.0) * onePixel;
float2 param_7 = colorTexCoord; float2 param_7 = colorTexCoord;
outAlphaLeft = float4(_235, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7)); outAlphaLeft = float4(_236, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7));
float param_8 = 0.0; float param_8 = 0.0;
float2 param_9 = colorTexCoord; float2 param_9 = colorTexCoord;
outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9); outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9);
@ -146,18 +148,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen
float2 param_13 = colorTexCoord; float2 param_13 = colorTexCoord;
float param_14 = 3.0 * onePixel; float param_14 = 3.0 * onePixel;
float2 param_15 = colorTexCoord; float2 param_15 = colorTexCoord;
float _295; float _296;
if (wide) if (wide)
{ {
float param_16 = 4.0 * onePixel; float param_16 = 4.0 * onePixel;
float2 param_17 = colorTexCoord; float2 param_17 = colorTexCoord;
_295 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); _296 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17);
} }
else else
{ {
_295 = 0.0; _296 = 0.0;
} }
outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _295); outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _296);
} }
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
@ -307,34 +309,34 @@ float3 compositeScreen(thread const float3& destColor, thread const float3& srcC
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse) float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse)
{ {
float _725; float _726;
if (cond.x) if (cond.x)
{ {
_725 = ifTrue.x; _726 = ifTrue.x;
} }
else else
{ {
_725 = ifFalse.x; _726 = ifFalse.x;
} }
float _736; float _737;
if (cond.y) if (cond.y)
{ {
_736 = ifTrue.y; _737 = ifTrue.y;
} }
else else
{ {
_736 = ifFalse.y; _737 = ifFalse.y;
} }
float _747; float _748;
if (cond.z) if (cond.z)
{ {
_747 = ifTrue.z; _748 = ifTrue.z;
} }
else else
{ {
_747 = ifFalse.z; _748 = ifFalse.z;
} }
return float3(_725, _736, _747); return float3(_726, _737, _748);
} }
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
@ -379,16 +381,16 @@ float3 compositeSoftLight(thread const float3& destColor, thread const float3& s
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
float compositeDivide(thread const float& num, thread const float& denom) float compositeDivide(thread const float& num, thread const float& denom)
{ {
float _761; float _762;
if (denom != 0.0) if (denom != 0.0)
{ {
_761 = num / denom; _762 = num / denom;
} }
else else
{ {
_761 = 0.0; _762 = 0.0;
} }
return _761; return _762;
} }
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
@ -398,25 +400,25 @@ float3 compositeRGBToHSL(thread const float3& rgb)
float xMin = fast::min(fast::min(rgb.x, rgb.y), rgb.z); float xMin = fast::min(fast::min(rgb.x, rgb.y), rgb.z);
float c = v - xMin; float c = v - xMin;
float l = mix(xMin, v, 0.5); float l = mix(xMin, v, 0.5);
float3 _867; float3 _868;
if (rgb.x == v) if (rgb.x == v)
{ {
_867 = float3(0.0, rgb.yz); _868 = float3(0.0, rgb.yz);
} }
else else
{ {
float3 _880; float3 _881;
if (rgb.y == v) if (rgb.y == v)
{ {
_880 = float3(2.0, rgb.zx); _881 = float3(2.0, rgb.zx);
} }
else else
{ {
_880 = float3(4.0, rgb.xy); _881 = float3(4.0, rgb.xy);
} }
_867 = _880; _868 = _881;
} }
float3 terms = _867; float3 terms = _868;
float param = ((terms.x * c) + terms.y) - terms.z; float param = ((terms.x * c) + terms.y) - terms.z;
float param_1 = c; float param_1 = c;
float h = 1.0471975803375244140625 * compositeDivide(param, param_1); float h = 1.0471975803375244140625 * compositeDivide(param, param_1);
@ -553,51 +555,52 @@ float4 composite(thread const float4& srcColor, thread const texture2d<float> de
} }
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d<float> uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d<float> uColorTexture0, thread const sampler uColorTexture0Smplr, thread texture2d<float> uGammaLUT, thread const sampler uGammaLUTSmplr, thread float2 uColorTexture0Size, thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread float4 uFilterParams0, thread float4 uFilterParams1, thread float4 uFilterParams2, thread texture2d<float> uDestTexture, thread const sampler uDestTextureSmplr, thread float4& oFragColor) void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d<float> uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread float2 uMaskTextureSize0, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d<float> uColorTexture0, thread const sampler uColorTexture0Smplr, thread texture2d<float> uGammaLUT, thread const sampler uGammaLUTSmplr, thread float2 uColorTextureSize0, thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread float4 uFilterParams0, thread float4 uFilterParams1, thread float4 uFilterParams2, thread texture2d<float> uDestTexture, thread const sampler uDestTextureSmplr, thread float4& oFragColor)
{ {
int maskCtrl0 = (tileCtrl >> 0) & 3; int maskCtrl0 = (tileCtrl >> 0) & 3;
float maskAlpha = 1.0; float maskAlpha = 1.0;
float param = maskAlpha; float param = maskAlpha;
float3 param_1 = vMaskTexCoord0; float2 param_1 = uMaskTextureSize0;
int param_2 = maskCtrl0; float3 param_2 = vMaskTexCoord0;
maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2); int param_3 = maskCtrl0;
maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2, param_3);
float4 color = vBaseColor; float4 color = vBaseColor;
int color0Combine = (ctrl >> 6) & 3; int color0Combine = (ctrl >> 6) & 3;
if (color0Combine != 0) if (color0Combine != 0)
{ {
int color0Filter = (ctrl >> 4) & 3; int color0Filter = (ctrl >> 4) & 3;
float2 param_3 = vColorTexCoord0; float2 param_4 = vColorTexCoord0;
float2 param_4 = uColorTexture0Size; float2 param_5 = uColorTextureSize0;
float2 param_5 = gl_FragCoord.xy; float2 param_6 = gl_FragCoord.xy;
float2 param_6 = uFramebufferSize; float2 param_7 = uFramebufferSize;
float4 param_7 = uFilterParams0; float4 param_8 = uFilterParams0;
float4 param_8 = uFilterParams1; float4 param_9 = uFilterParams1;
float4 param_9 = uFilterParams2; float4 param_10 = uFilterParams2;
int param_10 = color0Filter; int param_11 = color0Filter;
float4 color0 = filterColor(param_3, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, param_4, param_5, param_6, param_7, param_8, param_9, param_10); float4 color0 = filterColor(param_4, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, param_5, param_6, param_7, param_8, param_9, param_10, param_11);
float4 param_11 = color; float4 param_12 = color;
float4 param_12 = color0; float4 param_13 = color0;
int param_13 = color0Combine; int param_14 = color0Combine;
color = combineColor0(param_11, param_12, param_13); color = combineColor0(param_12, param_13, param_14);
} }
color.w *= maskAlpha; color.w *= maskAlpha;
int compositeOp = (ctrl >> 8) & 15; int compositeOp = (ctrl >> 8) & 15;
float4 param_14 = color; float4 param_15 = color;
float2 param_15 = uFramebufferSize; float2 param_16 = uFramebufferSize;
float2 param_16 = gl_FragCoord.xy; float2 param_17 = gl_FragCoord.xy;
int param_17 = compositeOp; int param_18 = compositeOp;
color = composite(param_14, uDestTexture, uDestTextureSmplr, param_15, param_16, param_17); color = composite(param_15, uDestTexture, uDestTextureSmplr, param_16, param_17, param_18);
float3 _1325 = color.xyz * color.w; float3 _1347 = color.xyz * color.w;
color = float4(_1325.x, _1325.y, _1325.z, color.w); color = float4(_1347.x, _1347.y, _1347.z, color.w);
oFragColor = color; oFragColor = color;
} }
fragment main0_out main0(main0_in in [[stage_in]], constant int& uCtrl [[buffer(5)]], constant float2& uColorTexture0Size [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]], constant float4& uFilterParams0 [[buffer(2)]], constant float4& uFilterParams1 [[buffer(3)]], constant float4& uFilterParams2 [[buffer(4)]], texture2d<float> uMaskTexture0 [[texture(0)]], texture2d<float> uColorTexture0 [[texture(1)]], texture2d<float> uGammaLUT [[texture(2)]], texture2d<float> uDestTexture [[texture(3)]], sampler uMaskTexture0Smplr [[sampler(0)]], sampler uColorTexture0Smplr [[sampler(1)]], sampler uGammaLUTSmplr [[sampler(2)]], sampler uDestTextureSmplr [[sampler(3)]], float4 gl_FragCoord [[position]]) fragment main0_out main0(main0_in in [[stage_in]], constant int& uCtrl [[buffer(6)]], constant float2& uMaskTextureSize0 [[buffer(0)]], constant float2& uColorTextureSize0 [[buffer(1)]], constant float2& uFramebufferSize [[buffer(2)]], constant float4& uFilterParams0 [[buffer(3)]], constant float4& uFilterParams1 [[buffer(4)]], constant float4& uFilterParams2 [[buffer(5)]], texture2d<float> uMaskTexture0 [[texture(0)]], texture2d<float> uColorTexture0 [[texture(1)]], texture2d<float> uGammaLUT [[texture(2)]], texture2d<float> uDestTexture [[texture(3)]], sampler uMaskTexture0Smplr [[sampler(0)]], sampler uColorTexture0Smplr [[sampler(1)]], sampler uGammaLUTSmplr [[sampler(2)]], sampler uDestTextureSmplr [[sampler(3)]], float4 gl_FragCoord [[position]])
{ {
main0_out out = {}; main0_out out = {};
int param = int(in.vTileCtrl); int param = int(in.vTileCtrl);
int param_1 = uCtrl; int param_1 = uCtrl;
calculateColor(param, param_1, uMaskTexture0, uMaskTexture0Smplr, in.vMaskTexCoord0, in.vBaseColor, in.vColorTexCoord0, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, uColorTexture0Size, gl_FragCoord, uFramebufferSize, uFilterParams0, uFilterParams1, uFilterParams2, uDestTexture, uDestTextureSmplr, out.oFragColor); calculateColor(param, param_1, uMaskTexture0, uMaskTexture0Smplr, uMaskTextureSize0, in.vMaskTexCoord0, in.vBaseColor, in.vColorTexCoord0, uColorTexture0, uColorTexture0Smplr, uGammaLUT, uGammaLUTSmplr, uColorTextureSize0, gl_FragCoord, uFramebufferSize, uFilterParams0, uFilterParams1, uFilterParams2, uDestTexture, uDestTextureSmplr, out.oFragColor);
return out; return out;
} }

View File

@ -29,7 +29,7 @@ vertex main0_out main0(main0_in in [[stage_in]], constant int2& uTextureMetadata
float2 tileOrigin = float2(in.aTileOrigin); float2 tileOrigin = float2(in.aTileOrigin);
float2 tileOffset = float2(in.aTileOffset); float2 tileOffset = float2(in.aTileOffset);
float2 position = (tileOrigin + tileOffset) * uTileSize; float2 position = (tileOrigin + tileOffset) * uTileSize;
float2 maskTexCoord0 = (float2(in.aMaskTexCoord0) + tileOffset) / float2(256.0); float2 maskTexCoord0 = (float2(in.aMaskTexCoord0) + tileOffset) * uTileSize;
float2 textureMetadataScale = float2(1.0) / float2(uTextureMetadataSize); float2 textureMetadataScale = float2(1.0) / float2(uTextureMetadataSize);
float2 metadataEntryCoord = float2(float((in.aColor % 128) * 4), float(in.aColor / 128)); float2 metadataEntryCoord = float2(float((in.aColor % 128) * 4), float(in.aColor / 128));
float2 colorTexMatrix0Coord = (metadataEntryCoord + float2(0.5)) * textureMetadataScale; float2 colorTexMatrix0Coord = (metadataEntryCoord + float2(0.5)) * textureMetadataScale;

View File

@ -18,8 +18,7 @@ struct main0_in
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]]) fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]])
{ {
main0_out out = {}; main0_out out = {};
float alpha = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord).x + in.vBackdrop), 0.0, 1.0); out.oFragColor = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord) + float4(in.vBackdrop)), float4(0.0), float4(1.0));
out.oFragColor = float4(alpha, 0.0, 0.0, 1.0);
return out; return out;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -17,7 +17,7 @@ precision highp sampler2D;
#include "fill.inc.glsl" #include "fill.inc.glsl"
layout(local_size_x = 16, local_size_y = 16) in; layout(local_size_x = 16, local_size_y = 4) in;
uniform writeonly image2D uDest; uniform writeonly image2D uDest;
uniform sampler2D uAreaLUT; uniform sampler2D uAreaLUT;
@ -36,18 +36,16 @@ layout(std430, binding = 2) buffer bFillTileMap {
}; };
void main() { void main() {
ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy); ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy) * ivec2(1, 4);
uint tileIndexOffset = gl_WorkGroupID.z; uint tileIndexOffset = gl_WorkGroupID.z;
uint tileIndex = tileIndexOffset + uint(uFirstTileIndex); uint tileIndex = tileIndexOffset + uint(uFirstTileIndex);
ivec2 tileOrigin = ivec2(tileIndex & 0xff, (tileIndex >> 8u) & 0xff) * 16;
ivec2 destCoord = tileOrigin + tileSubCoord;
int fillIndex = iFillTileMap[tileIndex]; int fillIndex = iFillTileMap[tileIndex];
if (fillIndex < 0) if (fillIndex < 0)
return; return;
float coverage = 0.0; vec4 coverages = vec4(0.0);
do { do {
uvec2 fill = iFills[fillIndex]; uvec2 fill = iFills[fillIndex];
vec2 from = vec2(fill.y & 0xf, (fill.y >> 4u) & 0xf) + vec2 from = vec2(fill.y & 0xf, (fill.y >> 4u) & 0xf) +
@ -55,13 +53,14 @@ void main() {
vec2 to = vec2((fill.y >> 8u) & 0xf, (fill.y >> 12u) & 0xf) + vec2 to = vec2((fill.y >> 8u) & 0xf, (fill.y >> 12u) & 0xf) +
vec2((fill.x >> 16u) & 0xff, (fill.x >> 24u) & 0xff) / 256.0; vec2((fill.x >> 16u) & 0xff, (fill.x >> 24u) & 0xff) / 256.0;
from -= vec2(tileSubCoord) + vec2(0.5); coverages += computeCoverage(from - (vec2(tileSubCoord) + vec2(0.5)),
to -= vec2(tileSubCoord) + vec2(0.5); to - (vec2(tileSubCoord) + vec2(0.5)),
uAreaLUT);
coverage += computeCoverage(from, to, uAreaLUT);
fillIndex = iNextFills[fillIndex]; fillIndex = iNextFills[fillIndex];
} while (fillIndex >= 0); } while (fillIndex >= 0);
imageStore(uDest, destCoord, vec4(coverage)); ivec2 tileOrigin = ivec2(tileIndex & 0xff, (tileIndex >> 8u) & 0xff) * ivec2(16, 4);
ivec2 destCoord = tileOrigin + ivec2(gl_LocalInvocationID.xy);
imageStore(uDest, destCoord, coverages);
} }

View File

@ -25,5 +25,5 @@ in vec2 vTo;
out vec4 oFragColor; out vec4 oFragColor;
void main() { void main() {
oFragColor = vec4(computeCoverage(vFrom, vTo, uAreaLUT)); oFragColor = computeCoverage(vFrom, vTo, uAreaLUT);
} }

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT) { vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT) {
// Determine winding, and sort into a consistent order so we only need to find one root below. // Determine winding, and sort into a consistent order so we only need to find one root below.
vec2 left = from.x < to.x ? from : to, right = from.x < to.x ? to : from; vec2 left = from.x < to.x ? from : to, right = from.x < to.x ? to : from;
@ -23,5 +23,5 @@ float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT) {
// Look up area under that line, and scale horizontally to the window size. // Look up area under that line, and scale horizontally to the window size.
float dX = window.x - window.y; float dX = window.x - window.y;
return texture(areaLUT, vec2(y + 8.0, abs(d * dX)) / 16.0).r * dX; return texture(areaLUT, vec2(y + 8.0, abs(d * dX)) / 16.0) * dX;
} }

View File

@ -29,7 +29,7 @@ out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset) * uTileSize; return vec2(tileOffset) * uTileSize * vec2(1.0, 0.25);
} }
void main() { void main() {
@ -47,9 +47,15 @@ void main() {
position.y = floor(min(from.y, to.y)); position.y = floor(min(from.y, to.y));
else else
position.y = uTileSize.y; position.y = uTileSize.y;
position.y = floor(position.y * 0.25);
vFrom = from - position; // Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will
vTo = to - position; // land the fragment halfway between the four-pixel strip, at pixel offset 2.0. But we want to
// do our coverage calculation on the center of the first pixel in the strip instead, at pixel
// offset 0.5. This adjustment of 1.5 accomplishes that.
vec2 offset = vec2(0.0, 1.5) - position * vec2(1.0, 4.0);
vFrom = from + offset;
vTo = to + offset;
vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0; vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0;
#ifdef PF_ORIGIN_UPPER_LEFT #ifdef PF_ORIGIN_UPPER_LEFT

View File

@ -82,11 +82,12 @@ uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0; uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture; uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT; uniform sampler2D uGammaLUT;
uniform vec2 uColorTextureSize0;
uniform vec2 uMaskTextureSize0;
uniform vec4 uFilterParams0; uniform vec4 uFilterParams0;
uniform vec4 uFilterParams1; uniform vec4 uFilterParams1;
uniform vec4 uFilterParams2; uniform vec4 uFilterParams2;
uniform vec2 uFramebufferSize; uniform vec2 uFramebufferSize;
uniform vec2 uColorTexture0Size;
uniform int uCtrl; uniform int uCtrl;
in vec3 vMaskTexCoord0; in vec3 vMaskTexCoord0;
@ -542,11 +543,16 @@ vec4 composite(vec4 srcColor,
float sampleMask(float maskAlpha, float sampleMask(float maskAlpha,
sampler2D maskTexture, sampler2D maskTexture,
vec2 maskTextureSize,
vec3 maskTexCoord, vec3 maskTexCoord,
int maskCtrl) { int maskCtrl) {
if (maskCtrl == 0) if (maskCtrl == 0)
return maskAlpha; return maskAlpha;
float coverage = texture(maskTexture, maskTexCoord.xy).r + maskTexCoord.z;
ivec2 maskTexCoordI = ivec2(floor(maskTexCoord.xy));
vec4 texel = texture(maskTexture, (vec2(maskTexCoordI / ivec2(1, 4)) + 0.5) / maskTextureSize);
float coverage = texel[maskTexCoordI.y % 4] + maskTexCoord.z;
if ((maskCtrl & TILE_CTRL_MASK_WINDING) != 0) if ((maskCtrl & TILE_CTRL_MASK_WINDING) != 0)
coverage = abs(coverage); coverage = abs(coverage);
else else
@ -560,7 +566,7 @@ void calculateColor(int tileCtrl, int ctrl) {
// Sample mask. // Sample mask.
int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK; int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK;
float maskAlpha = 1.0; float maskAlpha = 1.0;
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, vMaskTexCoord0, maskCtrl0); maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
// Sample color. // Sample color.
vec4 color = vBaseColor; vec4 color = vBaseColor;
@ -571,7 +577,7 @@ void calculateColor(int tileCtrl, int ctrl) {
vec4 color0 = filterColor(vColorTexCoord0, vec4 color0 = filterColor(vColorTexCoord0,
uColorTexture0, uColorTexture0,
uGammaLUT, uGammaLUT,
uColorTexture0Size, uColorTextureSize0,
gl_FragCoord.xy, gl_FragCoord.xy,
uFramebufferSize, uFramebufferSize,
uFilterParams0, uFilterParams0,

View File

@ -34,7 +34,7 @@ void main() {
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position = (tileOrigin + tileOffset) * uTileSize; vec2 position = (tileOrigin + tileOffset) * uTileSize;
vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) / 256.0; vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * uTileSize;
vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize); vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);

View File

@ -21,6 +21,5 @@ in float vBackdrop;
out vec4 oFragColor; out vec4 oFragColor;
void main() { void main() {
float alpha = clamp(abs(texture(uSrc, vTexCoord).r + vBackdrop), 0.0, 1.0); oFragColor = clamp(abs(texture(uSrc, vTexCoord) + vBackdrop), 0.0, 1.0);
oFragColor = vec4(alpha, 0.0, 0.0, 1.0);
} }

View File

@ -21,8 +21,8 @@ use pathfinder_color::ColorU;
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i}; use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i};
use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device}; use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device};
use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, UniformData}; use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, TextureFormat};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use pathfinder_simd::default::F32x4; use pathfinder_simd::default::F32x4;
use serde_json; use serde_json;
@ -91,10 +91,15 @@ impl<D> UIPresenter<D> where D: Device {
let solid_program = DebugSolidProgram::new(device, resources); let solid_program = DebugSolidProgram::new(device, resources);
let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program); let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program);
let font_texture = device.create_texture_from_png(resources, FONT_PNG_NAME); let font_texture = device.create_texture_from_png(resources,
let corner_fill_texture = device.create_texture_from_png(resources, CORNER_FILL_PNG_NAME); FONT_PNG_NAME,
TextureFormat::R8);
let corner_fill_texture = device.create_texture_from_png(resources,
CORNER_FILL_PNG_NAME,
TextureFormat::R8);
let corner_outline_texture = device.create_texture_from_png(resources, let corner_outline_texture = device.create_texture_from_png(resources,
CORNER_OUTLINE_PNG_NAME); CORNER_OUTLINE_PNG_NAME,
TextureFormat::R8);
UIPresenter { UIPresenter {
event_queue: UIEventQueue::new(), event_queue: UIEventQueue::new(),

View File

@ -6,7 +6,7 @@ extern crate image;
use clap::{App, Arg}; use clap::{App, Arg};
use euclid::default::Point2D; use euclid::default::Point2D;
use image::{ImageBuffer, Luma}; use image::{ImageBuffer, Rgba};
use std::f32; use std::f32;
use std::path::Path; use std::path::Path;
@ -26,6 +26,44 @@ fn area_rect(p0: Point2D<f32>, p1: Point2D<f32>) -> f32 {
(p1.x - p0.x) * (p0.y - p1.y) (p1.x - p0.x) * (p0.y - p1.y)
} }
fn area(y: f32, dydx: f32) -> f32 {
let (x_left, x_right) = (-0.5, 0.5);
let (y_left, y_right) = (dydx * x_left + y, dydx * x_right + y);
let (p0, p1) = (Point2D::new(x_left, y_left), Point2D::new(x_right, y_right));
let p2 = solve_line_y(&p0, &p1, -0.5);
let p3 = Point2D::new(p1.x, -0.5);
let p4 = solve_line_y(&p0, &p1, 0.5);
let p7 = Point2D::new(p1.x, 0.5);
let alpha;
if p0.y > 0.5 {
if p1.y < -0.5 {
// Case 0
alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7) + area_tri(p0, p4);
} else if p1.y < 0.5 {
// Case 6
alpha = area_tri(p0, p1) - area_rect(p0, p7) + area_tri(p0, p4);
} else {
// Case 3
alpha = 0.0;
}
} else if p0.y > -0.5 {
if p1.y < -0.5 {
// Case 1
alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7);
} else {
// Case 4
alpha = area_tri(p0, p1) - area_rect(p0, p7);
}
} else {
// Case 2
alpha = -area_rect(p0, p7) + area_rect(p0, p3);
}
alpha
}
fn main() { fn main() {
let app = App::new("Pathfinder Area LUT Generator") let app = App::new("Pathfinder Area LUT Generator")
.version("0.1") .version("0.1")
@ -38,50 +76,23 @@ fn main() {
let matches = app.get_matches(); let matches = app.get_matches();
let image = ImageBuffer::from_fn(WIDTH, HEIGHT, |u, v| { let image = ImageBuffer::from_fn(WIDTH, HEIGHT, |u, v| {
if u == 0 { if u == 0 {
return Luma([255]) return Rgba([255, 255, 255, 255])
} }
if u == WIDTH - 1 { if u == WIDTH - 1 {
return Luma([0]) return Rgba([0, 0, 0, 0])
} }
let y = ((u as f32) - (WIDTH / 2) as f32) / 16.0; let y = ((u as f32) - (WIDTH / 2) as f32) / 16.0;
let dydx = -(v as f32) / 16.0; let dydx = -(v as f32) / 16.0;
let (x_left, x_right) = (-0.5, 0.5); let alphas = [
let (y_left, y_right) = (dydx * x_left + y, dydx * x_right + y); (area(y - 0.0, dydx) * 255.0).round() as u8,
(area(y - 1.0, dydx) * 255.0).round() as u8,
(area(y - 2.0, dydx) * 255.0).round() as u8,
(area(y - 3.0, dydx) * 255.0).round() as u8,
];
let (p0, p1) = (Point2D::new(x_left, y_left), Point2D::new(x_right, y_right)); Rgba([alphas[0], alphas[1], alphas[2], alphas[3]])
let p2 = solve_line_y(&p0, &p1, -0.5);
let p3 = Point2D::new(p1.x, -0.5);
let p4 = solve_line_y(&p0, &p1, 0.5);
let p7 = Point2D::new(p1.x, 0.5);
let alpha;
if p0.y > 0.5 {
if p1.y < -0.5 {
// Case 0
alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7) + area_tri(p0, p4);
} else if p1.y < 0.5 {
// Case 6
alpha = area_tri(p0, p1) - area_rect(p0, p7) + area_tri(p0, p4);
} else {
// Case 3
alpha = 0.0;
}
} else if p0.y > -0.5 {
if p1.y < -0.5 {
// Case 1
alpha = area_tri(p0, p1) - area_tri(p2, p1) - area_rect(p0, p7);
} else {
// Case 4
alpha = area_tri(p0, p1) - area_rect(p0, p7);
}
} else {
// Case 2
alpha = -area_rect(p0, p7) + area_rect(p0, p3);
}
Luma([f32::round(alpha * 255.0) as u8])
}); });
let output_path = matches.value_of("OUTPUT-PATH").unwrap(); let output_path = matches.value_of("OUTPUT-PATH").unwrap();