diff --git a/demo/common/src/ui.rs b/demo/common/src/ui.rs index 8538e2b9..2c29d9e2 100644 --- a/demo/common/src/ui.rs +++ b/demo/common/src/ui.rs @@ -14,7 +14,7 @@ use crate::{BackgroundColor, Options}; use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::vector::{Vector2I, vec2i}; -use pathfinder_gpu::Device; +use pathfinder_gpu::{Device, TextureFormat}; use pathfinder_renderer::gpu::debug::DebugUIPresenter; use pathfinder_resources::ResourceLoader; use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING}; @@ -121,15 +121,30 @@ where D: Device, { pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter { - let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME); - let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME); - let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME); - let zoom_in_texture = device.create_texture_from_png(resources, ZOOM_IN_PNG_NAME); + let effects_texture = device.create_texture_from_png(resources, + EFFECTS_PNG_NAME, + TextureFormat::R8); + 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, - ZOOM_ACTUAL_SIZE_PNG_NAME); - let zoom_out_texture = device.create_texture_from_png(resources, ZOOM_OUT_PNG_NAME); - let background_texture = device.create_texture_from_png(resources, BACKGROUND_PNG_NAME); - let screenshot_texture = device.create_texture_from_png(resources, SCREENSHOT_PNG_NAME); + ZOOM_ACTUAL_SIZE_PNG_NAME, + TextureFormat::R8); + 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, + TextureFormat::R8); + let screenshot_texture = device.create_texture_from_png(resources, + SCREENSHOT_PNG_NAME, + TextureFormat::R8); DemoUIPresenter { effects_texture, diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 47009731..bc578620 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -104,13 +104,26 @@ pub trait Device: Sized { fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option; 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 image = image::load_from_memory_with_format(&data, ImageFormat::Png) - .unwrap() - .to_luma(); - let size = vec2i(image.width() as i32, image.height() as i32); - self.create_texture_from_data(TextureFormat::R8, size, TextureDataRef::U8(&image)) + let image = image::load_from_memory_with_format(&data, ImageFormat::Png).unwrap(); + match format { + TextureFormat::R8 => { + let image = image.to_luma(); + 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( diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 15b20cdf..a96a6767 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -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; // FIXME(pcwalton): Shrink this again! -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_WIDTH: i32 = TILE_WIDTH as i32 * MASK_TILES_ACROSS 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_DEST_IN: i32 = 0x2; @@ -170,8 +170,10 @@ impl Renderer where D: Device { let stencil_program = StencilProgram::new(&device, resources); let reprojection_program = ReprojectionProgram::new(&device, resources); - let area_lut_texture = device.create_texture_from_png(resources, "area-lut"); - let gamma_lut_texture = device.create_texture_from_png(resources, "gamma-lut"); + let area_lut_texture = + 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); device.allocate_buffer(&quad_vertex_positions_buffer, @@ -906,7 +908,10 @@ impl Renderer where D: Device { if let Some(alpha_tile_page) = self.back_frame.alpha_tile_pages.get(&tile_page) { 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)); } @@ -919,16 +924,16 @@ impl Renderer where D: Device { self.device.set_texture_sampling_mode(color_texture_page, color_texture.sampling_flags); uniforms.push((&self.tile_program.color_texture_0_uniform, - UniformData::TextureUnit(textures.len() as u32))); - uniforms.push((&self.tile_program.color_texture_0_size_uniform, - UniformData::Vec2(color_texture_size.0))); + UniformData::TextureUnit(textures.len() as u32))); + uniforms.push((&self.tile_program.color_texture_size_0_uniform, + UniformData::Vec2(color_texture_size.0))); textures.push(color_texture_page); ctrl |= color_texture.composite_op.to_combine_mode() << COMBINER_CTRL_COLOR_COMBINE_SHIFT; } 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()))); } } @@ -1913,7 +1918,7 @@ struct AlphaTilePage where D: Device { impl AlphaTilePage where D: Device { fn new(device: &mut D) -> AlphaTilePage { 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); AlphaTilePage { buffered_fills: vec![], diff --git a/renderer/src/gpu/shaders.rs b/renderer/src/gpu/shaders.rs index 56005758..4b34186b 100644 --- a/renderer/src/gpu/shaders.rs +++ b/renderer/src/gpu/shaders.rs @@ -388,7 +388,7 @@ pub struct FillComputeProgram where D: Device { impl FillComputeProgram where D: Device { pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram { 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); let dest_uniform = device.get_uniform(&program, "Dest"); @@ -418,10 +418,11 @@ pub struct TileProgram where D: Device { pub texture_metadata_size_uniform: D::Uniform, pub dest_texture_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 mask_texture_0_uniform: D::Uniform, + pub mask_texture_size_0_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_1_uniform: D::Uniform, pub filter_params_2_uniform: D::Uniform, @@ -438,10 +439,11 @@ impl TileProgram where D: Device { let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize"); let dest_texture_uniform = device.get_uniform(&program, "DestTexture"); 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 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 color_texture_0_size_uniform = device.get_uniform(&program, "ColorTexture0Size"); let filter_params_0_uniform = device.get_uniform(&program, "FilterParams0"); let filter_params_1_uniform = device.get_uniform(&program, "FilterParams1"); let filter_params_2_uniform = device.get_uniform(&program, "FilterParams2"); @@ -455,10 +457,11 @@ impl TileProgram where D: Device { texture_metadata_size_uniform, dest_texture_uniform, color_texture_0_uniform, + color_texture_size_0_uniform, color_texture_1_uniform, mask_texture_0_uniform, + mask_texture_size_0_uniform, gamma_lut_uniform, - color_texture_0_size_uniform, filter_params_0_uniform, filter_params_1_uniform, filter_params_2_uniform, diff --git a/resources/shaders/gl3/fill.fs.glsl b/resources/shaders/gl3/fill.fs.glsl index 09a8069b..7541b242 100644 --- a/resources/shaders/gl3/fill.fs.glsl +++ b/resources/shaders/gl3/fill.fs.glsl @@ -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; @@ -43,7 +43,7 @@ float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){ 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; void main(){ - oFragColor = vec4(computeCoverage(vFrom, vTo, uAreaLUT)); + oFragColor = computeCoverage(vFrom, vTo, uAreaLUT); } diff --git a/resources/shaders/gl3/fill.vs.glsl b/resources/shaders/gl3/fill.vs.glsl index 06970424..6f530e42 100644 --- a/resources/shaders/gl3/fill.vs.glsl +++ b/resources/shaders/gl3/fill.vs.glsl @@ -31,7 +31,7 @@ out vec2 vTo; vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){ uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset)* uTileSize; + return vec2(tileOffset)* uTileSize * vec2(1.0, 0.25); } void main(){ @@ -49,9 +49,15 @@ void main(){ position . y = floor(min(from . y, to . y)); else 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; diff --git a/resources/shaders/gl3/tile.fs.glsl b/resources/shaders/gl3/tile.fs.glsl index 7b9f0ac4..9cd13cf7 100644 --- a/resources/shaders/gl3/tile.fs.glsl +++ b/resources/shaders/gl3/tile.fs.glsl @@ -84,11 +84,12 @@ uniform sampler2D uColorTexture0; uniform sampler2D uMaskTexture0; uniform sampler2D uDestTexture; uniform sampler2D uGammaLUT; +uniform vec2 uColorTextureSize0; +uniform vec2 uMaskTextureSize0; uniform vec4 uFilterParams0; uniform vec4 uFilterParams1; uniform vec4 uFilterParams2; uniform vec2 uFramebufferSize; -uniform vec2 uColorTexture0Size; uniform int uCtrl; in vec3 vMaskTexCoord0; @@ -544,11 +545,16 @@ vec4 composite(vec4 srcColor, float sampleMask(float maskAlpha, sampler2D maskTexture, + vec2 maskTextureSize, vec3 maskTexCoord, int maskCtrl){ if(maskCtrl == 0) 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) coverage = abs(coverage); else @@ -562,7 +568,7 @@ void calculateColor(int tileCtrl, int ctrl){ int maskCtrl0 =(tileCtrl >> 0)& 0x3; float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, vMaskTexCoord0, maskCtrl0); + maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0); vec4 color = vBaseColor; @@ -573,7 +579,7 @@ void calculateColor(int tileCtrl, int ctrl){ vec4 color0 = filterColor(vColorTexCoord0, uColorTexture0, uGammaLUT, - uColorTexture0Size, + uColorTextureSize0, gl_FragCoord . xy, uFramebufferSize, uFilterParams0, diff --git a/resources/shaders/gl3/tile.vs.glsl b/resources/shaders/gl3/tile.vs.glsl index f385d7a3..029f364c 100644 --- a/resources/shaders/gl3/tile.vs.glsl +++ b/resources/shaders/gl3/tile.vs.glsl @@ -36,7 +36,7 @@ void main(){ vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); 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 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); diff --git a/resources/shaders/gl3/tile_clip.fs.glsl b/resources/shaders/gl3/tile_clip.fs.glsl index 56ae412c..93ffe55e 100644 --- a/resources/shaders/gl3/tile_clip.fs.glsl +++ b/resources/shaders/gl3/tile_clip.fs.glsl @@ -23,7 +23,6 @@ in float vBackdrop; out vec4 oFragColor; void main(){ - float alpha = clamp(abs(texture(uSrc, vTexCoord). r + vBackdrop), 0.0, 1.0); - oFragColor = vec4(alpha, 0.0, 0.0, 1.0); + oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0); } diff --git a/resources/shaders/metal/fill.cs.metal b/resources/shaders/metal/fill.cs.metal index e7b20b48..b1ad19ce 100644 --- a/resources/shaders/metal/fill.cs.metal +++ b/resources/shaders/metal/fill.cs.metal @@ -21,10 +21,10 @@ struct bNextFills 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)) -float computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSmplr) +float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSmplr) { float2 left = select(to, from, 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 d = (right.y - left.y) / (right.x - left.x); 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 uAreaLUT [[texture(0)]], texture2d 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 uAreaLUT [[texture(0)]], texture2d 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 tileIndex = tileIndexOffset + uint(uFirstTileIndex); - int2 tileOrigin = int2(int(tileIndex & 255u), int((tileIndex >> 8u) & 255u)) * int2(16); - int2 destCoord = tileOrigin + tileSubCoord; - int fillIndex = _165.iFillTileMap[tileIndex]; + int fillIndex = _150.iFillTileMap[tileIndex]; if (fillIndex < 0) { return; } - float coverage = 0.0; + float4 coverages = float4(0.0); 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 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)); - to -= (float2(tileSubCoord) + float2(0.5)); - float2 param = from; - float2 param_1 = to; - coverage += computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr); - fillIndex = _269.iNextFills[fillIndex]; + float2 param = from - (float2(tileSubCoord) + float2(0.5)); + float2 param_1 = to - (float2(tileSubCoord) + float2(0.5)); + coverages += computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr); + fillIndex = _256.iNextFills[fillIndex]; } 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)); } diff --git a/resources/shaders/metal/fill.fs.metal b/resources/shaders/metal/fill.fs.metal index 28fd8afa..77892f26 100644 --- a/resources/shaders/metal/fill.fs.metal +++ b/resources/shaders/metal/fill.fs.metal @@ -18,7 +18,7 @@ struct main0_in }; static inline __attribute__((always_inline)) -float computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSmplr) +float4 computeCoverage(thread const float2& from, thread const float2& to, thread const texture2d areaLUT, thread const sampler areaLUTSmplr) { float2 left = select(to, from, 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 d = (right.y - left.y) / (right.x - left.x); 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 uAreaLUT [[texture(0)]], sampler uAreaLUTSmplr [[sampler(0)]]) @@ -36,7 +36,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d uAreaLUT [[t main0_out out = {}; float2 param = in.vFrom; float2 param_1 = in.vTo; - out.oFragColor = float4(computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr)); + out.oFragColor = computeCoverage(param, param_1, uAreaLUT, uAreaLUTSmplr); return out; } diff --git a/resources/shaders/metal/fill.vs.metal b/resources/shaders/metal/fill.vs.metal index 13c7b2d9..a8cf9a86 100644 --- a/resources/shaders/metal/fill.vs.metal +++ b/resources/shaders/metal/fill.vs.metal @@ -28,7 +28,7 @@ float2 computeTileOffset(thread const uint& tileIndex, thread const float& stenc { uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); 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)]]) @@ -56,8 +56,10 @@ vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[bu { position.y = uTileSize.y; } - out.vFrom = from - position; - out.vTo = to - position; + position.y = floor(position.y * 0.25); + 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); globalPosition.y = -globalPosition.y; out.gl_Position = float4(globalPosition, 0.0, 1.0); diff --git a/resources/shaders/metal/tile.fs.metal b/resources/shaders/metal/tile.fs.metal index fcb15dd7..1b2c7e9d 100644 --- a/resources/shaders/metal/tile.fs.metal +++ b/resources/shaders/metal/tile.fs.metal @@ -6,7 +6,7 @@ using namespace metal; -constant float3 _1041 = {}; +constant float3 _1042 = {}; struct main0_out { @@ -29,13 +29,15 @@ inline Tx mod(Tx x, Ty y) } static inline __attribute__((always_inline)) -float sampleMask(thread const float& maskAlpha, thread const texture2d maskTexture, thread const sampler maskTextureSmplr, thread const float3& maskTexCoord, thread const int& maskCtrl) +float sampleMask(thread const float& maskAlpha, thread const texture2d maskTexture, thread const sampler maskTextureSmplr, thread const float2& maskTextureSize, thread const float3& maskTexCoord, thread const int& maskCtrl) { if (maskCtrl == 0) { 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) { coverage = abs(coverage); @@ -69,16 +71,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex { ts = ts.yx; } - float _554; + float _555; if (ts.x >= 0.0) { - _554 = ts.x; + _555 = ts.x; } 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))); } return color; @@ -92,19 +94,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel) { bool wide = kernel0.x > 0.0; - float _235; + float _236; if (wide) { float param = (-4.0) * onePixel; float2 param_1 = colorTexCoord; - _235 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); + _236 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1); } else { - _235 = 0.0; + _236 = 0.0; } float param_2 = (-3.0) * onePixel; float2 param_3 = colorTexCoord; @@ -136,7 +138,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_5 = colorTexCoord; float param_6 = (-1.0) * onePixel; 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; float2 param_9 = colorTexCoord; outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9); @@ -146,18 +148,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen float2 param_13 = colorTexCoord; float param_14 = 3.0 * onePixel; float2 param_15 = colorTexCoord; - float _295; + float _296; if (wide) { float param_16 = 4.0 * onePixel; float2 param_17 = colorTexCoord; - _295 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); + _296 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17); } 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)) @@ -307,34 +309,34 @@ float3 compositeScreen(thread const float3& destColor, thread const float3& srcC static inline __attribute__((always_inline)) float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse) { - float _725; + float _726; if (cond.x) { - _725 = ifTrue.x; + _726 = ifTrue.x; } else { - _725 = ifFalse.x; + _726 = ifFalse.x; } - float _736; + float _737; if (cond.y) { - _736 = ifTrue.y; + _737 = ifTrue.y; } else { - _736 = ifFalse.y; + _737 = ifFalse.y; } - float _747; + float _748; if (cond.z) { - _747 = ifTrue.z; + _748 = ifTrue.z; } else { - _747 = ifFalse.z; + _748 = ifFalse.z; } - return float3(_725, _736, _747); + return float3(_726, _737, _748); } static inline __attribute__((always_inline)) @@ -379,16 +381,16 @@ float3 compositeSoftLight(thread const float3& destColor, thread const float3& s static inline __attribute__((always_inline)) float compositeDivide(thread const float& num, thread const float& denom) { - float _761; + float _762; if (denom != 0.0) { - _761 = num / denom; + _762 = num / denom; } else { - _761 = 0.0; + _762 = 0.0; } - return _761; + return _762; } 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 c = v - xMin; float l = mix(xMin, v, 0.5); - float3 _867; + float3 _868; if (rgb.x == v) { - _867 = float3(0.0, rgb.yz); + _868 = float3(0.0, rgb.yz); } else { - float3 _880; + float3 _881; if (rgb.y == v) { - _880 = float3(2.0, rgb.zx); + _881 = float3(2.0, rgb.zx); } 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_1 = c; float h = 1.0471975803375244140625 * compositeDivide(param, param_1); @@ -553,51 +555,52 @@ float4 composite(thread const float4& srcColor, thread const texture2d de } static inline __attribute__((always_inline)) -void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d uColorTexture0, thread const sampler uColorTexture0Smplr, thread texture2d 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 uDestTexture, thread const sampler uDestTextureSmplr, thread float4& oFragColor) +void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread float2 uMaskTextureSize0, thread float3& vMaskTexCoord0, thread float4& vBaseColor, thread float2& vColorTexCoord0, thread texture2d uColorTexture0, thread const sampler uColorTexture0Smplr, thread texture2d 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 uDestTexture, thread const sampler uDestTextureSmplr, thread float4& oFragColor) { int maskCtrl0 = (tileCtrl >> 0) & 3; float maskAlpha = 1.0; float param = maskAlpha; - float3 param_1 = vMaskTexCoord0; - int param_2 = maskCtrl0; - maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2); + float2 param_1 = uMaskTextureSize0; + float3 param_2 = vMaskTexCoord0; + int param_3 = maskCtrl0; + maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2, param_3); float4 color = vBaseColor; int color0Combine = (ctrl >> 6) & 3; if (color0Combine != 0) { int color0Filter = (ctrl >> 4) & 3; - float2 param_3 = vColorTexCoord0; - float2 param_4 = uColorTexture0Size; - float2 param_5 = gl_FragCoord.xy; - float2 param_6 = uFramebufferSize; - float4 param_7 = uFilterParams0; - float4 param_8 = uFilterParams1; - float4 param_9 = uFilterParams2; - int param_10 = 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 param_11 = color; - float4 param_12 = color0; - int param_13 = color0Combine; - color = combineColor0(param_11, param_12, param_13); + float2 param_4 = vColorTexCoord0; + float2 param_5 = uColorTextureSize0; + float2 param_6 = gl_FragCoord.xy; + float2 param_7 = uFramebufferSize; + float4 param_8 = uFilterParams0; + float4 param_9 = uFilterParams1; + float4 param_10 = uFilterParams2; + int param_11 = color0Filter; + 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_12 = color; + float4 param_13 = color0; + int param_14 = color0Combine; + color = combineColor0(param_12, param_13, param_14); } color.w *= maskAlpha; int compositeOp = (ctrl >> 8) & 15; - float4 param_14 = color; - float2 param_15 = uFramebufferSize; - float2 param_16 = gl_FragCoord.xy; - int param_17 = compositeOp; - color = composite(param_14, uDestTexture, uDestTextureSmplr, param_15, param_16, param_17); - float3 _1325 = color.xyz * color.w; - color = float4(_1325.x, _1325.y, _1325.z, color.w); + float4 param_15 = color; + float2 param_16 = uFramebufferSize; + float2 param_17 = gl_FragCoord.xy; + int param_18 = compositeOp; + color = composite(param_15, uDestTexture, uDestTextureSmplr, param_16, param_17, param_18); + float3 _1347 = color.xyz * color.w; + color = float4(_1347.x, _1347.y, _1347.z, color.w); 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 uMaskTexture0 [[texture(0)]], texture2d uColorTexture0 [[texture(1)]], texture2d uGammaLUT [[texture(2)]], texture2d 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 uMaskTexture0 [[texture(0)]], texture2d uColorTexture0 [[texture(1)]], texture2d uGammaLUT [[texture(2)]], texture2d 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 = {}; int param = int(in.vTileCtrl); 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; } diff --git a/resources/shaders/metal/tile.vs.metal b/resources/shaders/metal/tile.vs.metal index f05bf6ae..6b297b65 100644 --- a/resources/shaders/metal/tile.vs.metal +++ b/resources/shaders/metal/tile.vs.metal @@ -29,7 +29,7 @@ vertex main0_out main0(main0_in in [[stage_in]], constant int2& uTextureMetadata float2 tileOrigin = float2(in.aTileOrigin); float2 tileOffset = float2(in.aTileOffset); 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 metadataEntryCoord = float2(float((in.aColor % 128) * 4), float(in.aColor / 128)); float2 colorTexMatrix0Coord = (metadataEntryCoord + float2(0.5)) * textureMetadataScale; diff --git a/resources/shaders/metal/tile_clip.fs.metal b/resources/shaders/metal/tile_clip.fs.metal index f35707f0..de4bf10a 100644 --- a/resources/shaders/metal/tile_clip.fs.metal +++ b/resources/shaders/metal/tile_clip.fs.metal @@ -18,8 +18,7 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], texture2d uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]]) { main0_out out = {}; - float alpha = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord).x + in.vBackdrop), 0.0, 1.0); - out.oFragColor = float4(alpha, 0.0, 0.0, 1.0); + out.oFragColor = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord) + float4(in.vBackdrop)), float4(0.0), float4(1.0)); return out; } diff --git a/resources/textures/area-lut.png b/resources/textures/area-lut.png index a576cc57..19b31cbf 100644 Binary files a/resources/textures/area-lut.png and b/resources/textures/area-lut.png differ diff --git a/shaders/fill.cs.glsl b/shaders/fill.cs.glsl index 93bdcecb..71a4beff 100644 --- a/shaders/fill.cs.glsl +++ b/shaders/fill.cs.glsl @@ -17,7 +17,7 @@ precision highp sampler2D; #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 sampler2D uAreaLUT; @@ -36,18 +36,16 @@ layout(std430, binding = 2) buffer bFillTileMap { }; void main() { - ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy); + ivec2 tileSubCoord = ivec2(gl_LocalInvocationID.xy) * ivec2(1, 4); uint tileIndexOffset = gl_WorkGroupID.z; uint tileIndex = tileIndexOffset + uint(uFirstTileIndex); - ivec2 tileOrigin = ivec2(tileIndex & 0xff, (tileIndex >> 8u) & 0xff) * 16; - ivec2 destCoord = tileOrigin + tileSubCoord; int fillIndex = iFillTileMap[tileIndex]; if (fillIndex < 0) return; - float coverage = 0.0; + vec4 coverages = vec4(0.0); do { uvec2 fill = iFills[fillIndex]; 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((fill.x >> 16u) & 0xff, (fill.x >> 24u) & 0xff) / 256.0; - from -= vec2(tileSubCoord) + vec2(0.5); - to -= vec2(tileSubCoord) + vec2(0.5); - - coverage += computeCoverage(from, to, uAreaLUT); + coverages += computeCoverage(from - (vec2(tileSubCoord) + vec2(0.5)), + to - (vec2(tileSubCoord) + vec2(0.5)), + uAreaLUT); fillIndex = iNextFills[fillIndex]; } 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); } diff --git a/shaders/fill.fs.glsl b/shaders/fill.fs.glsl index 89da3e01..0848eb48 100644 --- a/shaders/fill.fs.glsl +++ b/shaders/fill.fs.glsl @@ -25,5 +25,5 @@ in vec2 vTo; out vec4 oFragColor; void main() { - oFragColor = vec4(computeCoverage(vFrom, vTo, uAreaLUT)); + oFragColor = computeCoverage(vFrom, vTo, uAreaLUT); } diff --git a/shaders/fill.inc.glsl b/shaders/fill.inc.glsl index 356248f1..c22125ae 100644 --- a/shaders/fill.inc.glsl +++ b/shaders/fill.inc.glsl @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // 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. 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. 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; } diff --git a/shaders/fill.vs.glsl b/shaders/fill.vs.glsl index 20d04463..a8bc1acd 100644 --- a/shaders/fill.vs.glsl +++ b/shaders/fill.vs.glsl @@ -29,7 +29,7 @@ out vec2 vTo; vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow); - return vec2(tileOffset) * uTileSize; + return vec2(tileOffset) * uTileSize * vec2(1.0, 0.25); } void main() { @@ -47,9 +47,15 @@ void main() { position.y = floor(min(from.y, to.y)); else position.y = uTileSize.y; + position.y = floor(position.y * 0.25); - vFrom = from - position; - vTo = to - position; + // Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will + // 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; #ifdef PF_ORIGIN_UPPER_LEFT diff --git a/shaders/tile.fs.glsl b/shaders/tile.fs.glsl index 862e8c60..3e137abd 100644 --- a/shaders/tile.fs.glsl +++ b/shaders/tile.fs.glsl @@ -82,11 +82,12 @@ uniform sampler2D uColorTexture0; uniform sampler2D uMaskTexture0; uniform sampler2D uDestTexture; uniform sampler2D uGammaLUT; +uniform vec2 uColorTextureSize0; +uniform vec2 uMaskTextureSize0; uniform vec4 uFilterParams0; uniform vec4 uFilterParams1; uniform vec4 uFilterParams2; uniform vec2 uFramebufferSize; -uniform vec2 uColorTexture0Size; uniform int uCtrl; in vec3 vMaskTexCoord0; @@ -542,11 +543,16 @@ vec4 composite(vec4 srcColor, float sampleMask(float maskAlpha, sampler2D maskTexture, + vec2 maskTextureSize, vec3 maskTexCoord, int maskCtrl) { if (maskCtrl == 0) 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) coverage = abs(coverage); else @@ -560,7 +566,7 @@ void calculateColor(int tileCtrl, int ctrl) { // Sample mask. int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK; float maskAlpha = 1.0; - maskAlpha = sampleMask(maskAlpha, uMaskTexture0, vMaskTexCoord0, maskCtrl0); + maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0); // Sample color. vec4 color = vBaseColor; @@ -571,7 +577,7 @@ void calculateColor(int tileCtrl, int ctrl) { vec4 color0 = filterColor(vColorTexCoord0, uColorTexture0, uGammaLUT, - uColorTexture0Size, + uColorTextureSize0, gl_FragCoord.xy, uFramebufferSize, uFilterParams0, diff --git a/shaders/tile.vs.glsl b/shaders/tile.vs.glsl index fc21ba44..9c38aded 100644 --- a/shaders/tile.vs.glsl +++ b/shaders/tile.vs.glsl @@ -34,7 +34,7 @@ void main() { vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset); 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 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128); diff --git a/shaders/tile_clip.fs.glsl b/shaders/tile_clip.fs.glsl index 3d6d02f9..4c10f65d 100644 --- a/shaders/tile_clip.fs.glsl +++ b/shaders/tile_clip.fs.glsl @@ -21,6 +21,5 @@ in float vBackdrop; out vec4 oFragColor; void main() { - float alpha = clamp(abs(texture(uSrc, vTexCoord).r + vBackdrop), 0.0, 1.0); - oFragColor = vec4(alpha, 0.0, 0.0, 1.0); + oFragColor = clamp(abs(texture(uSrc, vTexCoord) + vBackdrop), 0.0, 1.0); } diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 35322543..237092cf 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -21,8 +21,8 @@ use pathfinder_color::ColorU; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i}; use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device}; -use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, UniformData}; -use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; +use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, TextureFormat}; +use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType}; use pathfinder_resources::ResourceLoader; use pathfinder_simd::default::F32x4; use serde_json; @@ -91,10 +91,15 @@ impl UIPresenter where D: Device { let solid_program = DebugSolidProgram::new(device, resources); let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program); - let font_texture = device.create_texture_from_png(resources, FONT_PNG_NAME); - let corner_fill_texture = device.create_texture_from_png(resources, CORNER_FILL_PNG_NAME); + let font_texture = device.create_texture_from_png(resources, + 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, - CORNER_OUTLINE_PNG_NAME); + CORNER_OUTLINE_PNG_NAME, + TextureFormat::R8); UIPresenter { event_queue: UIEventQueue::new(), diff --git a/utils/area-lut/src/main.rs b/utils/area-lut/src/main.rs index 1c6c92f2..09110b3d 100644 --- a/utils/area-lut/src/main.rs +++ b/utils/area-lut/src/main.rs @@ -6,7 +6,7 @@ extern crate image; use clap::{App, Arg}; use euclid::default::Point2D; -use image::{ImageBuffer, Luma}; +use image::{ImageBuffer, Rgba}; use std::f32; use std::path::Path; @@ -26,6 +26,44 @@ fn area_rect(p0: Point2D, p1: Point2D) -> f32 { (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() { let app = App::new("Pathfinder Area LUT Generator") .version("0.1") @@ -38,50 +76,23 @@ fn main() { let matches = app.get_matches(); let image = ImageBuffer::from_fn(WIDTH, HEIGHT, |u, v| { if u == 0 { - return Luma([255]) + return Rgba([255, 255, 255, 255]) } 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 dydx = -(v as f32) / 16.0; - let (x_left, x_right) = (-0.5, 0.5); - let (y_left, y_right) = (dydx * x_left + y, dydx * x_right + y); + let alphas = [ + (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)); - 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]) + Rgba([alphas[0], alphas[1], alphas[2], alphas[3]]) }); let output_path = matches.value_of("OUTPUT-PATH").unwrap();