Rename the existing renderer to `d3d9` in preparation for the D3D11 branch

This commit is contained in:
Patrick Walton 2020-06-23 12:27:04 -07:00
parent 5e3fb5fed0
commit 754a44ae22
59 changed files with 2691 additions and 2032 deletions

View File

@ -0,0 +1,12 @@
// pathfinder/renderer/src/gpu/d3d9/mod.rs
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub mod renderer;
pub mod shaders;

View File

@ -0,0 +1,573 @@
// pathfinder/renderer/src/gpu/d3d9/renderer.rs
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::gpu::blend::{BlendModeExt, ToBlendState};
use crate::gpu::perf::TimerFuture;
use crate::gpu::renderer::{FramebufferFlags, MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_WIDTH};
use crate::gpu::renderer::{RendererCore, RendererFlags};
use crate::gpu::d3d9::shaders::{ClipTileCombineVertexArrayD3D9, ClipTileCopyVertexArrayD3D9};
use crate::gpu::d3d9::shaders::{CopyTileVertexArray, FillVertexArrayD3D9};
use crate::gpu::d3d9::shaders::{ProgramsD3D9, TileVertexArrayD3D9};
use crate::gpu_data::{Clip, DrawTileBatchD3D9, Fill, TileBatchTexture, TileObjectPrimitive};
use crate::tile_map::DenseTileMap;
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
use byte_slice_cast::AsByteSlice;
use pathfinder_color::ColorF;
use pathfinder_content::effects::BlendMode;
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::transform3d::Transform4F;
use pathfinder_geometry::vector::{Vector2I, Vector4F, vec2i};
use pathfinder_gpu::allocator::{BufferID, BufferTag, FramebufferID, FramebufferTag};
use pathfinder_gpu::allocator::{TextureID, TextureTag};
use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, ClearOps, Device, Primitive};
use pathfinder_gpu::{RenderOptions, RenderState, RenderTarget, StencilFunc, StencilState};
use pathfinder_gpu::{TextureDataRef, TextureFormat, UniformData};
use pathfinder_resources::ResourceLoader;
use pathfinder_simd::default::F32x2;
use std::u32;
const MAX_FILLS_PER_BATCH: usize = 0x10000;
pub(crate) struct RendererD3D9<D> where D: Device {
// Basic data
programs: ProgramsD3D9<D>,
quads_vertex_indices_buffer_id: Option<BufferID>,
quads_vertex_indices_length: usize,
// Fills.
buffered_fills: Vec<Fill>,
pending_fills: Vec<Fill>,
// Temporary framebuffers
dest_blend_framebuffer_id: FramebufferID,
}
impl<D> RendererD3D9<D> where D: Device {
pub(crate) fn new(core: &mut RendererCore<D>, resources: &dyn ResourceLoader)
-> RendererD3D9<D> {
let programs = ProgramsD3D9::new(&core.device, resources);
let window_size = core.options.dest.window_size(&core.device);
let dest_blend_framebuffer_id =
core.allocator.allocate_framebuffer(&core.device,
window_size,
TextureFormat::RGBA8,
FramebufferTag("DestBlendD3D9"));
RendererD3D9 {
programs,
quads_vertex_indices_buffer_id: None,
quads_vertex_indices_length: 0,
buffered_fills: vec![],
pending_fills: vec![],
dest_blend_framebuffer_id,
}
}
pub(crate) fn upload_and_draw_tiles(&mut self,
core: &mut RendererCore<D>,
batch: &DrawTileBatchD3D9) {
if !batch.clips.is_empty() {
let clip_buffer_info = self.upload_clip_tiles(core, &batch.clips);
self.clip_tiles(core, &clip_buffer_info);
core.allocator.free_buffer(clip_buffer_info.clip_buffer_id);
}
let tile_buffer = self.upload_tiles(core, &batch.tiles);
let z_buffer_texture_id = self.upload_z_buffer(core, &batch.z_buffer_data);
self.draw_tiles(core,
batch.tiles.len() as u32,
tile_buffer.tile_vertex_buffer_id,
batch.color_texture,
batch.blend_mode,
z_buffer_texture_id);
core.allocator.free_texture(z_buffer_texture_id);
core.allocator.free_buffer(tile_buffer.tile_vertex_buffer_id);
}
fn upload_tiles(&mut self, core: &mut RendererCore<D>, tiles: &[TileObjectPrimitive])
-> TileBufferD3D9 {
let tile_vertex_buffer_id =
core.allocator.allocate_buffer::<TileObjectPrimitive>(&core.device,
tiles.len() as u64,
BufferTag("TileD3D9"));
let tile_vertex_buffer = &core.allocator.get_buffer(tile_vertex_buffer_id);
core.device.upload_to_buffer(tile_vertex_buffer, 0, tiles, BufferTarget::Vertex);
self.ensure_index_buffer(core, tiles.len());
TileBufferD3D9 { tile_vertex_buffer_id }
}
fn ensure_index_buffer(&mut self, core: &mut RendererCore<D>, mut length: usize) {
length = length.next_power_of_two();
if self.quads_vertex_indices_length >= length {
return;
}
// TODO(pcwalton): Generate these with SIMD.
let mut indices: Vec<u32> = Vec::with_capacity(length * 6);
for index in 0..(length as u32) {
indices.extend_from_slice(&[
index * 4 + 0, index * 4 + 1, index * 4 + 2,
index * 4 + 1, index * 4 + 3, index * 4 + 2,
]);
}
if let Some(quads_vertex_indices_buffer_id) = self.quads_vertex_indices_buffer_id.take() {
core.allocator.free_buffer(quads_vertex_indices_buffer_id);
}
let quads_vertex_indices_buffer_id =
core.allocator.allocate_buffer::<u32>(&core.device,
indices.len() as u64,
BufferTag("QuadsVertexIndicesD3D9"));
let quads_vertex_indices_buffer =
core.allocator.get_buffer(quads_vertex_indices_buffer_id);
core.device.upload_to_buffer(quads_vertex_indices_buffer,
0,
&indices,
BufferTarget::Index);
self.quads_vertex_indices_buffer_id = Some(quads_vertex_indices_buffer_id);
self.quads_vertex_indices_length = length;
}
pub(crate) fn add_fills(&mut self, core: &mut RendererCore<D>, fill_batch: &[Fill]) {
if fill_batch.is_empty() {
return;
}
core.stats.fill_count += fill_batch.len();
let preserve_alpha_mask_contents = core.alpha_tile_count > 0;
self.pending_fills.reserve(fill_batch.len());
for fill in fill_batch {
core.alpha_tile_count = core.alpha_tile_count.max(fill.link + 1);
self.pending_fills.push(*fill);
}
core.stats.alpha_tile_count = core.alpha_tile_count as usize;
core.reallocate_alpha_tile_pages_if_necessary(preserve_alpha_mask_contents);
if self.buffered_fills.len() + self.pending_fills.len() > MAX_FILLS_PER_BATCH {
self.draw_buffered_fills(core);
}
self.buffered_fills.extend(self.pending_fills.drain(..));
}
pub(crate) fn draw_buffered_fills(&mut self, core: &mut RendererCore<D>) {
if self.buffered_fills.is_empty() {
return;
}
let fill_storage_info = self.upload_buffered_fills(core);
self.draw_fills(core, fill_storage_info.fill_buffer_id, fill_storage_info.fill_count);
core.allocator.free_buffer(fill_storage_info.fill_buffer_id);
}
fn upload_buffered_fills(&mut self, core: &mut RendererCore<D>) -> FillBufferInfoD3D9 {
let buffered_fills = &mut self.buffered_fills;
debug_assert!(!buffered_fills.is_empty());
let fill_buffer_id = core.allocator.allocate_buffer::<Fill>(&core.device,
MAX_FILLS_PER_BATCH as u64,
BufferTag("Fill"));
let fill_vertex_buffer = core.allocator.get_buffer(fill_buffer_id);
debug_assert!(buffered_fills.len() <= u32::MAX as usize);
core.device.upload_to_buffer(fill_vertex_buffer, 0, &buffered_fills, BufferTarget::Vertex);
let fill_count = buffered_fills.len() as u32;
buffered_fills.clear();
FillBufferInfoD3D9 { fill_buffer_id, fill_count }
}
fn draw_fills(&mut self,
core: &mut RendererCore<D>,
fill_buffer_id: BufferID,
fill_count: u32) {
let fill_raster_program = &self.programs.fill_program;
let fill_vertex_buffer = core.allocator.get_buffer(fill_buffer_id);
let quad_vertex_positions_buffer = core.allocator
.get_buffer(core.quad_vertex_positions_buffer_id);
let quad_vertex_indices_buffer = core.allocator
.get_buffer(core.quad_vertex_indices_buffer_id);
let area_lut_texture = core.allocator.get_texture(core.area_lut_texture_id);
let mask_viewport = self.mask_viewport(core);
let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?");
let mask_framebuffer_id = mask_storage.framebuffer_id;
let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id);
let fill_vertex_array = FillVertexArrayD3D9::new(&core.device,
fill_raster_program,
fill_vertex_buffer,
quad_vertex_positions_buffer,
quad_vertex_indices_buffer);
let mut clear_color = None;
if !core.framebuffer_flags.contains(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY) {
clear_color = Some(ColorF::default());
};
let timer_query = core.timer_query_cache.alloc(&core.device);
core.device.begin_timer_query(&timer_query);
core.device.draw_elements_instanced(6, fill_count, &RenderState {
target: &RenderTarget::Framebuffer(mask_framebuffer),
program: &fill_raster_program.program,
vertex_array: &fill_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &[(&fill_raster_program.area_lut_texture, area_lut_texture)],
uniforms: &[
(&fill_raster_program.framebuffer_size_uniform,
UniformData::Vec2(mask_viewport.size().to_f32().0)),
(&fill_raster_program.tile_size_uniform,
UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))),
],
images: &[],
storage_buffers: &[],
viewport: mask_viewport,
options: RenderOptions {
blend: Some(BlendState {
src_rgb_factor: BlendFactor::One,
src_alpha_factor: BlendFactor::One,
dest_rgb_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
..BlendState::default()
}),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
..RenderOptions::default()
},
});
core.device.end_timer_query(&timer_query);
core.current_timer.as_mut().unwrap().fill_times.push(TimerFuture::new(timer_query));
core.stats.drawcall_count += 1;
core.framebuffer_flags.insert(FramebufferFlags::MASK_FRAMEBUFFER_IS_DIRTY);
}
fn clip_tiles(&mut self, core: &mut RendererCore<D>, clip_buffer_info: &ClipBufferInfo) {
// Allocate temp mask framebuffer.
let mask_temp_framebuffer_id =
core.allocator.allocate_framebuffer(&core.device,
self.mask_viewport(core).size(),
core.mask_texture_format(),
FramebufferTag("TempClipMaskD3D9"));
let mask_temp_framebuffer = core.allocator.get_framebuffer(mask_temp_framebuffer_id);
let mask_storage = core.mask_storage.as_ref().expect("Where's the mask storage?");
let mask_framebuffer_id = mask_storage.framebuffer_id;
let mask_framebuffer = core.allocator.get_framebuffer(mask_framebuffer_id);
let mask_texture = core.device.framebuffer_texture(mask_framebuffer);
let mask_texture_size = core.device.texture_size(&mask_texture);
let clip_vertex_buffer = core.allocator.get_buffer(clip_buffer_info.clip_buffer_id);
let quad_vertex_positions_buffer = core.allocator
.get_buffer(core.quad_vertex_positions_buffer_id);
let quad_vertex_indices_buffer = core.allocator
.get_buffer(core.quad_vertex_indices_buffer_id);
let tile_clip_copy_vertex_array =
ClipTileCopyVertexArrayD3D9::new(&core.device,
&self.programs.tile_clip_copy_program,
clip_vertex_buffer,
quad_vertex_positions_buffer,
quad_vertex_indices_buffer);
let tile_clip_combine_vertex_array =
ClipTileCombineVertexArrayD3D9::new(&core.device,
&self.programs.tile_clip_combine_program,
clip_vertex_buffer,
quad_vertex_positions_buffer,
quad_vertex_indices_buffer);
let timer_query = core.timer_query_cache.alloc(&core.device);
core.device.begin_timer_query(&timer_query);
// Copy out tiles.
//
// TODO(pcwalton): Don't do this on GL4.
core.device.draw_elements_instanced(6, clip_buffer_info.clip_count * 2, &RenderState {
target: &RenderTarget::Framebuffer(mask_temp_framebuffer),
program: &self.programs.tile_clip_copy_program.program,
vertex_array: &tile_clip_copy_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &[
(&self.programs.tile_clip_copy_program.src_texture,
core.device.framebuffer_texture(mask_framebuffer)),
],
images: &[],
uniforms: &[
(&self.programs.tile_clip_copy_program.framebuffer_size_uniform,
UniformData::Vec2(mask_texture_size.to_f32().0)),
],
storage_buffers: &[],
viewport: RectI::new(Vector2I::zero(), mask_texture_size),
options: RenderOptions::default(),
});
// Combine clip tiles.
core.device.draw_elements_instanced(6, clip_buffer_info.clip_count, &RenderState {
target: &RenderTarget::Framebuffer(mask_framebuffer),
program: &self.programs.tile_clip_combine_program.program,
vertex_array: &tile_clip_combine_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &[
(&self.programs.tile_clip_combine_program.src_texture,
core.device.framebuffer_texture(&mask_temp_framebuffer)),
],
images: &[],
uniforms: &[
(&self.programs.tile_clip_combine_program.framebuffer_size_uniform,
UniformData::Vec2(mask_texture_size.to_f32().0)),
],
storage_buffers: &[],
viewport: RectI::new(Vector2I::zero(), mask_texture_size),
options: RenderOptions::default(),
});
core.device.end_timer_query(&timer_query);
core.current_timer.as_mut().unwrap().other_times.push(TimerFuture::new(timer_query));
core.stats.drawcall_count += 2;
core.allocator.free_framebuffer(mask_temp_framebuffer_id);
}
fn upload_z_buffer(&mut self, core: &mut RendererCore<D>, z_buffer_map: &DenseTileMap<i32>)
-> TextureID {
let z_buffer_texture_id = core.allocator.allocate_texture(&core.device,
z_buffer_map.rect.size(),
TextureFormat::RGBA8,
TextureTag("ZBufferD3D9"));
let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id);
debug_assert_eq!(z_buffer_map.rect.origin(), Vector2I::default());
let z_data: &[u8] = z_buffer_map.data.as_byte_slice();
core.device.upload_to_texture(z_buffer_texture,
z_buffer_map.rect,
TextureDataRef::U8(&z_data));
z_buffer_texture_id
}
// Uploads clip tiles from CPU to GPU.
fn upload_clip_tiles(&mut self, core: &mut RendererCore<D>, clips: &[Clip]) -> ClipBufferInfo {
let clip_buffer_id = core.allocator.allocate_buffer::<Clip>(&core.device,
clips.len() as u64,
BufferTag("ClipD3D9"));
let clip_buffer = core.allocator.get_buffer(clip_buffer_id);
core.device.upload_to_buffer(clip_buffer, 0, clips, BufferTarget::Vertex);
ClipBufferInfo { clip_buffer_id, clip_count: clips.len() as u32 }
}
fn draw_tiles(&mut self,
core: &mut RendererCore<D>,
tile_count: u32,
tile_vertex_buffer_id: BufferID,
color_texture_0: Option<TileBatchTexture>,
blend_mode: BlendMode,
z_buffer_texture_id: TextureID) {
// TODO(pcwalton): Disable blend for solid tiles.
if tile_count == 0 {
return;
}
core.stats.total_tile_count += tile_count as usize;
let needs_readable_framebuffer = blend_mode.needs_readable_framebuffer();
if needs_readable_framebuffer {
self.copy_alpha_tiles_to_dest_blend_texture(core, tile_count, tile_vertex_buffer_id);
}
let clear_color = core.clear_color_for_draw_operation();
let draw_viewport = core.draw_viewport();
let timer_query = core.timer_query_cache.alloc(&core.device);
core.device.begin_timer_query(&timer_query);
let tile_raster_program = &self.programs.tile_program;
let tile_vertex_buffer = core.allocator.get_buffer(tile_vertex_buffer_id);
let quad_vertex_positions_buffer = core.allocator
.get_buffer(core.quad_vertex_positions_buffer_id);
let quad_vertex_indices_buffer = core.allocator
.get_buffer(core.quad_vertex_indices_buffer_id);
let dest_blend_framebuffer = core.allocator
.get_framebuffer(self.dest_blend_framebuffer_id);
let (mut textures, mut uniforms) = (vec![], vec![]);
core.set_uniforms_for_drawing_tiles(&tile_raster_program.common,
&mut textures,
&mut uniforms,
color_texture_0);
uniforms.push((&tile_raster_program.transform_uniform,
UniformData::Mat4(self.tile_transform(core).to_columns())));
if needs_readable_framebuffer {
textures.push((&tile_raster_program.dest_texture,
core.device.framebuffer_texture(dest_blend_framebuffer)));
}
let z_buffer_texture = core.allocator.get_texture(z_buffer_texture_id);
textures.push((&tile_raster_program.common.z_buffer_texture, z_buffer_texture));
uniforms.push((&tile_raster_program.common.z_buffer_texture_size_uniform,
UniformData::IVec2(core.device.texture_size(z_buffer_texture).0)));
let tile_vertex_array = TileVertexArrayD3D9::new(&core.device,
&self.programs.tile_program,
tile_vertex_buffer,
quad_vertex_positions_buffer,
quad_vertex_indices_buffer);
core.device.draw_elements_instanced(6, tile_count, &RenderState {
target: &core.draw_render_target(),
program: &tile_raster_program.common.program,
vertex_array: &tile_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &textures,
images: &[],
storage_buffers: &[],
uniforms: &uniforms,
viewport: draw_viewport,
options: RenderOptions {
blend: blend_mode.to_blend_state(),
stencil: self.stencil_state(core),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
..RenderOptions::default()
},
});
core.device.end_timer_query(&timer_query);
core.current_timer.as_mut().unwrap().composite_times.push(TimerFuture::new(timer_query));
core.stats.drawcall_count += 1;
core.preserve_draw_framebuffer();
}
fn copy_alpha_tiles_to_dest_blend_texture(&mut self,
core: &mut RendererCore<D>,
tile_count: u32,
vertex_buffer_id: BufferID) {
let draw_viewport = core.draw_viewport();
let mut textures = vec![];
let mut uniforms = vec![
(&self.programs.tile_copy_program.transform_uniform,
UniformData::Mat4(self.tile_transform(core).to_columns())),
(&self.programs.tile_copy_program.tile_size_uniform,
UniformData::Vec2(F32x2::new(TILE_WIDTH as f32, TILE_HEIGHT as f32))),
];
let draw_framebuffer = match core.draw_render_target() {
RenderTarget::Framebuffer(framebuffer) => framebuffer,
RenderTarget::Default => panic!("Can't copy alpha tiles from default framebuffer!"),
};
let draw_texture = core.device.framebuffer_texture(&draw_framebuffer);
textures.push((&self.programs.tile_copy_program.src_texture, draw_texture));
uniforms.push((&self.programs.tile_copy_program.framebuffer_size_uniform,
UniformData::Vec2(draw_viewport.size().to_f32().0)));
let quads_vertex_indices_buffer_id = self.quads_vertex_indices_buffer_id
.expect("Where's the quads vertex buffer?");
let quads_vertex_indices_buffer = core.allocator
.get_buffer(quads_vertex_indices_buffer_id);
let vertex_buffer = core.allocator.get_buffer(vertex_buffer_id);
let tile_copy_vertex_array = CopyTileVertexArray::new(&core.device,
&self.programs.tile_copy_program,
vertex_buffer,
quads_vertex_indices_buffer);
let dest_blend_framebuffer = core.allocator
.get_framebuffer(self.dest_blend_framebuffer_id);
core.device.draw_elements(tile_count * 6, &RenderState {
target: &RenderTarget::Framebuffer(dest_blend_framebuffer),
program: &self.programs.tile_copy_program.program,
vertex_array: &tile_copy_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &textures,
images: &[],
storage_buffers: &[],
uniforms: &uniforms,
viewport: draw_viewport,
options: RenderOptions {
clear_ops: ClearOps {
color: Some(ColorF::new(1.0, 0.0, 0.0, 1.0)),
..ClearOps::default()
},
..RenderOptions::default()
},
});
core.stats.drawcall_count += 1;
}
fn stencil_state(&self, core: &RendererCore<D>) -> Option<StencilState> {
if !core.renderer_flags.contains(RendererFlags::USE_DEPTH) {
return None;
}
Some(StencilState {
func: StencilFunc::Equal,
reference: 1,
mask: 1,
write: false,
})
}
fn mask_viewport(&self, core: &RendererCore<D>) -> RectI {
let page_count = match core.mask_storage {
Some(ref mask_storage) => mask_storage.allocated_page_count as i32,
None => 0,
};
let height = MASK_FRAMEBUFFER_HEIGHT * page_count;
RectI::new(Vector2I::default(), vec2i(MASK_FRAMEBUFFER_WIDTH, height))
}
fn tile_transform(&self, core: &RendererCore<D>) -> Transform4F {
let draw_viewport = core.draw_viewport().size().to_f32();
let scale = Vector4F::new(2.0 / draw_viewport.x(), -2.0 / draw_viewport.y(), 1.0, 1.0);
Transform4F::from_scale(scale).translate(Vector4F::new(-1.0, 1.0, 0.0, 1.0))
}
}
#[derive(Clone)]
pub(crate) struct TileBatchInfoD3D9 {
pub(crate) tile_count: u32,
pub(crate) z_buffer_id: BufferID,
tile_vertex_buffer_id: BufferID,
}
#[derive(Clone)]
struct FillBufferInfoD3D9 {
fill_buffer_id: BufferID,
fill_count: u32,
}
struct TileBufferD3D9 {
tile_vertex_buffer_id: BufferID,
}
struct ClipBufferInfo {
clip_buffer_id: BufferID,
clip_count: u32,
}

