Merge pull request #317 from pcwalton/four-at-a-time
Use all four channels in the mask texture.
This commit is contained in:
commit
cfc1d44638
|
@ -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<D> {
|
||||
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,
|
||||
|
|
|
@ -104,13 +104,26 @@ pub trait Device: Sized {
|
|||
fn try_recv_texture_data(&self, receiver: &Self::TextureDataReceiver) -> Option<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 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(
|
||||
|
|
|
@ -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<D> Renderer<D> 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<D> Renderer<D> 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<D> Renderer<D> 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<D> where D: Device {
|
|||
impl<D> AlphaTilePage<D> where D: Device {
|
||||
fn new(device: &mut D) -> AlphaTilePage<D> {
|
||||
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![],
|
||||
|
|
|
@ -388,7 +388,7 @@ pub struct FillComputeProgram<D> where D: Device {
|
|||
impl<D> FillComputeProgram<D> where D: Device {
|
||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillComputeProgram<D> {
|
||||
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<D> 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<D> TileProgram<D> 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<D> TileProgram<D> 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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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 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<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 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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 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<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 = {};
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<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)
|
||||
{
|
||||
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<flo
|
|||
float3 gaussCoeff = filterParams1.xyz;
|
||||
float gaussSum = gaussCoeff.x;
|
||||
float4 color = colorTexture.sample(colorTextureSmplr, colorTexCoord) * gaussCoeff.x;
|
||||
float2 _599 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_599.x, _599.y, gaussCoeff.z);
|
||||
float2 _600 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_600.x, _600.y, gaussCoeff.z);
|
||||
for (int i = 1; i <= support; i += 2)
|
||||
{
|
||||
float gaussPartialSum = gaussCoeff.x;
|
||||
float2 _619 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_619.x, _619.y, gaussCoeff.z);
|
||||
float2 _620 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_620.x, _620.y, gaussCoeff.z);
|
||||
gaussPartialSum += gaussCoeff.x;
|
||||
float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum));
|
||||
color += ((colorTexture.sample(colorTextureSmplr, (colorTexCoord - srcOffset)) + colorTexture.sample(colorTextureSmplr, (colorTexCoord + srcOffset))) * gaussPartialSum);
|
||||
gaussSum += (2.0 * gaussPartialSum);
|
||||
float2 _659 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_659.x, _659.y, gaussCoeff.z);
|
||||
float2 _660 = gaussCoeff.xy * gaussCoeff.yz;
|
||||
gaussCoeff = float3(_660.x, _660.y, gaussCoeff.z);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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<float> de
|
|||
}
|
||||
|
||||
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;
|
||||
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<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 = {};
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]])
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 34 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@ in vec2 vTo;
|
|||
out vec4 oFragColor;
|
||||
|
||||
void main() {
|
||||
oFragColor = vec4(computeCoverage(vFrom, vTo, uAreaLUT));
|
||||
oFragColor = computeCoverage(vFrom, vTo, uAreaLUT);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<D> UIPresenter<D> 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(),
|
||||
|
|
|
@ -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<f32>, p1: Point2D<f32>) -> 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();
|
||||
|
|
Loading…
Reference in New Issue