Use all four channels in the mask texture.

Each bundle of four pixels on a scanline is packed into the RGBA channels of
the mask texture. The area LUT is also expanded to be RGBA so that four pixels'
worth of areas can be looked up at once.

Nice improvement on `paris-30k` from MPVG.

Closes #262.
This commit is contained in:
Patrick Walton 2020-05-04 13:26:40 -07:00
parent c7ce2153de
commit 478008dcf0
25 changed files with 276 additions and 201 deletions

View File

@ -14,7 +14,7 @@ use crate::{BackgroundColor, Options};
use pathfinder_color::ColorU;
use pathfinder_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,

View File

@ -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(

View File

@ -65,8 +65,8 @@ const TEXTURE_METADATA_TEXTURE_WIDTH: i32 = TEXTURE_METADATA_ENTRIES_PER_ROW *
const TEXTURE_METADATA_TEXTURE_HEIGHT: i32 = 65536 / TEXTURE_METADATA_ENTRIES_PER_ROW;
// 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![],

View File

@ -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,

View File

@ -28,7 +28,7 @@ precision highp sampler2D;
float computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){
vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){
vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from;
@ -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);
}

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -18,8 +18,7 @@ struct main0_in
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]])
{
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

View File

@ -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);
}

View File

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

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// 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;
}

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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(),

View File

@ -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();