View File

@ -0,0 +1,441 @@
// pathfinder/renderer/src/gpu/d3d9/shaders.rs
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::gpu::shaders::{TILE_INSTANCE_SIZE, TileProgramCommon};
use pathfinder_gpu::{BufferTarget, Device, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader;
const FILL_INSTANCE_SIZE: usize = 12;
const CLIP_TILE_INSTANCE_SIZE: usize = 16;
pub struct FillVertexArrayD3D9<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> FillVertexArrayD3D9<D> where D: Device {
pub fn new(device: &D,
fill_program: &FillProgramD3D9<D>,
vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> FillVertexArrayD3D9<D> {
let vertex_array = device.create_vertex_array();
let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap();
let line_segment_attr = device.get_vertex_attr(&fill_program.program, "LineSegment")
.unwrap();
let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &line_segment_attr, &VertexAttrDescriptor {
size: 4,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U16,
stride: FILL_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: FILL_INSTANCE_SIZE,
offset: 8,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
FillVertexArrayD3D9 { vertex_array }
}
}
pub struct TileVertexArrayD3D9<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> TileVertexArrayD3D9<D> where D: Device {
pub fn new(device: &D,
tile_program: &TileProgramD3D9<D>,
tile_vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> TileVertexArrayD3D9<D> {
let vertex_array = device.create_vertex_array();
let tile_offset_attr =
device.get_vertex_attr(&tile_program.common.program, "TileOffset").unwrap();
let tile_origin_attr =
device.get_vertex_attr(&tile_program.common.program, "TileOrigin").unwrap();
let mask_0_tex_coord_attr =
device.get_vertex_attr(&tile_program.common.program, "MaskTexCoord0").unwrap();
let ctrl_backdrop_attr =
device.get_vertex_attr(&tile_program.common.program, "CtrlBackdrop").unwrap();
let color_attr = device.get_vertex_attr(&tile_program.common.program, "Color").unwrap();
let path_index_attr = device.get_vertex_attr(&tile_program.common.program, "PathIndex")
.unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor {
size: 4,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: TILE_INSTANCE_SIZE,
offset: 4,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &path_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: TILE_INSTANCE_SIZE,
offset: 8,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 12,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &ctrl_backdrop_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I8,
stride: TILE_INSTANCE_SIZE,
offset: 14,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
TileVertexArrayD3D9 { vertex_array }
}
}
pub struct ClipTileCopyVertexArrayD3D9<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> ClipTileCopyVertexArrayD3D9<D> where D: Device {
pub fn new(device: &D,
clip_tile_copy_program: &ClipTileCopyProgramD3D9<D>,
vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> ClipTileCopyVertexArrayD3D9<D> {
let vertex_array = device.create_vertex_array();
let tile_offset_attr =
device.get_vertex_attr(&clip_tile_copy_program.program, "TileOffset").unwrap();
let tile_index_attr =
device.get_vertex_attr(&clip_tile_copy_program.program, "TileIndex").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: CLIP_TILE_INSTANCE_SIZE / 2,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
ClipTileCopyVertexArrayD3D9 { vertex_array }
}
}
pub struct ClipTileCombineVertexArrayD3D9<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> ClipTileCombineVertexArrayD3D9<D> where D: Device {
pub fn new(device: &D,
clip_tile_combine_program: &ClipTileCombineProgramD3D9<D>,
vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> ClipTileCombineVertexArrayD3D9<D> {
let vertex_array = device.create_vertex_array();
let tile_offset_attr =
device.get_vertex_attr(&clip_tile_combine_program.program, "TileOffset").unwrap();
let dest_tile_index_attr =
device.get_vertex_attr(&clip_tile_combine_program.program, "DestTileIndex").unwrap();
let dest_backdrop_attr =
device.get_vertex_attr(&clip_tile_combine_program.program, "DestBackdrop").unwrap();
let src_tile_index_attr =
device.get_vertex_attr(&clip_tile_combine_program.program, "SrcTileIndex").unwrap();
let src_backdrop_attr =
device.get_vertex_attr(&clip_tile_combine_program.program, "SrcBackdrop").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &dest_tile_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &dest_backdrop_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 4,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &src_tile_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 8,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I32,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 12,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
ClipTileCombineVertexArrayD3D9 { vertex_array }
}
}
pub struct CopyTileVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> CopyTileVertexArray<D> where D: Device {
pub fn new(device: &D,
copy_tile_program: &CopyTileProgram<D>,
copy_tile_vertex_buffer: &D::Buffer,
quads_vertex_indices_buffer: &D::Buffer)
-> CopyTileVertexArray<D> {
let vertex_array = device.create_vertex_array();
let tile_position_attr =
device.get_vertex_attr(&copy_tile_program.program, "TilePosition").unwrap();
device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
CopyTileVertexArray { vertex_array }
}
}
pub struct FillProgramD3D9<D> where D: Device {
pub program: D::Program,
pub framebuffer_size_uniform: D::Uniform,
pub tile_size_uniform: D::Uniform,
pub area_lut_texture: D::TextureParameter,
}
impl<D> FillProgramD3D9<D> where D: Device {
fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgramD3D9<D> {
let program = device.create_raster_program(resources, "d3d9/fill");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT");
FillProgramD3D9 {
program,
framebuffer_size_uniform,
tile_size_uniform,
area_lut_texture,
}
}
}
pub struct TileProgramD3D9<D> where D: Device {
pub common: TileProgramCommon<D>,
pub dest_texture: D::TextureParameter,
pub transform_uniform: D::Uniform,
}
impl<D> TileProgramD3D9<D> where D: Device {
fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgramD3D9<D> {
let program = device.create_raster_program(resources, "d3d9/tile");
let dest_texture = device.get_texture_parameter(&program, "DestTexture");
let transform_uniform = device.get_uniform(&program, "Transform");
let common = TileProgramCommon::new(device, program);
TileProgramD3D9 { common, dest_texture, transform_uniform }
}
}
pub struct ClipTileCombineProgramD3D9<D> where D: Device {
pub program: D::Program,
pub src_texture: D::TextureParameter,
pub framebuffer_size_uniform: D::Uniform,
}
impl<D> ClipTileCombineProgramD3D9<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCombineProgramD3D9<D> {
let program = device.create_raster_program(resources, "d3d9/tile_clip_combine");
let src_texture = device.get_texture_parameter(&program, "Src");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
ClipTileCombineProgramD3D9 { program, src_texture, framebuffer_size_uniform }
}
}
pub struct ClipTileCopyProgramD3D9<D> where D: Device {
pub program: D::Program,
pub src_texture: D::TextureParameter,
pub framebuffer_size_uniform: D::Uniform,
}
impl<D> ClipTileCopyProgramD3D9<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileCopyProgramD3D9<D> {
let program = device.create_raster_program(resources, "d3d9/tile_clip_copy");
let src_texture = device.get_texture_parameter(&program, "Src");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
ClipTileCopyProgramD3D9 { program, src_texture, framebuffer_size_uniform }
}
}
pub struct CopyTileProgram<D> where D: Device {
pub program: D::Program,
pub transform_uniform: D::Uniform,
pub tile_size_uniform: D::Uniform,
pub framebuffer_size_uniform: D::Uniform,
pub src_texture: D::TextureParameter,
}
impl<D> CopyTileProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram<D> {
let program = device.create_raster_program(resources, "d3d9/tile_copy");
let transform_uniform = device.get_uniform(&program, "Transform");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let src_texture = device.get_texture_parameter(&program, "Src");
CopyTileProgram {
program,
transform_uniform,
tile_size_uniform,
framebuffer_size_uniform,
src_texture,
}
}
}
pub struct D3D9Programs<D> where D: Device {
pub fill_program: FillProgramD3D9<D>,
pub tile_program: TileProgramD3D9<D>,
pub tile_clip_combine_program: ClipTileCombineProgramD3D9<D>,
pub tile_clip_copy_program: ClipTileCopyProgramD3D9<D>,
pub tile_copy_program: CopyTileProgram<D>,
}
impl<D> D3D9Programs<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> D3D9Programs<D> {
D3D9Programs {
fill_program: FillProgramD3D9::new(device, resources),
tile_program: TileProgramD3D9::new(device, resources),
tile_clip_combine_program: ClipTileCombineProgramD3D9::new(device, resources),
tile_clip_copy_program: ClipTileCopyProgramD3D9::new(device, resources),
tile_copy_program: CopyTileProgram::new(device, resources),
}
}
}
pub struct ProgramsD3D9<D> where D: Device {
pub fill_program: FillProgramD3D9<D>,
pub tile_program: TileProgramD3D9<D>,
pub tile_clip_copy_program: ClipTileCopyProgramD3D9<D>,
pub tile_clip_combine_program: ClipTileCombineProgramD3D9<D>,
pub tile_copy_program: CopyTileProgram<D>,
}
impl<D> ProgramsD3D9<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsD3D9<D> {
ProgramsD3D9 {
fill_program: FillProgramD3D9::new(device, resources),
tile_program: TileProgramD3D9::new(device, resources),
tile_clip_copy_program: ClipTileCopyProgramD3D9::new(device, resources),
tile_clip_combine_program: ClipTileCombineProgramD3D9::new(device, resources),
tile_copy_program: CopyTileProgram::new(device, resources),
}
}
}

View File

@ -8,20 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::gpu::options::RendererOptions;
use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN};
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_gpu::{BufferTarget, BufferUploadMode, Device, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader;
// TODO(pcwalton): Replace with `mem::size_of` calls?
pub(crate) const TILE_INSTANCE_SIZE: usize = 12;
const FILL_INSTANCE_SIZE: usize = 8;
const CLIP_TILE_INSTANCE_SIZE: usize = 8;
pub const MAX_FILLS_PER_BATCH: usize = 0x10000;
pub const MAX_TILES_PER_BATCH: usize = MASK_TILES_ACROSS as usize * MASK_TILES_DOWN as usize;
pub(crate) const TILE_INSTANCE_SIZE: usize = 16;
pub struct BlitVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
@ -52,6 +44,25 @@ impl<D> BlitVertexArray<D> where D: Device {
}
}
pub struct VertexArraysCore<D> where D: Device {
pub blit_vertex_array: BlitVertexArray<D>,
}
impl<D> VertexArraysCore<D> where D: Device {
pub fn new(device: &D,
programs: &ProgramsCore<D>,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> VertexArraysCore<D> {
VertexArraysCore {
blit_vertex_array: BlitVertexArray::new(device,
&programs.blit_program,
quad_vertex_positions_buffer,
quad_vertex_indices_buffer),
}
}
}
pub struct ClearVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
@ -81,288 +92,32 @@ impl<D> ClearVertexArray<D> where D: Device {
}
}
pub struct FillVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> FillVertexArray<D>
where
D: Device,
{
pub fn new(
device: &D,
fill_program: &FillRasterProgram<D>,
vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer,
) -> FillVertexArray<D> {
let vertex_array = device.create_vertex_array();
let tess_coord_attr = device.get_vertex_attr(&fill_program.program, "TessCoord").unwrap();
let from_px_attr = device.get_vertex_attr(&fill_program.program, "FromPx").unwrap();
let to_px_attr = device.get_vertex_attr(&fill_program.program, "ToPx").unwrap();
let from_subpx_attr = device.get_vertex_attr(&fill_program.program, "FromSubpx").unwrap();
let to_subpx_attr = device.get_vertex_attr(&fill_program.program, "ToSubpx").unwrap();
let tile_index_attr = device.get_vertex_attr(&fill_program.program, "TileIndex").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tess_coord_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &from_subpx_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::FloatNorm,
attr_type: VertexAttrType::U8,
stride: FILL_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &to_subpx_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::FloatNorm,
attr_type: VertexAttrType::U8,
stride: FILL_INSTANCE_SIZE,
offset: 2,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &from_px_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: FILL_INSTANCE_SIZE,
offset: 4,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &to_px_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: FILL_INSTANCE_SIZE,
offset: 5,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &tile_index_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U16,
stride: FILL_INSTANCE_SIZE,
offset: 6,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
FillVertexArray { vertex_array }
}
}
pub struct TileVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> TileVertexArray<D> where D: Device {
pub fn new(device: &D,
tile_program: &TileProgram<D>,
tile_vertex_buffer: &D::Buffer,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> TileVertexArray<D> {
let vertex_array = device.create_vertex_array();
let tile_offset_attr =
device.get_vertex_attr(&tile_program.program, "TileOffset").unwrap();
let tile_origin_attr =
device.get_vertex_attr(&tile_program.program, "TileOrigin").unwrap();
let mask_0_tex_coord_attr =
device.get_vertex_attr(&tile_program.program, "MaskTexCoord0").unwrap();
let mask_backdrop_attr =
device.get_vertex_attr(&tile_program.program, "MaskBackdrop").unwrap();
let color_attr = device.get_vertex_attr(&tile_program.program, "Color").unwrap();
let tile_ctrl_attr = device.get_vertex_attr(&tile_program.program, "TileCtrl").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, tile_vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_origin_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &mask_0_tex_coord_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: TILE_INSTANCE_SIZE,
offset: 4,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &mask_backdrop_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I8,
stride: TILE_INSTANCE_SIZE,
offset: 6,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &color_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 8,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &tile_ctrl_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 10,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
TileVertexArray { vertex_array }
}
}
pub struct CopyTileVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> CopyTileVertexArray<D> where D: Device {
pub fn new(
device: &D,
copy_tile_program: &CopyTileProgram<D>,
copy_tile_vertex_buffer: &D::Buffer,
quads_vertex_indices_buffer: &D::Buffer,
) -> CopyTileVertexArray<D> {
let vertex_array = device.create_vertex_array();
let tile_position_attr =
device.get_vertex_attr(&copy_tile_program.program, "TilePosition").unwrap();
device.bind_buffer(&vertex_array, copy_tile_vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: TILE_INSTANCE_SIZE,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
CopyTileVertexArray { vertex_array }
}
}
pub struct ClipTileVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
pub vertex_buffer: D::Buffer,
}
impl<D> ClipTileVertexArray<D> where D: Device {
pub fn new(device: &D,
clip_tile_program: &ClipTileProgram<D>,
quad_vertex_positions_buffer: &D::Buffer,
quad_vertex_indices_buffer: &D::Buffer)
-> ClipTileVertexArray<D> {
let vertex_array = device.create_vertex_array();
let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic);
let tile_offset_attr =
device.get_vertex_attr(&clip_tile_program.program, "TileOffset").unwrap();
let dest_tile_origin_attr =
device.get_vertex_attr(&clip_tile_program.program, "DestTileOrigin").unwrap();
let src_tile_origin_attr =
device.get_vertex_attr(&clip_tile_program.program, "SrcTileOrigin").unwrap();
let src_backdrop_attr =
device.get_vertex_attr(&clip_tile_program.program, "SrcBackdrop").unwrap();
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &tile_offset_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &dest_tile_origin_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 0,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &src_tile_origin_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::U8,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 2,
divisor: 1,
buffer_index: 1,
});
device.configure_vertex_attr(&vertex_array, &src_backdrop_attr, &VertexAttrDescriptor {
size: 1,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I8,
stride: CLIP_TILE_INSTANCE_SIZE,
offset: 4,
divisor: 1,
buffer_index: 1,
});
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
ClipTileVertexArray { vertex_array, vertex_buffer }
}
}
pub struct BlitProgram<D> where D: Device {
pub program: D::Program,
pub dest_rect_uniform: D::Uniform,
pub framebuffer_size_uniform: D::Uniform,
pub src_texture: D::TextureParameter,
}
impl<D> BlitProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram<D> {
let program = device.create_raster_program(resources, "blit");
let dest_rect_uniform = device.get_uniform(&program, "DestRect");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let src_texture = device.get_texture_parameter(&program, "Src");
BlitProgram { program, src_texture }
BlitProgram { program, dest_rect_uniform, framebuffer_size_uniform, src_texture }
}
}
pub struct ProgramsCore<D> where D: Device {
pub blit_program: BlitProgram<D>,
}
impl<D> ProgramsCore<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ProgramsCore<D> {
ProgramsCore {
blit_program: BlitProgram::new(device, resources),
}
}
}
@ -383,211 +138,73 @@ impl<D> ClearProgram<D> where D: Device {
}
}
pub enum FillProgram<D> where D: Device {
Raster(FillRasterProgram<D>),
Compute(FillComputeProgram<D>),
}
impl<D> FillProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader, options: &RendererOptions)
-> FillProgram<D> {
match (options.no_compute, device.feature_level()) {
(false, FeatureLevel::D3D11) => {
FillProgram::Compute(FillComputeProgram::new(device, resources))
}
(_, FeatureLevel::D3D10) | (true, _) => {
FillProgram::Raster(FillRasterProgram::new(device, resources))
}
}
}
}
pub struct FillRasterProgram<D> where D: Device {
pub struct TileProgramCommon<D> where D: Device {
pub program: D::Program,
pub framebuffer_size_uniform: D::Uniform,
pub tile_size_uniform: D::Uniform,
pub area_lut_texture: D::TextureParameter,
}
impl<D> FillRasterProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FillRasterProgram<D> {
let program = device.create_raster_program(resources, "fill");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT");
FillRasterProgram {
program,
framebuffer_size_uniform,
tile_size_uniform,
area_lut_texture,
}
}
}
pub struct FillComputeProgram<D> where D: Device {
pub program: D::Program,
pub dest_image: D::ImageParameter,
pub area_lut_texture: D::TextureParameter,
pub first_tile_index_uniform: D::Uniform,
pub fills_storage_buffer: D::StorageBuffer,
pub next_fills_storage_buffer: D::StorageBuffer,
pub fill_tile_map_storage_buffer: D::StorageBuffer,
}
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 / 4, z: 1 };
device.set_compute_program_local_size(&mut program, local_size);
let dest_image = device.get_image_parameter(&program, "Dest");
let area_lut_texture = device.get_texture_parameter(&program, "AreaLUT");
let first_tile_index_uniform = device.get_uniform(&program, "FirstTileIndex");
let fills_storage_buffer = device.get_storage_buffer(&program, "Fills", 0);
let next_fills_storage_buffer = device.get_storage_buffer(&program, "NextFills", 1);
let fill_tile_map_storage_buffer = device.get_storage_buffer(&program, "FillTileMap", 2);
FillComputeProgram {
program,
dest_image,
area_lut_texture,
first_tile_index_uniform,
fills_storage_buffer,
next_fills_storage_buffer,
fill_tile_map_storage_buffer,
}
}
}
pub struct TileProgram<D> where D: Device {
pub program: D::Program,
pub transform_uniform: D::Uniform,
pub tile_size_uniform: D::Uniform,
pub texture_metadata_texture: D::TextureParameter,
pub texture_metadata_size_uniform: D::Uniform,
pub dest_texture: D::TextureParameter,
pub z_buffer_texture: D::TextureParameter,
pub z_buffer_texture_size_uniform: D::Uniform,
pub color_texture_0: D::TextureParameter,
pub color_texture_size_0_uniform: D::Uniform,
pub color_texture_1: D::TextureParameter,
pub mask_texture_0: D::TextureParameter,
pub mask_texture_size_0_uniform: D::Uniform,
pub gamma_lut_texture: D::TextureParameter,
pub filter_params_0_uniform: D::Uniform,
pub filter_params_1_uniform: D::Uniform,
pub filter_params_2_uniform: D::Uniform,
pub framebuffer_size_uniform: D::Uniform,
pub ctrl_uniform: D::Uniform,
}
impl<D> TileProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgram<D> {
let program = device.create_raster_program(resources, "tile");
let transform_uniform = device.get_uniform(&program, "Transform");
impl<D> TileProgramCommon<D> where D: Device {
pub(crate) fn new(device: &D, program: D::Program) -> TileProgramCommon<D> {
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let texture_metadata_texture = device.get_texture_parameter(&program, "TextureMetadata");
let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize");
let dest_texture = device.get_texture_parameter(&program, "DestTexture");
let z_buffer_texture = device.get_texture_parameter(&program, "ZBuffer");
let z_buffer_texture_size_uniform = device.get_uniform(&program, "ZBufferSize");
let color_texture_0 = device.get_texture_parameter(&program, "ColorTexture0");
let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0");
let color_texture_1 = device.get_texture_parameter(&program, "ColorTexture1");
let mask_texture_0 = device.get_texture_parameter(&program, "MaskTexture0");
let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0");
let gamma_lut_texture = device.get_texture_parameter(&program, "GammaLUT");
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");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let ctrl_uniform = device.get_uniform(&program, "Ctrl");
TileProgram {
TileProgramCommon {
program,
transform_uniform,
tile_size_uniform,
texture_metadata_texture,
texture_metadata_size_uniform,
dest_texture,
z_buffer_texture,
z_buffer_texture_size_uniform,
color_texture_0,
color_texture_size_0_uniform,
color_texture_1,
mask_texture_0,
mask_texture_size_0_uniform,
gamma_lut_texture,
filter_params_0_uniform,
filter_params_1_uniform,
filter_params_2_uniform,
framebuffer_size_uniform,
ctrl_uniform,
}
}
}
pub struct CopyTileProgram<D> where D: Device {
pub program: D::Program,
pub transform_uniform: D::Uniform,
pub tile_size_uniform: D::Uniform,
pub framebuffer_size_uniform: D::Uniform,
pub src_texture: D::TextureParameter,
}
impl<D> CopyTileProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> CopyTileProgram<D> {
let program = device.create_raster_program(resources, "tile_copy");
let transform_uniform = device.get_uniform(&program, "Transform");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let src_texture = device.get_texture_parameter(&program, "Src");
CopyTileProgram {
program,
transform_uniform,
tile_size_uniform,
framebuffer_size_uniform,
src_texture,
}
}
}
pub struct ClipTileProgram<D> where D: Device {
pub program: D::Program,
pub src_texture: D::TextureParameter,
}
impl<D> ClipTileProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> ClipTileProgram<D> {
let program = device.create_raster_program(resources, "tile_clip");
let src_texture = device.get_texture_parameter(&program, "Src");
ClipTileProgram { program, src_texture }
}
}
pub struct StencilProgram<D>
where
D: Device,
{
pub struct StencilProgram<D> where D: Device {
pub program: D::Program,
}
impl<D> StencilProgram<D>
where
D: Device,
{
impl<D> StencilProgram<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
let program = device.create_raster_program(resources, "stencil");
StencilProgram { program }
}
}
pub struct StencilVertexArray<D>
where
D: Device,
{
pub struct StencilVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
pub vertex_buffer: D::Buffer,
pub index_buffer: D::Buffer,
}
impl<D> StencilVertexArray<D>
where
D: Device,
{
impl<D> StencilVertexArray<D> where D: Device {
pub fn new(device: &D, stencil_program: &StencilProgram<D>) -> StencilVertexArray<D> {
let vertex_array = device.create_vertex_array();
let vertex_buffer = device.create_buffer(BufferUploadMode::Static);
@ -628,17 +245,11 @@ impl<D> ReprojectionProgram<D> where D: Device {
}
}
pub struct ReprojectionVertexArray<D>
where
D: Device,
{
pub struct ReprojectionVertexArray<D> where D: Device {
pub vertex_array: D::VertexArray,
}
impl<D> ReprojectionVertexArray<D>
where
D: Device,
{
impl<D> ReprojectionVertexArray<D> where D: Device {
pub fn new(
device: &D,
reprojection_program: &ReprojectionProgram<D>,

View File

@ -0,0 +1,86 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#extension GL_GOOGLE_include_directive : enable
precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in uvec2 aTessCoord;
in uvec4 aLineSegment;
in int aTileIndex;
out vec2 vFrom;
out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize){
uint tilesPerRow = uint(stencilTextureWidth / tileSize . x);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset)* tileSize * vec2(1.0, 0.25);
}
vec4 computeVertexPosition(uint tileIndex,
uvec2 tessCoord,
uvec4 packedLineSegment,
vec2 tileSize,
vec2 framebufferSize,
out vec2 outFrom,
out vec2 outTo){
vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize . x, tileSize);
vec4 lineSegment = vec4(packedLineSegment)/ 256.0;
vec2 from = lineSegment . xy, to = lineSegment . zw;
vec2 position;
if(tessCoord . x == 0u)
position . x = floor(min(from . x, to . x));
else
position . x = ceil(max(from . x, to . x));
if(tessCoord . y == 0u)
position . y = floor(min(from . y, to . y));
else
position . y = tileSize . y;
position . y = floor(position . y * 0.25);
vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0);
outFrom = from + offset;
outTo = to + offset;
vec2 globalPosition =(tileOrigin + position)/ framebufferSize * 2.0 - 1.0;
return vec4(globalPosition, 0.0, 1.0);
}
void main(){
gl_Position = computeVertexPosition(uint(aTileIndex),
aTessCoord,
aLineSegment,
uTileSize,
uFramebufferSize,
vFrom,
vTo);
}

View File

@ -12,27 +12,6 @@
#extension GL_GOOGLE_include_directive : enable
precision highp float;
@ -83,24 +62,37 @@ precision highp float;
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 int uCtrl;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
out vec4 oFragColor;
@ -567,27 +559,42 @@ float sampleMask(float maskAlpha,
void calculateColor(int tileCtrl, int ctrl){
vec4 calculateColor(vec2 fragCoord,
sampler2D colorTexture0,
sampler2D maskTexture0,
sampler2D destTexture,
sampler2D gammaLUT,
vec2 colorTextureSize0,
vec2 maskTextureSize0,
vec4 filterParams0,
vec4 filterParams1,
vec4 filterParams2,
vec2 framebufferSize,
int ctrl,
vec3 maskTexCoord0,
vec2 colorTexCoord0,
vec4 baseColor,
int tileCtrl){
int maskCtrl0 =(tileCtrl >> 0)& 0x3;
float maskAlpha = 1.0;
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0);
vec4 color = vBaseColor;
vec4 color = baseColor;
int color0Combine =(ctrl >> 6)&
0x3;
if(color0Combine != 0){
int color0Filter =(ctrl >> 4)& 0x3;
vec4 color0 = filterColor(vColorTexCoord0,
uColorTexture0,
uGammaLUT,
uColorTextureSize0,
gl_FragCoord . xy,
uFramebufferSize,
uFilterParams0,
uFilterParams1,
uFilterParams2,
vec4 color0 = filterColor(colorTexCoord0,
colorTexture0,
gammaLUT,
colorTextureSize0,
fragCoord,
framebufferSize,
filterParams0,
filterParams1,
filterParams2,
color0Filter);
color = combineColor0(color, color0, color0Combine);
}
@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){
int compositeOp =(ctrl >> 8)& 0xf;
color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord . xy, compositeOp);
color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp);
color . rgb *= color . a;
oFragColor = color;
return color;
}
uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT;
uniform vec2 uColorTextureSize0;
uniform vec2 uMaskTextureSize0;
uniform vec2 uFramebufferSize;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
in vec4 vFilterParams0;
in vec4 vFilterParams1;
in vec4 vFilterParams2;
in float vCtrl;
out vec4 oFragColor;
void main(){
calculateColor(int(vTileCtrl), uCtrl);
oFragColor = calculateColor(gl_FragCoord . xy,
uColorTexture0,
uMaskTexture0,
uDestTexture,
uGammaLUT,
uColorTextureSize0,
uMaskTextureSize0,
vFilterParams0,
vFilterParams1,
vFilterParams2,
uFramebufferSize,
int(vCtrl),
vMaskTexCoord0,
vColorTexCoord0,
vBaseColor,
int(vTileCtrl));
}

View File

@ -0,0 +1,123 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#extension GL_GOOGLE_include_directive : enable
precision highp float;
vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry){
return texture(srcTexture,(originCoord + vec2(0.5)+ vec2(entry, 0))* scale);
}
void computeTileVaryings(vec2 position,
int colorEntry,
sampler2D textureMetadata,
ivec2 textureMetadataSize,
out vec2 outColorTexCoord0,
out vec4 outBaseColor,
out vec4 outFilterParams0,
out vec4 outFilterParams1,
out vec4 outFilterParams2,
out int outCtrl){
vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize);
vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128);
vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0);
vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1);
vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2);
vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3);
vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4);
vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5);
vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6);
outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy;
outBaseColor = baseColor;
outFilterParams0 = filterParams0;
outFilterParams1 = filterParams1;
outFilterParams2 = filterParams2;
outCtrl = int(extra . x);
}
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
uniform sampler2D uZBuffer;
uniform ivec2 uZBufferSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec4 aMaskTexCoord0;
in ivec2 aCtrlBackdrop;
in int aPathIndex;
in int aColor;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
out vec4 vFilterParams0;
out vec4 vFilterParams1;
out vec4 vFilterParams2;
out float vCtrl;
void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize;
ivec4 zValue = ivec4(texture(uZBuffer,(tileOrigin + vec2(0.5))/ vec2(uZBufferSize))* 255.0);
if(aPathIndex <(zValue . x |(zValue . y << 8)|(zValue . z << 16)|(zValue . w << 24))){
gl_Position = vec4(0.0);
return;
}
uvec2 maskTileCoord = uvec2(aMaskTexCoord0 . x, aMaskTexCoord0 . y + 256u * aMaskTexCoord0 . z);
vec2 maskTexCoord0 =(vec2(maskTileCoord)+ tileOffset)* uTileSize;
if(aCtrlBackdrop . y == 0 && aMaskTexCoord0 . w != 0u){
gl_Position = vec4(0.0);
return;
}
int ctrl;
computeTileVaryings(position,
aColor,
uTextureMetadata,
uTextureMetadataSize,
vColorTexCoord0,
vBaseColor,
vFilterParams0,
vFilterParams1,
vFilterParams2,
ctrl);
vTileCtrl = float(aCtrlBackdrop . x);
vCtrl = float(ctrl);
vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop . y));
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -0,0 +1,34 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform sampler2D uSrc;
in vec2 vTexCoord0;
in float vBackdrop0;
in vec2 vTexCoord1;
in float vBackdrop1;
out vec4 oFragColor;
void main(){
oFragColor = min(abs(texture(uSrc, vTexCoord0)+ vBackdrop0),
abs(texture(uSrc, vTexCoord1)+ vBackdrop1));
}

View File

@ -0,0 +1,54 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in int aDestTileIndex;
in int aDestBackdrop;
in int aSrcTileIndex;
in int aSrcBackdrop;
out vec2 vTexCoord0;
out float vBackdrop0;
out vec2 vTexCoord1;
out float vBackdrop1;
void main(){
vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256)+ aTileOffset);
vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256)+ aTileOffset);
destPosition *= vec2(16.0, 4.0)/ uFramebufferSize;
srcPosition *= vec2(16.0, 4.0)/ uFramebufferSize;
vTexCoord0 = destPosition;
vTexCoord1 = srcPosition;
vBackdrop0 = float(aDestBackdrop);
vBackdrop1 = float(aSrcBackdrop);
if(aDestTileIndex < 0)
destPosition = vec2(0.0);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0);
}

View File

@ -21,11 +21,10 @@ precision highp float;
uniform sampler2D uSrc;
in vec2 vTexCoord;
in float vBackdrop;
out vec4 oFragColor;
void main(){
oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0);
oFragColor = texture(uSrc, vTexCoord);
}

View File

@ -0,0 +1,42 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in int aTileIndex;
out vec2 vTexCoord;
void main(){
vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256)+ aTileOffset);
position *= vec2(16.0, 4.0)/ uFramebufferSize;
vTexCoord = position;
if(aTileIndex < 0)
position = vec2(0.0);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), position), 0.0, 1.0);
}

View File

@ -1,71 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx;
in vec2 aToSubpx;
in uint aTileIndex;
out vec2 vFrom;
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 * vec2(1.0, 0.25);
}
void main(){
vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize . x);
vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u)+ aFromSubpx;
vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx;
vec2 position;
if(aTessCoord . x == 0u)
position . x = floor(min(from . x, to . x));
else
position . x = ceil(max(from . x, to . x));
if(aTessCoord . y == 0u)
position . y = floor(min(from . y, to . y));
else
position . y = uTileSize . y;
position . y = floor(position . y * 0.25);
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;
gl_Position = vec4(globalPosition, 0.0, 1.0);
}

View File

@ -1,59 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec2 aMaskTexCoord0;
in ivec2 aMaskBackdrop;
in int aColor;
in int aTileCtrl;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize;
vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)* uTileSize;
vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);
vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale;
vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale;
vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale;
vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord);
vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord);
vec4 baseColor = texture(uTextureMetadata, baseColorCoord);
vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy;
vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop . x));
vBaseColor = baseColor;
vTileCtrl = float(aTileCtrl);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -1,36 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
in ivec2 aTileOffset;
in ivec2 aDestTileOrigin;
in ivec2 aSrcTileOrigin;
in int aSrcBackdrop;
out vec2 vTexCoord;
out float vBackdrop;
void main(){
vec2 destPosition = vec2(aDestTileOrigin + aTileOffset)/ vec2(256.0);
vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset)/ vec2(256.0);
vTexCoord = srcPosition;
vBackdrop = float(aSrcBackdrop);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0);
}

View File

@ -0,0 +1,86 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#extension GL_GOOGLE_include_directive : enable
precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in uvec2 aTessCoord;
in uvec4 aLineSegment;
in int aTileIndex;
out vec2 vFrom;
out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize){
uint tilesPerRow = uint(stencilTextureWidth / tileSize . x);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset)* tileSize * vec2(1.0, 0.25);
}
vec4 computeVertexPosition(uint tileIndex,
uvec2 tessCoord,
uvec4 packedLineSegment,
vec2 tileSize,
vec2 framebufferSize,
out vec2 outFrom,
out vec2 outTo){
vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize . x, tileSize);
vec4 lineSegment = vec4(packedLineSegment)/ 256.0;
vec2 from = lineSegment . xy, to = lineSegment . zw;
vec2 position;
if(tessCoord . x == 0u)
position . x = floor(min(from . x, to . x));
else
position . x = ceil(max(from . x, to . x));
if(tessCoord . y == 0u)
position . y = floor(min(from . y, to . y));
else
position . y = tileSize . y;
position . y = floor(position . y * 0.25);
vec2 offset = vec2(0.0, 1.5)- position * vec2(1.0, 4.0);
outFrom = from + offset;
outTo = to + offset;
vec2 globalPosition =(tileOrigin + position)/ framebufferSize * 2.0 - 1.0;
return vec4(globalPosition, 0.0, 1.0);
}
void main(){
gl_Position = computeVertexPosition(uint(aTileIndex),
aTessCoord,
aLineSegment,
uTileSize,
uFramebufferSize,
vFrom,
vTo);
}

View File

@ -12,27 +12,6 @@
#extension GL_GOOGLE_include_directive : enable
precision highp float;
@ -83,24 +62,37 @@ precision highp float;
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 int uCtrl;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
out vec4 oFragColor;
@ -567,27 +559,42 @@ float sampleMask(float maskAlpha,
void calculateColor(int tileCtrl, int ctrl){
vec4 calculateColor(vec2 fragCoord,
sampler2D colorTexture0,
sampler2D maskTexture0,
sampler2D destTexture,
sampler2D gammaLUT,
vec2 colorTextureSize0,
vec2 maskTextureSize0,
vec4 filterParams0,
vec4 filterParams1,
vec4 filterParams2,
vec2 framebufferSize,
int ctrl,
vec3 maskTexCoord0,
vec2 colorTexCoord0,
vec4 baseColor,
int tileCtrl){
int maskCtrl0 =(tileCtrl >> 0)& 0x3;
float maskAlpha = 1.0;
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0);
vec4 color = vBaseColor;
vec4 color = baseColor;
int color0Combine =(ctrl >> 6)&
0x3;
if(color0Combine != 0){
int color0Filter =(ctrl >> 4)& 0x3;
vec4 color0 = filterColor(vColorTexCoord0,
uColorTexture0,
uGammaLUT,
uColorTextureSize0,
gl_FragCoord . xy,
uFramebufferSize,
uFilterParams0,
uFilterParams1,
uFilterParams2,
vec4 color0 = filterColor(colorTexCoord0,
colorTexture0,
gammaLUT,
colorTextureSize0,
fragCoord,
framebufferSize,
filterParams0,
filterParams1,
filterParams2,
color0Filter);
color = combineColor0(color, color0, color0Combine);
}
@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){
int compositeOp =(ctrl >> 8)& 0xf;
color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord . xy, compositeOp);
color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp);
color . rgb *= color . a;
oFragColor = color;
return color;
}
uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT;
uniform vec2 uColorTextureSize0;
uniform vec2 uMaskTextureSize0;
uniform vec2 uFramebufferSize;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
in vec4 vFilterParams0;
in vec4 vFilterParams1;
in vec4 vFilterParams2;
in float vCtrl;
out vec4 oFragColor;
void main(){
calculateColor(int(vTileCtrl), uCtrl);
oFragColor = calculateColor(gl_FragCoord . xy,
uColorTexture0,
uMaskTexture0,
uDestTexture,
uGammaLUT,
uColorTextureSize0,
uMaskTextureSize0,
vFilterParams0,
vFilterParams1,
vFilterParams2,
uFramebufferSize,
int(vCtrl),
vMaskTexCoord0,
vColorTexCoord0,
vBaseColor,
int(vTileCtrl));
}

View File

@ -0,0 +1,123 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#extension GL_GOOGLE_include_directive : enable
precision highp float;
vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry){
return texture(srcTexture,(originCoord + vec2(0.5)+ vec2(entry, 0))* scale);
}
void computeTileVaryings(vec2 position,
int colorEntry,
sampler2D textureMetadata,
ivec2 textureMetadataSize,
out vec2 outColorTexCoord0,
out vec4 outBaseColor,
out vec4 outFilterParams0,
out vec4 outFilterParams1,
out vec4 outFilterParams2,
out int outCtrl){
vec2 metadataScale = vec2(1.0)/ vec2(textureMetadataSize);
vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128);
vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0);
vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1);
vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2);
vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3);
vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4);
vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5);
vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6);
outColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy;
outBaseColor = baseColor;
outFilterParams0 = filterParams0;
outFilterParams1 = filterParams1;
outFilterParams2 = filterParams2;
outCtrl = int(extra . x);
}
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
uniform sampler2D uZBuffer;
uniform ivec2 uZBufferSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec4 aMaskTexCoord0;
in ivec2 aCtrlBackdrop;
in int aPathIndex;
in int aColor;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
out vec4 vFilterParams0;
out vec4 vFilterParams1;
out vec4 vFilterParams2;
out float vCtrl;
void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize;
ivec4 zValue = ivec4(texture(uZBuffer,(tileOrigin + vec2(0.5))/ vec2(uZBufferSize))* 255.0);
if(aPathIndex <(zValue . x |(zValue . y << 8)|(zValue . z << 16)|(zValue . w << 24))){
gl_Position = vec4(0.0);
return;
}
uvec2 maskTileCoord = uvec2(aMaskTexCoord0 . x, aMaskTexCoord0 . y + 256u * aMaskTexCoord0 . z);
vec2 maskTexCoord0 =(vec2(maskTileCoord)+ tileOffset)* uTileSize;
if(aCtrlBackdrop . y == 0 && aMaskTexCoord0 . w != 0u){
gl_Position = vec4(0.0);
return;
}
int ctrl;
computeTileVaryings(position,
aColor,
uTextureMetadata,
uTextureMetadataSize,
vColorTexCoord0,
vBaseColor,
vFilterParams0,
vFilterParams1,
vFilterParams2,
ctrl);
vTileCtrl = float(aCtrlBackdrop . x);
vCtrl = float(ctrl);
vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop . y));
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -0,0 +1,34 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform sampler2D uSrc;
in vec2 vTexCoord0;
in float vBackdrop0;
in vec2 vTexCoord1;
in float vBackdrop1;
out vec4 oFragColor;
void main(){
oFragColor = min(abs(texture(uSrc, vTexCoord0)+ vBackdrop0),
abs(texture(uSrc, vTexCoord1)+ vBackdrop1));
}

View File

@ -0,0 +1,54 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in int aDestTileIndex;
in int aDestBackdrop;
in int aSrcTileIndex;
in int aSrcBackdrop;
out vec2 vTexCoord0;
out float vBackdrop0;
out vec2 vTexCoord1;
out float vBackdrop1;
void main(){
vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256)+ aTileOffset);
vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256)+ aTileOffset);
destPosition *= vec2(16.0, 4.0)/ uFramebufferSize;
srcPosition *= vec2(16.0, 4.0)/ uFramebufferSize;
vTexCoord0 = destPosition;
vTexCoord1 = srcPosition;
vBackdrop0 = float(aDestBackdrop);
vBackdrop1 = float(aSrcBackdrop);
if(aDestTileIndex < 0)
destPosition = vec2(0.0);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0);
}

View File

@ -21,11 +21,10 @@ precision highp float;
uniform sampler2D uSrc;
in vec2 vTexCoord;
in float vBackdrop;
out vec4 oFragColor;
void main(){
oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0);
oFragColor = texture(uSrc, vTexCoord);
}

View File

@ -0,0 +1,42 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in int aTileIndex;
out vec2 vTexCoord;
void main(){
vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256)+ aTileOffset);
position *= vec2(16.0, 4.0)/ uFramebufferSize;
vTexCoord = position;
if(aTileIndex < 0)
position = vec2(0.0);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), position), 0.0, 1.0);
}

View File

@ -1,71 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx;
in vec2 aToSubpx;
in uint aTileIndex;
out vec2 vFrom;
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 * vec2(1.0, 0.25);
}
void main(){
vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize . x);
vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u)+ aFromSubpx;
vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx;
vec2 position;
if(aTessCoord . x == 0u)
position . x = floor(min(from . x, to . x));
else
position . x = ceil(max(from . x, to . x));
if(aTessCoord . y == 0u)
position . y = floor(min(from . y, to . y));
else
position . y = uTileSize . y;
position . y = floor(position . y * 0.25);
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;
gl_Position = vec4(globalPosition, 0.0, 1.0);
}

View File

@ -1,59 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec2 aMaskTexCoord0;
in ivec2 aMaskBackdrop;
in int aColor;
in int aTileCtrl;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize;
vec2 maskTexCoord0 =(vec2(aMaskTexCoord0)+ tileOffset)* uTileSize;
vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);
vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale;
vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale;
vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale;
vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord);
vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord);
vec4 baseColor = texture(uTextureMetadata, baseColorCoord);
vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy;
vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop . x));
vBaseColor = baseColor;
vTileCtrl = float(aTileCtrl);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -1,36 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
in ivec2 aTileOffset;
in ivec2 aDestTileOrigin;
in ivec2 aSrcTileOrigin;
in int aSrcBackdrop;
out vec2 vTexCoord;
out float vBackdrop;
void main(){
vec2 destPosition = vec2(aDestTileOrigin + aTileOffset)/ vec2(256.0);
vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset)/ vec2(256.0);
vTexCoord = srcPosition;
vBackdrop = float(aSrcBackdrop);
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), destPosition), 0.0, 1.0);
}

View File

@ -1,708 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#extension GL_GOOGLE_include_directive : enable
precision highp float;
precision highp sampler2D;
uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT;
uniform vec4 uFilterParams0;
uniform vec4 uFilterParams1;
uniform vec4 uFilterParams2;
uniform vec2 uFramebufferSize;
uniform vec2 uColorTextureSize0;
uniform int uCtrl;
uniform sampler2D uAreaLUT;
layout(std430, binding = 0)buffer bFills {
restrict readonly uvec2 iFills[];
};
layout(std430, binding = 1)buffer bNextFills {
restrict readonly int iNextFills[];
};
layout(std430, binding = 2)buffer bFillTileMap {
restrict readonly int iFillTileMap[];
};
in vec2 vTileSubCoord;
flat in uint vMaskTileIndex0;
flat in int vMaskTileBackdrop0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
out vec4 oFragColor;
vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT){
vec2 left = from . x < to . x ? from : to, right = from . x < to . x ? to : from;
vec2 window = clamp(vec2(from . x, to . x), - 0.5, 0.5);
float offset = mix(window . x, window . y, 0.5)- left . x;
float t = offset /(right . x - left . x);
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 texture(areaLUT, vec2(y + 8.0, abs(d * dX))/ 16.0)* dX;
}
vec4 computeCoverage(vec2 from, vec2 to, sampler2D areaLUT);
ivec2 calculateTileOrigin(uint tileIndex){
return ivec2(tileIndex & 0xff,(tileIndex >> 8u)& 0xff)* 16;
}
vec4 calculateFillAlpha(ivec2 tileSubCoord, uint tileIndex){
int fillIndex = iFillTileMap[tileIndex];
if(fillIndex < 0)
return vec4(0.0);
vec4 coverages = vec4(0.0);
do {
uvec2 fill = iFills[fillIndex];
vec2 from = vec2(fill . y & 0xf,(fill . y >> 4u)& 0xf)+
vec2(fill . x & 0xff,(fill . x >> 8u)& 0xff)/ 256.0;
vec2 to = vec2((fill . y >> 8u)& 0xf,(fill . y >> 12u)& 0xf)+
vec2((fill . x >> 16u)& 0xff,(fill . x >> 24u)& 0xff)/ 256.0;
coverages += computeCoverage(from -(vec2(tileSubCoord)+ vec2(0.5)),
to -(vec2(tileSubCoord)+ vec2(0.5)),
uAreaLUT);
fillIndex = iNextFills[fillIndex];
} while(fillIndex >= 0);
return coverages;
}
vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord){
return texture(colorTexture, colorTexCoord);
}
vec4 combineColor0(vec4 destColor, vec4 srcColor, int op){
switch(op){
case 0x1 :
return vec4(srcColor . rgb, srcColor . a * destColor . a);
case 0x2 :
return vec4(destColor . rgb, srcColor . a * destColor . a);
}
return destColor;
}
float filterTextSample1Tap(float offset, sampler2D colorTexture, vec2 colorTexCoord){
return texture(colorTexture, colorTexCoord + vec2(offset, 0.0)). r;
}
void filterTextSample9Tap(out vec4 outAlphaLeft,
out float outAlphaCenter,
out vec4 outAlphaRight,
sampler2D colorTexture,
vec2 colorTexCoord,
vec4 kernel,
float onePixel){
bool wide = kernel . x > 0.0;
outAlphaLeft =
vec4(wide ? filterTextSample1Tap(- 4.0 * onePixel, colorTexture, colorTexCoord): 0.0,
filterTextSample1Tap(- 3.0 * onePixel, colorTexture, colorTexCoord),
filterTextSample1Tap(- 2.0 * onePixel, colorTexture, colorTexCoord),
filterTextSample1Tap(- 1.0 * onePixel, colorTexture, colorTexCoord));
outAlphaCenter = filterTextSample1Tap(0.0, colorTexture, colorTexCoord);
outAlphaRight =
vec4(filterTextSample1Tap(1.0 * onePixel, colorTexture, colorTexCoord),
filterTextSample1Tap(2.0 * onePixel, colorTexture, colorTexCoord),
filterTextSample1Tap(3.0 * onePixel, colorTexture, colorTexCoord),
wide ? filterTextSample1Tap(4.0 * onePixel, colorTexture, colorTexCoord): 0.0);
}
float filterTextConvolve7Tap(vec4 alpha0, vec3 alpha1, vec4 kernel){
return dot(alpha0, kernel)+ dot(alpha1, kernel . zyx);
}
float filterTextGammaCorrectChannel(float bgColor, float fgColor, sampler2D gammaLUT){
return texture(gammaLUT, vec2(fgColor, 1.0 - bgColor)). r;
}
vec3 filterTextGammaCorrect(vec3 bgColor, vec3 fgColor, sampler2D gammaLUT){
return vec3(filterTextGammaCorrectChannel(bgColor . r, fgColor . r, gammaLUT),
filterTextGammaCorrectChannel(bgColor . g, fgColor . g, gammaLUT),
filterTextGammaCorrectChannel(bgColor . b, fgColor . b, gammaLUT));
}
vec4 filterText(vec2 colorTexCoord,
sampler2D colorTexture,
sampler2D gammaLUT,
vec2 colorTextureSize,
vec4 filterParams0,
vec4 filterParams1,
vec4 filterParams2){
vec4 kernel = filterParams0;
vec3 bgColor = filterParams1 . rgb;
vec3 fgColor = filterParams2 . rgb;
bool gammaCorrectionEnabled = filterParams2 . a != 0.0;
vec3 alpha;
if(kernel . w == 0.0){
alpha = texture(colorTexture, colorTexCoord). rrr;
} else {
vec4 alphaLeft, alphaRight;
float alphaCenter;
filterTextSample9Tap(alphaLeft,
alphaCenter,
alphaRight,
colorTexture,
colorTexCoord,
kernel,
1.0 / colorTextureSize . x);
float r = filterTextConvolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight . xy), kernel);
float g = filterTextConvolve7Tap(vec4(alphaLeft . yzw, alphaCenter), alphaRight . xyz, kernel);
float b = filterTextConvolve7Tap(vec4(alphaLeft . zw, alphaCenter, alphaRight . x),
alphaRight . yzw,
kernel);
alpha = vec3(r, g, b);
}
if(gammaCorrectionEnabled)
alpha = filterTextGammaCorrect(bgColor, alpha, gammaLUT);
return vec4(mix(bgColor, fgColor, alpha), 1.0);
}
vec4 filterRadialGradient(vec2 colorTexCoord,
sampler2D colorTexture,
vec2 colorTextureSize,
vec2 fragCoord,
vec2 framebufferSize,
vec4 filterParams0,
vec4 filterParams1){
vec2 lineFrom = filterParams0 . xy, lineVector = filterParams0 . zw;
vec2 radii = filterParams1 . xy, uvOrigin = filterParams1 . zw;
vec2 dP = colorTexCoord - lineFrom, dC = lineVector;
float dR = radii . y - radii . x;
float a = dot(dC, dC)- dR * dR;
float b = dot(dP, dC)+ radii . x * dR;
float c = dot(dP, dP)- radii . x * radii . x;
float discrim = b * b - a * c;
vec4 color = vec4(0.0);
if(abs(discrim)>= 0.00001){
vec2 ts = vec2(sqrt(discrim)* vec2(1.0, - 1.0)+ vec2(b))/ vec2(a);
if(ts . x > ts . y)
ts = ts . yx;
float t = ts . x >= 0.0 ? ts . x : ts . y;
color = texture(colorTexture, uvOrigin + vec2(clamp(t, 0.0, 1.0), 0.0));
}
return color;
}
vec4 filterBlur(vec2 colorTexCoord,
sampler2D colorTexture,
vec2 colorTextureSize,
vec4 filterParams0,
vec4 filterParams1){
vec2 srcOffsetScale = filterParams0 . xy / colorTextureSize;
int support = int(filterParams0 . z);
vec3 gaussCoeff = filterParams1 . xyz;
float gaussSum = gaussCoeff . x;
vec4 color = texture(colorTexture, colorTexCoord)* gaussCoeff . x;
gaussCoeff . xy *= gaussCoeff . yz;
for(int i = 1;i <= support;i += 2){
float gaussPartialSum = gaussCoeff . x;
gaussCoeff . xy *= gaussCoeff . yz;
gaussPartialSum += gaussCoeff . x;
vec2 srcOffset = srcOffsetScale *(float(i)+ gaussCoeff . x / gaussPartialSum);
color +=(texture(colorTexture, colorTexCoord - srcOffset)+
texture(colorTexture, colorTexCoord + srcOffset))* gaussPartialSum;
gaussSum += 2.0 * gaussPartialSum;
gaussCoeff . xy *= gaussCoeff . yz;
}
return color / gaussSum;
}
vec4 filterNone(vec2 colorTexCoord, sampler2D colorTexture){
return sampleColor(colorTexture, colorTexCoord);
}
vec4 filterColor(vec2 colorTexCoord,
sampler2D colorTexture,
sampler2D gammaLUT,
vec2 colorTextureSize,
vec2 fragCoord,
vec2 framebufferSize,
vec4 filterParams0,
vec4 filterParams1,
vec4 filterParams2,
int colorFilter){
switch(colorFilter){
case 0x1 :
return filterRadialGradient(colorTexCoord,
colorTexture,
colorTextureSize,
fragCoord,
framebufferSize,
filterParams0,
filterParams1);
case 0x3 :
return filterBlur(colorTexCoord,
colorTexture,
colorTextureSize,
filterParams0,
filterParams1);
case 0x2 :
return filterText(colorTexCoord,
colorTexture,
gammaLUT,
colorTextureSize,
filterParams0,
filterParams1,
filterParams2);
}
return filterNone(colorTexCoord, colorTexture);
}
vec3 compositeSelect(bvec3 cond, vec3 ifTrue, vec3 ifFalse){
return vec3(cond . x ? ifTrue . x : ifFalse . x,
cond . y ? ifTrue . y : ifFalse . y,
cond . z ? ifTrue . z : ifFalse . z);
}
float compositeDivide(float num, float denom){
return denom != 0.0 ? num / denom : 0.0;
}
vec3 compositeColorDodge(vec3 destColor, vec3 srcColor){
bvec3 destZero = equal(destColor, vec3(0.0)), srcOne = equal(srcColor, vec3(1.0));
return compositeSelect(destZero,
vec3(0.0),
compositeSelect(srcOne, vec3(1.0), destColor /(vec3(1.0)- srcColor)));
}
vec3 compositeHSLToRGB(vec3 hsl){
float a = hsl . y * min(hsl . z, 1.0 - hsl . z);
vec3 ks = mod(vec3(0.0, 8.0, 4.0)+ vec3(hsl . x * 1.9098593171027443), 12.0);
return hsl . zzz - clamp(min(ks - vec3(3.0), vec3(9.0)- ks), - 1.0, 1.0)* a;
}
vec3 compositeRGBToHSL(vec3 rgb){
float v = max(max(rgb . r, rgb . g), rgb . b), xMin = min(min(rgb . r, rgb . g), rgb . b);
float c = v - xMin, l = mix(xMin, v, 0.5);
vec3 terms = rgb . r == v ? vec3(0.0, rgb . gb):
rgb . g == v ? vec3(2.0, rgb . br):
vec3(4.0, rgb . rg);
float h = 1.0471975511965976 * compositeDivide(terms . x * c + terms . y - terms . z, c);
float s = compositeDivide(c, v);
return vec3(h, s, l);
}
vec3 compositeScreen(vec3 destColor, vec3 srcColor){
return destColor + srcColor - destColor * srcColor;
}
vec3 compositeHardLight(vec3 destColor, vec3 srcColor){
return compositeSelect(lessThanEqual(srcColor, vec3(0.5)),
destColor * vec3(2.0)* srcColor,
compositeScreen(destColor, vec3(2.0)* srcColor - vec3(1.0)));
}
vec3 compositeSoftLight(vec3 destColor, vec3 srcColor){
vec3 darkenedDestColor =
compositeSelect(lessThanEqual(destColor, vec3(0.25)),
((vec3(16.0)* destColor - 12.0)* destColor + 4.0)* destColor,
sqrt(destColor));
vec3 factor = compositeSelect(lessThanEqual(srcColor, vec3(0.5)),
destColor *(vec3(1.0)- destColor),
darkenedDestColor - destColor);
return destColor +(srcColor * 2.0 - 1.0)* factor;
}
vec3 compositeHSL(vec3 destColor, vec3 srcColor, int op){
switch(op){
case 0xc :
return vec3(srcColor . x, destColor . y, destColor . z);
case 0xd :
return vec3(destColor . x, srcColor . y, destColor . z);
case 0xe :
return vec3(srcColor . x, srcColor . y, destColor . z);
default :
return vec3(destColor . x, destColor . y, srcColor . z);
}
}
vec3 compositeRGB(vec3 destColor, vec3 srcColor, int op){
switch(op){
case 0x1 :
return destColor * srcColor;
case 0x2 :
return compositeScreen(destColor, srcColor);
case 0x3 :
return compositeHardLight(srcColor, destColor);
case 0x4 :
return min(destColor, srcColor);
case 0x5 :
return max(destColor, srcColor);
case 0x6 :
return compositeColorDodge(destColor, srcColor);
case 0x7 :
return vec3(1.0)- compositeColorDodge(vec3(1.0)- destColor, vec3(1.0)- srcColor);
case 0x8 :
return compositeHardLight(destColor, srcColor);
case 0x9 :
return compositeSoftLight(destColor, srcColor);
case 0xa :
return abs(destColor - srcColor);
case 0xb :
return destColor + srcColor - vec3(2.0)* destColor * srcColor;
case 0xc :
case 0xd :
case 0xe :
case 0xf :
return compositeHSLToRGB(compositeHSL(compositeRGBToHSL(destColor),
compositeRGBToHSL(srcColor),
op));
}
return srcColor;
}
vec4 composite(vec4 srcColor,
sampler2D destTexture,
vec2 destTextureSize,
vec2 fragCoord,
int op){
if(op == 0x0)
return srcColor;
vec2 destTexCoord = fragCoord / destTextureSize;
vec4 destColor = texture(destTexture, destTexCoord);
vec3 blendedRGB = compositeRGB(destColor . rgb, srcColor . rgb, op);
return vec4(srcColor . a *(1.0 - destColor . a)* srcColor . rgb +
srcColor . a * destColor . a * blendedRGB +
(1.0 - srcColor . a)* destColor . rgb,
1.0);
}
float sampleMask(float maskAlpha,
sampler2D maskTexture,
vec2 maskTextureSize,
vec3 maskTexCoord,
int maskCtrl){
if(maskCtrl == 0)
return maskAlpha;
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
coverage = 1.0 - abs(1.0 - mod(coverage, 2.0));
return min(maskAlpha, coverage);
}
vec4 calculateColorWithMaskAlpha(float maskAlpha,
vec4 baseColor,
vec2 colorTexCoord0,
vec2 fragCoord,
int ctrl){
vec4 color = baseColor;
int color0Combine =(ctrl >> 6)&
0x3;
if(color0Combine != 0){
int color0Filter =(ctrl >> 4)& 0x3;
vec4 color0 = filterColor(colorTexCoord0,
uColorTexture0,
uGammaLUT,
uColorTextureSize0,
fragCoord,
uFramebufferSize,
uFilterParams0,
uFilterParams1,
uFilterParams2,
color0Filter);
color = combineColor0(color, color0, color0Combine);
}
color . a *= maskAlpha;
color . rgb *= color . a;
return color;
}
vec4 calculateColor(int tileCtrl, int ctrl){
float maskAlpha = 1.0;
int maskCtrl0 =(ctrl >> 0)& 0x1;
int maskTileCtrl0 =(tileCtrl >> 0)& 0x3;
uint maskTileIndex0 = vMaskTileIndex0;
if(maskCtrl0 != 0 && maskTileCtrl0 != 0){
ivec2 tileSubCoord = ivec2(floor(vTileSubCoord));
vec4 alphas = calculateFillAlpha(tileSubCoord, maskTileIndex0)+ float(vMaskTileBackdrop0);
maskAlpha = alphas . x;
}
return calculateColorWithMaskAlpha(maskAlpha,
vBaseColor,
vColorTexCoord0,
gl_FragCoord . xy,
ctrl);
}
void main(){
oFragColor = calculateColor(int(vTileCtrl), uCtrl);
}

View File

@ -1,58 +0,0 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
precision highp float;
precision highp sampler2D;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uint aMaskTileIndex0;
in ivec2 aMaskBackdrop;
in int aColor;
in int aTileCtrl;
out vec2 vTileSubCoord;
flat out uint vMaskTileIndex0;
flat out int vMaskTileBackdrop0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
void main(){
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position =(tileOrigin + tileOffset)* uTileSize;
vec2 textureMetadataScale = vec2(1.0)/ vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);
vec2 colorTexMatrix0Coord =(metadataEntryCoord + vec2(0.5, 0.5))* textureMetadataScale;
vec2 colorTexOffsetsCoord =(metadataEntryCoord + vec2(1.5, 0.5))* textureMetadataScale;
vec2 baseColorCoord =(metadataEntryCoord + vec2(2.5, 0.5))* textureMetadataScale;
vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord);
vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord);
vec4 baseColor = texture(uTextureMetadata, baseColorCoord);
vTileSubCoord = tileOffset * vec2(16.0);
vColorTexCoord0 = mat2(colorTexMatrix0)* position + colorTexOffsets . xy;
vMaskTileIndex0 = aMaskTileIndex0;
vMaskTileBackdrop0 = aMaskBackdrop . x;
vBaseColor = baseColor;
vTileCtrl = float(aTileCtrl);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -0,0 +1,83 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vFrom [[user(locn0)]];
float2 vTo [[user(locn1)]];
float4 gl_Position [[position]];
};
struct main0_in
{
uint2 aTessCoord [[attribute(0)]];
uint4 aLineSegment [[attribute(1)]];
int aTileIndex [[attribute(2)]];
};
static inline __attribute__((always_inline))
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread const float2& tileSize)
{
uint tilesPerRow = uint(stencilTextureWidth / tileSize.x);
uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return (float2(tileOffset) * tileSize) * float2(1.0, 0.25);
}
static inline __attribute__((always_inline))
float4 computeVertexPosition(thread const uint& tileIndex, thread const uint2& tessCoord, thread const uint4& packedLineSegment, thread const float2& tileSize, thread const float2& framebufferSize, thread float2& outFrom, thread float2& outTo)
{
uint param = tileIndex;
float param_1 = framebufferSize.x;
float2 param_2 = tileSize;
float2 tileOrigin = computeTileOffset(param, param_1, param_2);
float4 lineSegment = float4(packedLineSegment) / float4(256.0);
float2 from = lineSegment.xy;
float2 to = lineSegment.zw;
float2 position;
if (tessCoord.x == 0u)
{
position.x = floor(fast::min(from.x, to.x));
}
else
{
position.x = ceil(fast::max(from.x, to.x));
}
if (tessCoord.y == 0u)
{
position.y = floor(fast::min(from.y, to.y));
}
else
{
position.y = tileSize.y;
}
position.y = floor(position.y * 0.25);
float2 offset = float2(0.0, 1.5) - (position * float2(1.0, 4.0));
outFrom = from + offset;
outTo = to + offset;
float2 globalPosition = (((tileOrigin + position) / framebufferSize) * 2.0) - float2(1.0);
globalPosition.y = -globalPosition.y;
return float4(globalPosition, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], constant float2& uTileSize [[buffer(0)]], constant float2& uFramebufferSize [[buffer(1)]])
{
main0_out out = {};
uint param = uint(in.aTileIndex);
uint2 param_1 = in.aTessCoord;
uint4 param_2 = in.aLineSegment;
float2 param_3 = uTileSize;
float2 param_4 = uFramebufferSize;
float2 param_5;
float2 param_6;
float4 _190 = computeVertexPosition(param, param_1, param_2, param_3, param_4, param_5, param_6);
out.vFrom = param_5;
out.vTo = param_6;
out.gl_Position = _190;
return out;
}

View File

@ -6,7 +6,7 @@
using namespace metal;
constant float3 _1042 = {};
constant float3 _1056 = {};
struct main0_out
{
@ -19,6 +19,10 @@ struct main0_in
float2 vColorTexCoord0 [[user(locn1)]];
float4 vBaseColor [[user(locn2)]];
float vTileCtrl [[user(locn3)]];
float4 vFilterParams0 [[user(locn4)]];
float4 vFilterParams1 [[user(locn5)]];
float4 vFilterParams2 [[user(locn6)]];
float vCtrl [[user(locn7)]];
};
// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
@ -71,16 +75,16 @@ float4 filterRadialGradient(thread const float2& colorTexCoord, thread const tex
{
ts = ts.yx;
}
float _555;
float _569;
if (ts.x >= 0.0)
{
_555 = ts.x;
_569 = ts.x;
}
else
{
_555 = ts.y;
_569 = ts.y;
}
float t = _555;
float t = _569;
color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0)));
}
return color;
@ -94,19 +98,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 _600 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_600.x, _600.y, gaussCoeff.z);
float2 _614 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_614.x, _614.y, gaussCoeff.z);
for (int i = 1; i <= support; i += 2)
{
float gaussPartialSum = gaussCoeff.x;
float2 _620 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_620.x, _620.y, gaussCoeff.z);
float2 _634 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_634.x, _634.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 _660 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_660.x, _660.y, gaussCoeff.z);
float2 _674 = gaussCoeff.xy * gaussCoeff.yz;
gaussCoeff = float3(_674.x, _674.y, gaussCoeff.z);
}
return color / float4(gaussSum);
}
@ -121,16 +125,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 _236;
float _250;
if (wide)
{
float param = (-4.0) * onePixel;
float2 param_1 = colorTexCoord;
_236 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1);
_250 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1);
}
else
{
_236 = 0.0;
_250 = 0.0;
}
float param_2 = (-3.0) * onePixel;
float2 param_3 = colorTexCoord;
@ -138,7 +142,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(_236, filterTextSample1Tap(param_2, colorTexture, colorTextureSmplr, param_3), filterTextSample1Tap(param_4, colorTexture, colorTextureSmplr, param_5), filterTextSample1Tap(param_6, colorTexture, colorTextureSmplr, param_7));
outAlphaLeft = float4(_250, 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);
@ -148,18 +152,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen
float2 param_13 = colorTexCoord;
float param_14 = 3.0 * onePixel;
float2 param_15 = colorTexCoord;
float _296;
float _310;
if (wide)
{
float param_16 = 4.0 * onePixel;
float2 param_17 = colorTexCoord;
_296 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17);
_310 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17);
}
else
{
_296 = 0.0;
_310 = 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), _296);
outAlphaRight = float4(filterTextSample1Tap(param_10, colorTexture, colorTextureSmplr, param_11), filterTextSample1Tap(param_12, colorTexture, colorTextureSmplr, param_13), filterTextSample1Tap(param_14, colorTexture, colorTextureSmplr, param_15), _310);
}
static inline __attribute__((always_inline))
@ -309,34 +313,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 _726;
float _740;
if (cond.x)
{
_726 = ifTrue.x;
_740 = ifTrue.x;
}
else
{
_726 = ifFalse.x;
_740 = ifFalse.x;
}
float _737;
float _751;
if (cond.y)
{
_737 = ifTrue.y;
_751 = ifTrue.y;
}
else
{
_737 = ifFalse.y;
_751 = ifFalse.y;
}
float _748;
float _762;
if (cond.z)
{
_748 = ifTrue.z;
_762 = ifTrue.z;
}
else
{
_748 = ifFalse.z;
_762 = ifFalse.z;
}
return float3(_726, _737, _748);
return float3(_740, _751, _762);
}
static inline __attribute__((always_inline))
@ -381,16 +385,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 _762;
float _776;
if (denom != 0.0)
{
_762 = num / denom;
_776 = num / denom;
}
else
{
_762 = 0.0;
_776 = 0.0;
}
return _762;
return _776;
}
static inline __attribute__((always_inline))
@ -400,25 +404,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 _868;
float3 _882;
if (rgb.x == v)
{
_868 = float3(0.0, rgb.yz);
_882 = float3(0.0, rgb.yz);
}
else
{
float3 _881;
float3 _895;
if (rgb.y == v)
{
_881 = float3(2.0, rgb.zx);
_895 = float3(2.0, rgb.zx);
}
else
{
_881 = float3(4.0, rgb.xy);
_895 = float3(4.0, rgb.xy);
}
_868 = _881;
_882 = _895;
}
float3 terms = _868;
float3 terms = _882;
float param = ((terms.x * c) + terms.y) - terms.z;
float param_1 = c;
float h = 1.0471975803375244140625 * compositeDivide(param, param_1);
@ -555,29 +559,29 @@ 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 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)
float4 calculateColor(thread const float2& fragCoord, thread const texture2d<float> colorTexture0, thread const sampler colorTexture0Smplr, thread const texture2d<float> maskTexture0, thread const sampler maskTexture0Smplr, thread const texture2d<float> destTexture, thread const sampler destTextureSmplr, thread const texture2d<float> gammaLUT, thread const sampler gammaLUTSmplr, thread const float2& colorTextureSize0, thread const float2& maskTextureSize0, thread const float4& filterParams0, thread const float4& filterParams1, thread const float4& filterParams2, thread const float2& framebufferSize, thread const int& ctrl, thread const float3& maskTexCoord0, thread const float2& colorTexCoord0, thread const float4& baseColor, thread const int& tileCtrl)
{
int maskCtrl0 = (tileCtrl >> 0) & 3;
float maskAlpha = 1.0;
float param = maskAlpha;
float2 param_1 = uMaskTextureSize0;
float3 param_2 = vMaskTexCoord0;
float2 param_1 = maskTextureSize0;
float3 param_2 = maskTexCoord0;
int param_3 = maskCtrl0;
maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2, param_3);
float4 color = vBaseColor;
maskAlpha = sampleMask(param, maskTexture0, maskTexture0Smplr, param_1, param_2, param_3);
float4 color = baseColor;
int color0Combine = (ctrl >> 6) & 3;
if (color0Combine != 0)
{
int color0Filter = (ctrl >> 4) & 3;
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;
float2 param_4 = colorTexCoord0;
float2 param_5 = colorTextureSize0;
float2 param_6 = fragCoord;
float2 param_7 = framebufferSize;
float4 param_8 = filterParams0;
float4 param_9 = filterParams1;
float4 param_10 = filterParams2;
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 color0 = filterColor(param_4, colorTexture0, colorTexture0Smplr, gammaLUT, gammaLUTSmplr, 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;
@ -586,21 +590,31 @@ void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread t
color.w *= maskAlpha;
int compositeOp = (ctrl >> 8) & 15;
float4 param_15 = color;
float2 param_16 = uFramebufferSize;
float2 param_17 = gl_FragCoord.xy;
float2 param_16 = framebufferSize;
float2 param_17 = fragCoord;
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;
color = composite(param_15, destTexture, destTextureSmplr, param_16, param_17, param_18);
float3 _1340 = color.xyz * color.w;
color = float4(_1340.x, _1340.y, _1340.z, color.w);
return color;
}
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]])
fragment main0_out main0(main0_in in [[stage_in]], constant float2& uColorTextureSize0 [[buffer(0)]], constant float2& uMaskTextureSize0 [[buffer(1)]], constant float2& uFramebufferSize [[buffer(2)]], texture2d<float> uColorTexture0 [[texture(0)]], texture2d<float> uMaskTexture0 [[texture(1)]], texture2d<float> uDestTexture [[texture(2)]], texture2d<float> uGammaLUT [[texture(3)]], sampler uColorTexture0Smplr [[sampler(0)]], sampler uMaskTexture0Smplr [[sampler(1)]], sampler uDestTextureSmplr [[sampler(2)]], sampler uGammaLUTSmplr [[sampler(3)]], float4 gl_FragCoord [[position]])
{
main0_out out = {};
int param = int(in.vTileCtrl);
int param_1 = uCtrl;
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);
float2 param = gl_FragCoord.xy;
float2 param_1 = uColorTextureSize0;
float2 param_2 = uMaskTextureSize0;
float4 param_3 = in.vFilterParams0;
float4 param_4 = in.vFilterParams1;
float4 param_5 = in.vFilterParams2;
float2 param_6 = uFramebufferSize;
int param_7 = int(in.vCtrl);
float3 param_8 = in.vMaskTexCoord0;
float2 param_9 = in.vColorTexCoord0;
float4 param_10 = in.vBaseColor;
int param_11 = int(in.vTileCtrl);
out.oFragColor = calculateColor(param, uColorTexture0, uColorTexture0Smplr, uMaskTexture0, uMaskTexture0Smplr, uDestTexture, uDestTextureSmplr, uGammaLUT, uGammaLUTSmplr, param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9, param_10, param_11);
return out;
}

View File

@ -0,0 +1,130 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float3 vMaskTexCoord0 [[user(locn0)]];
float2 vColorTexCoord0 [[user(locn1)]];
float4 vBaseColor [[user(locn2)]];
float vTileCtrl [[user(locn3)]];
float4 vFilterParams0 [[user(locn4)]];
float4 vFilterParams1 [[user(locn5)]];
float4 vFilterParams2 [[user(locn6)]];
float vCtrl [[user(locn7)]];
float4 gl_Position [[position]];
};
struct main0_in
{
int2 aTileOffset [[attribute(0)]];
int2 aTileOrigin [[attribute(1)]];
uint4 aMaskTexCoord0 [[attribute(2)]];
int2 aCtrlBackdrop [[attribute(3)]];
int aPathIndex [[attribute(4)]];
int aColor [[attribute(5)]];
};
static inline __attribute__((always_inline))
float4 fetchUnscaled(thread const texture2d<float> srcTexture, thread const sampler srcTextureSmplr, thread const float2& scale, thread const float2& originCoord, thread const int& entry)
{
return srcTexture.sample(srcTextureSmplr, (((originCoord + float2(0.5)) + float2(float(entry), 0.0)) * scale), level(0.0));
}
static inline __attribute__((always_inline))
void computeTileVaryings(thread const float2& position, thread const int& colorEntry, thread const texture2d<float> textureMetadata, thread const sampler textureMetadataSmplr, thread const int2& textureMetadataSize, thread float2& outColorTexCoord0, thread float4& outBaseColor, thread float4& outFilterParams0, thread float4& outFilterParams1, thread float4& outFilterParams2, thread int& outCtrl)
{
float2 metadataScale = float2(1.0) / float2(textureMetadataSize);
float2 metadataEntryCoord = float2(float((colorEntry % 128) * 8), float(colorEntry / 128));
float2 param = metadataScale;
float2 param_1 = metadataEntryCoord;
int param_2 = 0;
float4 colorTexMatrix0 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param, param_1, param_2);
float2 param_3 = metadataScale;
float2 param_4 = metadataEntryCoord;
int param_5 = 1;
float4 colorTexOffsets = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_3, param_4, param_5);
float2 param_6 = metadataScale;
float2 param_7 = metadataEntryCoord;
int param_8 = 2;
float4 baseColor = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_6, param_7, param_8);
float2 param_9 = metadataScale;
float2 param_10 = metadataEntryCoord;
int param_11 = 3;
float4 filterParams0 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_9, param_10, param_11);
float2 param_12 = metadataScale;
float2 param_13 = metadataEntryCoord;
int param_14 = 4;
float4 filterParams1 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_12, param_13, param_14);
float2 param_15 = metadataScale;
float2 param_16 = metadataEntryCoord;
int param_17 = 5;
float4 filterParams2 = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_15, param_16, param_17);
float2 param_18 = metadataScale;
float2 param_19 = metadataEntryCoord;
int param_20 = 6;
float4 extra = fetchUnscaled(textureMetadata, textureMetadataSmplr, param_18, param_19, param_20);
outColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy;
outBaseColor = baseColor;
outFilterParams0 = filterParams0;
outFilterParams1 = filterParams1;
outFilterParams2 = filterParams2;
outCtrl = int(extra.x);
}
vertex main0_out main0(main0_in in [[stage_in]], constant int2& uZBufferSize [[buffer(1)]], constant int2& uTextureMetadataSize [[buffer(2)]], constant float2& uTileSize [[buffer(0)]], constant float4x4& uTransform [[buffer(3)]], texture2d<float> uZBuffer [[texture(0)]], texture2d<float> uTextureMetadata [[texture(1)]], sampler uZBufferSmplr [[sampler(0)]], sampler uTextureMetadataSmplr [[sampler(1)]])
{
main0_out out = {};
float2 tileOrigin = float2(in.aTileOrigin);
float2 tileOffset = float2(in.aTileOffset);
float2 position = (tileOrigin + tileOffset) * uTileSize;
int4 zValue = int4(uZBuffer.sample(uZBufferSmplr, ((tileOrigin + float2(0.5)) / float2(uZBufferSize)), level(0.0)) * 255.0);
if (in.aPathIndex < (((zValue.x | (zValue.y << 8)) | (zValue.z << 16)) | (zValue.w << 24)))
{
out.gl_Position = float4(0.0);
return out;
}
uint2 maskTileCoord = uint2(in.aMaskTexCoord0.x, in.aMaskTexCoord0.y + (256u * in.aMaskTexCoord0.z));
float2 maskTexCoord0 = (float2(maskTileCoord) + tileOffset) * uTileSize;
bool _244 = in.aCtrlBackdrop.y == 0;
bool _250;
if (_244)
{
_250 = in.aMaskTexCoord0.w != 0u;
}
else
{
_250 = _244;
}
if (_250)
{
out.gl_Position = float4(0.0);
return out;
}
float2 param = position;
int param_1 = in.aColor;
int2 param_2 = uTextureMetadataSize;
float2 param_3;
float4 param_4;
float4 param_5;
float4 param_6;
float4 param_7;
int param_8;
computeTileVaryings(param, param_1, uTextureMetadata, uTextureMetadataSmplr, param_2, param_3, param_4, param_5, param_6, param_7, param_8);
out.vColorTexCoord0 = param_3;
out.vBaseColor = param_4;
out.vFilterParams0 = param_5;
out.vFilterParams1 = param_6;
out.vFilterParams2 = param_7;
int ctrl = param_8;
out.vTileCtrl = float(in.aCtrlBackdrop.x);
out.vCtrl = float(ctrl);
out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aCtrlBackdrop.y));
out.gl_Position = uTransform * float4(position, 0.0, 1.0);
return out;
}

View File

@ -0,0 +1,26 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 oFragColor [[color(0)]];
};
struct main0_in
{
float2 vTexCoord0 [[user(locn0)]];
float vBackdrop0 [[user(locn1)]];
float2 vTexCoord1 [[user(locn2)]];
float vBackdrop1 [[user(locn3)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]])
{
main0_out out = {};
out.oFragColor = fast::min(abs(uSrc.sample(uSrcSmplr, in.vTexCoord0) + float4(in.vBackdrop0)), abs(uSrc.sample(uSrcSmplr, in.vTexCoord1) + float4(in.vBackdrop1)));
return out;
}

View File

@ -0,0 +1,44 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vTexCoord0 [[user(locn0)]];
float vBackdrop0 [[user(locn1)]];
float2 vTexCoord1 [[user(locn2)]];
float vBackdrop1 [[user(locn3)]];
float4 gl_Position [[position]];
};
struct main0_in
{
int2 aTileOffset [[attribute(0)]];
int aDestTileIndex [[attribute(1)]];
int aDestBackdrop [[attribute(2)]];
int aSrcTileIndex [[attribute(3)]];
int aSrcBackdrop [[attribute(4)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant float2& uFramebufferSize [[buffer(0)]])
{
main0_out out = {};
float2 destPosition = float2(int2(in.aDestTileIndex % 256, in.aDestTileIndex / 256) + in.aTileOffset);
float2 srcPosition = float2(int2(in.aSrcTileIndex % 256, in.aSrcTileIndex / 256) + in.aTileOffset);
destPosition *= (float2(16.0, 4.0) / uFramebufferSize);
srcPosition *= (float2(16.0, 4.0) / uFramebufferSize);
out.vTexCoord0 = destPosition;
out.vTexCoord1 = srcPosition;
out.vBackdrop0 = float(in.aDestBackdrop);
out.vBackdrop1 = float(in.aSrcBackdrop);
if (in.aDestTileIndex < 0)
{
destPosition = float2(0.0);
}
destPosition.y = 1.0 - destPosition.y;
out.gl_Position = float4(mix(float2(-1.0), float2(1.0), destPosition), 0.0, 1.0);
return out;
}

View File

@ -12,13 +12,12 @@ struct main0_out
struct main0_in
{
float2 vTexCoord [[user(locn0)]];
float vBackdrop [[user(locn1)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]])
{
main0_out out = {};
out.oFragColor = fast::clamp(abs(uSrc.sample(uSrcSmplr, in.vTexCoord) + float4(in.vBackdrop)), float4(0.0), float4(1.0));
out.oFragColor = uSrc.sample(uSrcSmplr, in.vTexCoord);
return out;
}

View File

@ -0,0 +1,33 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
int2 aTileOffset [[attribute(0)]];
int aTileIndex [[attribute(1)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant float2& uFramebufferSize [[buffer(0)]])
{
main0_out out = {};
float2 position = float2(int2(in.aTileIndex % 256, in.aTileIndex / 256) + in.aTileOffset);
position *= (float2(16.0, 4.0) / uFramebufferSize);
out.vTexCoord = position;
if (in.aTileIndex < 0)
{
position = float2(0.0);
}
position.y = 1.0 - position.y;
out.gl_Position = float4(mix(float2(-1.0), float2(1.0), position), 0.0, 1.0);
return out;
}

View File

@ -1,68 +0,0 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vFrom [[user(locn0)]];
float2 vTo [[user(locn1)]];
float4 gl_Position [[position]];
};
struct main0_in
{
uint2 aTessCoord [[attribute(0)]];
uint aFromPx [[attribute(1)]];
uint aToPx [[attribute(2)]];
float2 aFromSubpx [[attribute(3)]];
float2 aToSubpx [[attribute(4)]];
uint aTileIndex [[attribute(5)]];
};
static inline __attribute__((always_inline))
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize)
{
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
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)]])
{
main0_out out = {};
uint param = in.aTileIndex;
float param_1 = uFramebufferSize.x;
float2 tileOrigin = computeTileOffset(param, param_1, uTileSize);
float2 from = float2(float(in.aFromPx & 15u), float(in.aFromPx >> 4u)) + in.aFromSubpx;
float2 to = float2(float(in.aToPx & 15u), float(in.aToPx >> 4u)) + in.aToSubpx;
float2 position;
if (in.aTessCoord.x == 0u)
{
position.x = floor(fast::min(from.x, to.x));
}
else
{
position.x = ceil(fast::max(from.x, to.x));
}
if (in.aTessCoord.y == 0u)
{
position.y = floor(fast::min(from.y, to.y));
}
else
{
position.y = uTileSize.y;
}
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);
return out;
}

View File

@ -1,48 +0,0 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float3 vMaskTexCoord0 [[user(locn0)]];
float2 vColorTexCoord0 [[user(locn1)]];
float4 vBaseColor [[user(locn2)]];
float vTileCtrl [[user(locn3)]];
float4 gl_Position [[position]];
};
struct main0_in
{
int2 aTileOffset [[attribute(0)]];
int2 aTileOrigin [[attribute(1)]];
uint2 aMaskTexCoord0 [[attribute(2)]];
int2 aMaskBackdrop [[attribute(3)]];
int aColor [[attribute(4)]];
int aTileCtrl [[attribute(5)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant int2& uTextureMetadataSize [[buffer(1)]], constant float2& uTileSize [[buffer(0)]], constant float4x4& uTransform [[buffer(2)]], texture2d<float> uTextureMetadata [[texture(0)]], sampler uTextureMetadataSmplr [[sampler(0)]])
{
main0_out out = {};
float2 tileOrigin = float2(in.aTileOrigin);
float2 tileOffset = float2(in.aTileOffset);
float2 position = (tileOrigin + tileOffset) * uTileSize;
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;
float2 colorTexOffsetsCoord = (metadataEntryCoord + float2(1.5, 0.5)) * textureMetadataScale;
float2 baseColorCoord = (metadataEntryCoord + float2(2.5, 0.5)) * textureMetadataScale;
float4 colorTexMatrix0 = uTextureMetadata.sample(uTextureMetadataSmplr, colorTexMatrix0Coord, level(0.0));
float4 colorTexOffsets = uTextureMetadata.sample(uTextureMetadataSmplr, colorTexOffsetsCoord, level(0.0));
float4 baseColor = uTextureMetadata.sample(uTextureMetadataSmplr, baseColorCoord, level(0.0));
out.vColorTexCoord0 = (float2x2(float2(colorTexMatrix0.xy), float2(colorTexMatrix0.zw)) * position) + colorTexOffsets.xy;
out.vMaskTexCoord0 = float3(maskTexCoord0, float(in.aMaskBackdrop.x));
out.vBaseColor = baseColor;
out.vTileCtrl = float(in.aTileCtrl);
out.gl_Position = uTransform * float4(position, 0.0, 1.0);
return out;
}

View File

@ -1,32 +0,0 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
float vBackdrop [[user(locn1)]];
float4 gl_Position [[position]];
};
struct main0_in
{
int2 aTileOffset [[attribute(0)]];
int2 aDestTileOrigin [[attribute(1)]];
int2 aSrcTileOrigin [[attribute(2)]];
int aSrcBackdrop [[attribute(3)]];
};
vertex main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
float2 destPosition = float2(in.aDestTileOrigin + in.aTileOffset) / float2(256.0);
float2 srcPosition = float2(in.aSrcTileOrigin + in.aTileOffset) / float2(256.0);
out.vTexCoord = srcPosition;
out.vBackdrop = float(in.aSrcBackdrop);
out.gl_Position = float4(mix(float2(-1.0), float2(1.0), destPosition), 0.0, 1.0);
return out;
}

View File

@ -18,7 +18,7 @@ precision highp float;
precision highp sampler2D;
#endif
#include "fill.inc.glsl"
#include "fill_area.inc.glsl"
uniform sampler2D uAreaLUT;

View File

@ -10,6 +10,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#extension GL_GOOGLE_include_directive : enable
precision highp float;
#ifdef GL_ES
@ -20,36 +22,39 @@ uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx;
in vec2 aToSubpx;
in uint aTileIndex;
in uvec4 aLineSegment;
in int aTileIndex;
out vec2 vFrom;
out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize) {
uint tilesPerRow = uint(stencilTextureWidth / tileSize.x);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset) * uTileSize * vec2(1.0, 0.25);
return vec2(tileOffset) * tileSize * vec2(1.0, 0.25);
}
void main() {
vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x);
vec4 computeVertexPosition(uint tileIndex,
uvec2 tessCoord,
uvec4 packedLineSegment,
vec2 tileSize,
vec2 framebufferSize,
out vec2 outFrom,
out vec2 outTo) {
vec2 tileOrigin = computeTileOffset(uint(tileIndex), framebufferSize.x, tileSize);
vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u) + aFromSubpx;
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
vec4 lineSegment = vec4(packedLineSegment) / 256.0;
vec2 from = lineSegment.xy, to = lineSegment.zw;
vec2 position;
if (aTessCoord.x == 0u)
if (tessCoord.x == 0u)
position.x = floor(min(from.x, to.x));
else
position.x = ceil(max(from.x, to.x));
if (aTessCoord.y == 0u)
if (tessCoord.y == 0u)
position.y = floor(min(from.y, to.y));
else
position.y = uTileSize.y;
position.y = tileSize.y;
position.y = floor(position.y * 0.25);
// Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will
@ -57,12 +62,22 @@ void main() {
// 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;
outFrom = from + offset;
outTo = to + offset;
vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0;
vec2 globalPosition = (tileOrigin + position) / framebufferSize * 2.0 - 1.0;
#ifdef PF_ORIGIN_UPPER_LEFT
globalPosition.y = -globalPosition.y;
#endif
gl_Position = vec4(globalPosition, 0.0, 1.0);
return vec4(globalPosition, 0.0, 1.0);
}
void main() {
gl_Position = computeVertexPosition(uint(aTileIndex),
aTessCoord,
aLineSegment,
uTileSize,
uFramebufferSize,
vFrom,
vTo);
}

63
shaders/d3d9/tile.fs.glsl Normal file
View File

@ -0,0 +1,63 @@
#version 330
// pathfinder/shaders/tile.fs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#extension GL_GOOGLE_include_directive : enable
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
#include "tile_fragment.inc.glsl"
uniform sampler2D uColorTexture0;
uniform sampler2D uMaskTexture0;
uniform sampler2D uDestTexture;
uniform sampler2D uGammaLUT;
uniform vec2 uColorTextureSize0;
uniform vec2 uMaskTextureSize0;
uniform vec2 uFramebufferSize;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
in vec4 vFilterParams0;
in vec4 vFilterParams1;
in vec4 vFilterParams2;
in float vCtrl;
out vec4 oFragColor;
// Entry point
//
// TODO(pcwalton): Generate this dynamically.
void main() {
oFragColor = calculateColor(gl_FragCoord.xy,
uColorTexture0,
uMaskTexture0,
uDestTexture,
uGammaLUT,
uColorTextureSize0,
uMaskTextureSize0,
vFilterParams0,
vFilterParams1,
vFilterParams2,
uFramebufferSize,
int(vCtrl),
vMaskTexCoord0,
vColorTexCoord0,
vBaseColor,
int(vTileCtrl));
}

79
shaders/d3d9/tile.vs.glsl Normal file
View File

@ -0,0 +1,79 @@
#version 330
// pathfinder/shaders/tile.vs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#extension GL_GOOGLE_include_directive : enable
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
#include "tile_vertex.inc.glsl"
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
uniform sampler2D uZBuffer;
uniform ivec2 uZBufferSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec4 aMaskTexCoord0;
in ivec2 aCtrlBackdrop;
in int aPathIndex;
in int aColor;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
out vec4 vFilterParams0;
out vec4 vFilterParams1;
out vec4 vFilterParams2;
out float vCtrl;
void main() {
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position = (tileOrigin + tileOffset) * uTileSize;
ivec4 zValue = ivec4(texture(uZBuffer, (tileOrigin + vec2(0.5)) / vec2(uZBufferSize)) * 255.0);
if (aPathIndex < (zValue.x | (zValue.y << 8) | (zValue.z << 16) | (zValue.w << 24))) {
gl_Position = vec4(0.0);
return;
}
uvec2 maskTileCoord = uvec2(aMaskTexCoord0.x, aMaskTexCoord0.y + 256u * aMaskTexCoord0.z);
vec2 maskTexCoord0 = (vec2(maskTileCoord) + tileOffset) * uTileSize;
if (aCtrlBackdrop.y == 0 && aMaskTexCoord0.w != 0u) {
gl_Position = vec4(0.0);
return;
}
int ctrl;
computeTileVaryings(position,
aColor,
uTextureMetadata,
uTextureMetadataSize,
vColorTexCoord0,
vBaseColor,
vFilterParams0,
vFilterParams1,
vFilterParams2,
ctrl);
vTileCtrl = float(aCtrlBackdrop.x);
vCtrl = float(ctrl);
vMaskTexCoord0 = vec3(maskTexCoord0, float(aCtrlBackdrop.y));
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -0,0 +1,31 @@
#version 330
// pathfinder/shaders/tile_clip_combine.fs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
uniform sampler2D uSrc;
in vec2 vTexCoord0;
in float vBackdrop0;
in vec2 vTexCoord1;
in float vBackdrop1;
out vec4 oFragColor;
void main() {
oFragColor = min(abs(texture(uSrc, vTexCoord0) + vBackdrop0),
abs(texture(uSrc, vTexCoord1) + vBackdrop1));
}

View File

@ -0,0 +1,51 @@
#version 330
// pathfinder/shaders/tile_clip_combine.vs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in int aDestTileIndex;
in int aDestBackdrop;
in int aSrcTileIndex;
in int aSrcBackdrop;
out vec2 vTexCoord0;
out float vBackdrop0;
out vec2 vTexCoord1;
out float vBackdrop1;
void main() {
vec2 destPosition = vec2(ivec2(aDestTileIndex % 256, aDestTileIndex / 256) + aTileOffset);
vec2 srcPosition = vec2(ivec2(aSrcTileIndex % 256, aSrcTileIndex / 256) + aTileOffset);
destPosition *= vec2(16.0, 4.0) / uFramebufferSize;
srcPosition *= vec2(16.0, 4.0) / uFramebufferSize;
vTexCoord0 = destPosition;
vTexCoord1 = srcPosition;
vBackdrop0 = float(aDestBackdrop);
vBackdrop1 = float(aSrcBackdrop);
if (aDestTileIndex < 0)
destPosition = vec2(0.0);
#ifdef PF_ORIGIN_UPPER_LEFT
destPosition.y = 1.0 - destPosition.y;
#endif
gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0);
}

View File

@ -1,6 +1,6 @@
#version 330
// pathfinder/shaders/tile_clip.fs.glsl
// pathfinder/shaders/tile_clip_copy.fs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
@ -19,10 +19,9 @@ precision highp sampler2D;
uniform sampler2D uSrc;
in vec2 vTexCoord;
in float vBackdrop;
out vec4 oFragColor;
void main() {
oFragColor = clamp(abs(texture(uSrc, vTexCoord) + vBackdrop), 0.0, 1.0);
oFragColor = texture(uSrc, vTexCoord);
}

View File

@ -1,6 +1,6 @@
#version 330
// pathfinder/shaders/tile_clip.vs.glsl
// pathfinder/shaders/tile_clip_copy.vs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
@ -16,18 +16,24 @@ precision highp float;
precision highp sampler2D;
#endif
uniform vec2 uFramebufferSize;
in ivec2 aTileOffset;
in ivec2 aDestTileOrigin;
in ivec2 aSrcTileOrigin;
in int aSrcBackdrop;
in int aTileIndex;
out vec2 vTexCoord;
out float vBackdrop;
void main() {
vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0);
vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0);
vTexCoord = srcPosition;
vBackdrop = float(aSrcBackdrop);
gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0);
vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256) + aTileOffset);
position *= vec2(16.0, 4.0) / uFramebufferSize;
vTexCoord = position;
if (aTileIndex < 0)
position = vec2(0.0);
#ifdef PF_ORIGIN_UPPER_LEFT
position.y = 1.0 - position.y;
#endif
gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), position), 0.0, 1.0);
}

View File

@ -1,27 +0,0 @@
// pathfinder/shaders/fill.inc.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
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;
// Shoot a vertical ray toward the curve.
vec2 window = clamp(vec2(from.x, to.x), -0.5, 0.5);
float offset = mix(window.x, window.y, 0.5) - left.x;
float t = offset / (right.x - left.x);
// Compute position and derivative to form a line approximation.
float y = mix(left.y, right.y, t);
float d = (right.y - left.y) / (right.x - left.x);
// 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) * dX;
}

View File

@ -1,56 +0,0 @@
#version 330
// pathfinder/shaders/tile.vs.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform sampler2D uTextureMetadata;
uniform ivec2 uTextureMetadataSize;
in ivec2 aTileOffset;
in ivec2 aTileOrigin;
in uvec2 aMaskTexCoord0;
in ivec2 aMaskBackdrop;
in int aColor;
in int aTileCtrl;
out vec3 vMaskTexCoord0;
out vec2 vColorTexCoord0;
out vec4 vBaseColor;
out float vTileCtrl;
void main() {
vec2 tileOrigin = vec2(aTileOrigin), tileOffset = vec2(aTileOffset);
vec2 position = (tileOrigin + tileOffset) * uTileSize;
vec2 maskTexCoord0 = (vec2(aMaskTexCoord0) + tileOffset) * uTileSize;
vec2 textureMetadataScale = vec2(1.0) / vec2(uTextureMetadataSize);
vec2 metadataEntryCoord = vec2(aColor % 128 * 4, aColor / 128);
vec2 colorTexMatrix0Coord = (metadataEntryCoord + vec2(0.5, 0.5)) * textureMetadataScale;
vec2 colorTexOffsetsCoord = (metadataEntryCoord + vec2(1.5, 0.5)) * textureMetadataScale;
vec2 baseColorCoord = (metadataEntryCoord + vec2(2.5, 0.5)) * textureMetadataScale;
vec4 colorTexMatrix0 = texture(uTextureMetadata, colorTexMatrix0Coord);
vec4 colorTexOffsets = texture(uTextureMetadata, colorTexOffsetsCoord);
vec4 baseColor = texture(uTextureMetadata, baseColorCoord);
vColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy;
vMaskTexCoord0 = vec3(maskTexCoord0, float(aMaskBackdrop.x));
vBaseColor = baseColor;
vTileCtrl = float(aTileCtrl);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -1,6 +1,4 @@
#version 330
// pathfinder/shaders/tile.fs.glsl
// pathfinder/shaders/tile_fragment.inc.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
@ -31,14 +29,6 @@
// + +
// Color UV 0 Color UV 1
#extension GL_GOOGLE_include_directive : enable
precision highp float;
#ifdef GL_ES
precision highp sampler2D;
#endif
#define EPSILON 0.00001
#define FRAC_6_PI 1.9098593171027443
@ -81,25 +71,6 @@ precision highp sampler2D;
#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6
#define COMBINER_CTRL_COMPOSITE_SHIFT 8
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 int uCtrl;
in vec3 vMaskTexCoord0;
in vec2 vColorTexCoord0;
in vec4 vBaseColor;
in float vTileCtrl;
out vec4 oFragColor;
// Color sampling
vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord) {
@ -565,27 +536,42 @@ float sampleMask(float maskAlpha,
// Main function
void calculateColor(int tileCtrl, int ctrl) {
vec4 calculateColor(vec2 fragCoord,
sampler2D colorTexture0,
sampler2D maskTexture0,
sampler2D destTexture,
sampler2D gammaLUT,
vec2 colorTextureSize0,
vec2 maskTextureSize0,
vec4 filterParams0,
vec4 filterParams1,
vec4 filterParams2,
vec2 framebufferSize,
int ctrl,
vec3 maskTexCoord0,
vec2 colorTexCoord0,
vec4 baseColor,
int tileCtrl) {
// Sample mask.
int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK;
float maskAlpha = 1.0;
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0);
// Sample color.
vec4 color = vBaseColor;
vec4 color = baseColor;
int color0Combine = (ctrl >> COMBINER_CTRL_COLOR_COMBINE_SHIFT) &
COMBINER_CTRL_COLOR_COMBINE_MASK;
if (color0Combine != 0) {
int color0Filter = (ctrl >> COMBINER_CTRL_COLOR_FILTER_SHIFT) & COMBINER_CTRL_FILTER_MASK;
vec4 color0 = filterColor(vColorTexCoord0,
uColorTexture0,
uGammaLUT,
uColorTextureSize0,
gl_FragCoord.xy,
uFramebufferSize,
uFilterParams0,
uFilterParams1,
uFilterParams2,
vec4 color0 = filterColor(colorTexCoord0,
colorTexture0,
gammaLUT,
colorTextureSize0,
fragCoord,
framebufferSize,
filterParams0,
filterParams1,
filterParams2,
color0Filter);
color = combineColor0(color, color0, color0Combine);
}
@ -595,17 +581,9 @@ void calculateColor(int tileCtrl, int ctrl) {
// Apply composite.
int compositeOp = (ctrl >> COMBINER_CTRL_COMPOSITE_SHIFT) & COMBINER_CTRL_COMPOSITE_MASK;
color = composite(color, uDestTexture, uFramebufferSize, gl_FragCoord.xy, compositeOp);
color = composite(color, destTexture, framebufferSize, fragCoord, compositeOp);
// Premultiply alpha.
color.rgb *= color.a;
oFragColor = color;
}
// Entry point
//
// TODO(pcwalton): Generate this dynamically.
void main() {
calculateColor(int(vTileCtrl), uCtrl);
return color;
}

View File

@ -0,0 +1,40 @@
// pathfinder/shaders/tile_vertex.inc.glsl
//
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
vec4 fetchUnscaled(sampler2D srcTexture, vec2 scale, vec2 originCoord, int entry) {
return texture(srcTexture, (originCoord + vec2(0.5) + vec2(entry, 0)) * scale);
}
void computeTileVaryings(vec2 position,
int colorEntry,
sampler2D textureMetadata,
ivec2 textureMetadataSize,
out vec2 outColorTexCoord0,
out vec4 outBaseColor,
out vec4 outFilterParams0,
out vec4 outFilterParams1,
out vec4 outFilterParams2,
out int outCtrl) {
vec2 metadataScale = vec2(1.0) / vec2(textureMetadataSize);
vec2 metadataEntryCoord = vec2(colorEntry % 128 * 8, colorEntry / 128);
vec4 colorTexMatrix0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 0);
vec4 colorTexOffsets = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 1);
vec4 baseColor = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 2);
vec4 filterParams0 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 3);
vec4 filterParams1 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 4);
vec4 filterParams2 = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 5);
vec4 extra = fetchUnscaled(textureMetadata, metadataScale, metadataEntryCoord, 6);
outColorTexCoord0 = mat2(colorTexMatrix0) * position + colorTexOffsets.xy;
outBaseColor = baseColor;
outFilterParams0 = filterParams0;
outFilterParams1 = filterParams1;
outFilterParams2 = filterParams2;
outCtrl = int(extra.x);
}