Rename the existing renderer to `d3d9` in preparation for the D3D11 branch
This commit is contained in:
parent
5e3fb5fed0
commit
754a44ae22
|
@ -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;
|
|
@ -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,
|
||||||
|
}
|
|
@ -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(©_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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,20 +8,12 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use crate::gpu::options::RendererOptions;
|
use pathfinder_gpu::{BufferTarget, BufferUploadMode, Device, VertexAttrClass};
|
||||||
use crate::gpu::renderer::{MASK_TILES_ACROSS, MASK_TILES_DOWN};
|
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
|
||||||
use pathfinder_gpu::{BufferTarget, BufferUploadMode, ComputeDimensions, Device, FeatureLevel};
|
|
||||||
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
|
||||||
use pathfinder_resources::ResourceLoader;
|
use pathfinder_resources::ResourceLoader;
|
||||||
|
|
||||||
// TODO(pcwalton): Replace with `mem::size_of` calls?
|
// TODO(pcwalton): Replace with `mem::size_of` calls?
|
||||||
pub(crate) const TILE_INSTANCE_SIZE: usize = 12;
|
pub(crate) const TILE_INSTANCE_SIZE: usize = 16;
|
||||||
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 struct BlitVertexArray<D> where D: Device {
|
pub struct BlitVertexArray<D> where D: Device {
|
||||||
pub vertex_array: D::VertexArray,
|
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 struct ClearVertexArray<D> where D: Device {
|
||||||
pub vertex_array: D::VertexArray,
|
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(©_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 struct BlitProgram<D> where D: Device {
|
||||||
pub program: D::Program,
|
pub program: D::Program,
|
||||||
|
pub dest_rect_uniform: D::Uniform,
|
||||||
|
pub framebuffer_size_uniform: D::Uniform,
|
||||||
pub src_texture: D::TextureParameter,
|
pub src_texture: D::TextureParameter,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> BlitProgram<D> where D: Device {
|
impl<D> BlitProgram<D> where D: Device {
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram<D> {
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> BlitProgram<D> {
|
||||||
let program = device.create_raster_program(resources, "blit");
|
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");
|
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 {
|
pub struct TileProgramCommon<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 program: D::Program,
|
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 tile_size_uniform: D::Uniform,
|
||||||
pub texture_metadata_texture: D::TextureParameter,
|
pub texture_metadata_texture: D::TextureParameter,
|
||||||
pub texture_metadata_size_uniform: D::Uniform,
|
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_0: D::TextureParameter,
|
||||||
pub color_texture_size_0_uniform: D::Uniform,
|
pub color_texture_size_0_uniform: D::Uniform,
|
||||||
pub color_texture_1: D::TextureParameter,
|
pub color_texture_1: D::TextureParameter,
|
||||||
pub mask_texture_0: D::TextureParameter,
|
pub mask_texture_0: D::TextureParameter,
|
||||||
pub mask_texture_size_0_uniform: D::Uniform,
|
pub mask_texture_size_0_uniform: D::Uniform,
|
||||||
pub gamma_lut_texture: D::TextureParameter,
|
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 framebuffer_size_uniform: D::Uniform,
|
||||||
pub ctrl_uniform: D::Uniform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> TileProgram<D> where D: Device {
|
impl<D> TileProgramCommon<D> where D: Device {
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> TileProgram<D> {
|
pub(crate) fn new(device: &D, program: D::Program) -> TileProgramCommon<D> {
|
||||||
let program = device.create_raster_program(resources, "tile");
|
|
||||||
let transform_uniform = device.get_uniform(&program, "Transform");
|
|
||||||
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
let tile_size_uniform = device.get_uniform(&program, "TileSize");
|
||||||
let texture_metadata_texture = device.get_texture_parameter(&program, "TextureMetadata");
|
let texture_metadata_texture = device.get_texture_parameter(&program, "TextureMetadata");
|
||||||
let texture_metadata_size_uniform = device.get_uniform(&program, "TextureMetadataSize");
|
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_0 = device.get_texture_parameter(&program, "ColorTexture0");
|
||||||
let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0");
|
let color_texture_size_0_uniform = device.get_uniform(&program, "ColorTextureSize0");
|
||||||
let color_texture_1 = device.get_texture_parameter(&program, "ColorTexture1");
|
let color_texture_1 = device.get_texture_parameter(&program, "ColorTexture1");
|
||||||
let mask_texture_0 = device.get_texture_parameter(&program, "MaskTexture0");
|
let mask_texture_0 = device.get_texture_parameter(&program, "MaskTexture0");
|
||||||
let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0");
|
let mask_texture_size_0_uniform = device.get_uniform(&program, "MaskTextureSize0");
|
||||||
let gamma_lut_texture = device.get_texture_parameter(&program, "GammaLUT");
|
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 framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
let ctrl_uniform = device.get_uniform(&program, "Ctrl");
|
|
||||||
TileProgram {
|
TileProgramCommon {
|
||||||
program,
|
program,
|
||||||
transform_uniform,
|
|
||||||
tile_size_uniform,
|
tile_size_uniform,
|
||||||
texture_metadata_texture,
|
texture_metadata_texture,
|
||||||
texture_metadata_size_uniform,
|
texture_metadata_size_uniform,
|
||||||
dest_texture,
|
z_buffer_texture,
|
||||||
|
z_buffer_texture_size_uniform,
|
||||||
color_texture_0,
|
color_texture_0,
|
||||||
color_texture_size_0_uniform,
|
color_texture_size_0_uniform,
|
||||||
color_texture_1,
|
color_texture_1,
|
||||||
mask_texture_0,
|
mask_texture_0,
|
||||||
mask_texture_size_0_uniform,
|
mask_texture_size_0_uniform,
|
||||||
gamma_lut_texture,
|
gamma_lut_texture,
|
||||||
filter_params_0_uniform,
|
|
||||||
filter_params_1_uniform,
|
|
||||||
filter_params_2_uniform,
|
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
ctrl_uniform,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CopyTileProgram<D> where D: Device {
|
pub struct StencilProgram<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 program: D::Program,
|
pub program: D::Program,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> StencilProgram<D>
|
impl<D> StencilProgram<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
|
||||||
let program = device.create_raster_program(resources, "stencil");
|
let program = device.create_raster_program(resources, "stencil");
|
||||||
StencilProgram { program }
|
StencilProgram { program }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StencilVertexArray<D>
|
pub struct StencilVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub vertex_array: D::VertexArray,
|
pub vertex_array: D::VertexArray,
|
||||||
pub vertex_buffer: D::Buffer,
|
pub vertex_buffer: D::Buffer,
|
||||||
pub index_buffer: D::Buffer,
|
pub index_buffer: D::Buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> StencilVertexArray<D>
|
impl<D> StencilVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub fn new(device: &D, stencil_program: &StencilProgram<D>) -> StencilVertexArray<D> {
|
pub fn new(device: &D, stencil_program: &StencilProgram<D>) -> StencilVertexArray<D> {
|
||||||
let vertex_array = device.create_vertex_array();
|
let vertex_array = device.create_vertex_array();
|
||||||
let vertex_buffer = device.create_buffer(BufferUploadMode::Static);
|
let vertex_buffer = device.create_buffer(BufferUploadMode::Static);
|
||||||
|
@ -628,17 +245,11 @@ impl<D> ReprojectionProgram<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReprojectionVertexArray<D>
|
pub struct ReprojectionVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub vertex_array: D::VertexArray,
|
pub vertex_array: D::VertexArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> ReprojectionVertexArray<D>
|
impl<D> ReprojectionVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &D,
|
device: &D,
|
||||||
reprojection_program: &ReprojectionProgram<D>,
|
reprojection_program: &ReprojectionProgram<D>,
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -12,27 +12,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
precision highp float;
|
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;
|
int maskCtrl0 =(tileCtrl >> 0)& 0x3;
|
||||||
float maskAlpha = 1.0;
|
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)&
|
int color0Combine =(ctrl >> 6)&
|
||||||
0x3;
|
0x3;
|
||||||
if(color0Combine != 0){
|
if(color0Combine != 0){
|
||||||
int color0Filter =(ctrl >> 4)& 0x3;
|
int color0Filter =(ctrl >> 4)& 0x3;
|
||||||
vec4 color0 = filterColor(vColorTexCoord0,
|
vec4 color0 = filterColor(colorTexCoord0,
|
||||||
uColorTexture0,
|
colorTexture0,
|
||||||
uGammaLUT,
|
gammaLUT,
|
||||||
uColorTextureSize0,
|
colorTextureSize0,
|
||||||
gl_FragCoord . xy,
|
fragCoord,
|
||||||
uFramebufferSize,
|
framebufferSize,
|
||||||
uFilterParams0,
|
filterParams0,
|
||||||
uFilterParams1,
|
filterParams1,
|
||||||
uFilterParams2,
|
filterParams2,
|
||||||
color0Filter);
|
color0Filter);
|
||||||
color = combineColor0(color, color0, color0Combine);
|
color = combineColor0(color, color0, color0Combine);
|
||||||
}
|
}
|
||||||
|
@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){
|
||||||
|
|
||||||
|
|
||||||
int compositeOp =(ctrl >> 8)& 0xf;
|
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;
|
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(){
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -21,11 +21,10 @@ precision highp float;
|
||||||
uniform sampler2D uSrc;
|
uniform sampler2D uSrc;
|
||||||
|
|
||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
in float vBackdrop;
|
|
||||||
|
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0);
|
oFragColor = texture(uSrc, vTexCoord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -12,27 +12,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
precision highp float;
|
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;
|
int maskCtrl0 =(tileCtrl >> 0)& 0x3;
|
||||||
float maskAlpha = 1.0;
|
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)&
|
int color0Combine =(ctrl >> 6)&
|
||||||
0x3;
|
0x3;
|
||||||
if(color0Combine != 0){
|
if(color0Combine != 0){
|
||||||
int color0Filter =(ctrl >> 4)& 0x3;
|
int color0Filter =(ctrl >> 4)& 0x3;
|
||||||
vec4 color0 = filterColor(vColorTexCoord0,
|
vec4 color0 = filterColor(colorTexCoord0,
|
||||||
uColorTexture0,
|
colorTexture0,
|
||||||
uGammaLUT,
|
gammaLUT,
|
||||||
uColorTextureSize0,
|
colorTextureSize0,
|
||||||
gl_FragCoord . xy,
|
fragCoord,
|
||||||
uFramebufferSize,
|
framebufferSize,
|
||||||
uFilterParams0,
|
filterParams0,
|
||||||
uFilterParams1,
|
filterParams1,
|
||||||
uFilterParams2,
|
filterParams2,
|
||||||
color0Filter);
|
color0Filter);
|
||||||
color = combineColor0(color, color0, color0Combine);
|
color = combineColor0(color, color0, color0Combine);
|
||||||
}
|
}
|
||||||
|
@ -597,18 +604,53 @@ void calculateColor(int tileCtrl, int ctrl){
|
||||||
|
|
||||||
|
|
||||||
int compositeOp =(ctrl >> 8)& 0xf;
|
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;
|
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(){
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -21,11 +21,10 @@ precision highp float;
|
||||||
uniform sampler2D uSrc;
|
uniform sampler2D uSrc;
|
||||||
|
|
||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
in float vBackdrop;
|
|
||||||
|
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
oFragColor = clamp(abs(texture(uSrc, vTexCoord)+ vBackdrop), 0.0, 1.0);
|
oFragColor = texture(uSrc, vTexCoord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
using namespace metal;
|
using namespace metal;
|
||||||
|
|
||||||
constant float3 _1042 = {};
|
constant float3 _1056 = {};
|
||||||
|
|
||||||
struct main0_out
|
struct main0_out
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,10 @@ struct main0_in
|
||||||
float2 vColorTexCoord0 [[user(locn1)]];
|
float2 vColorTexCoord0 [[user(locn1)]];
|
||||||
float4 vBaseColor [[user(locn2)]];
|
float4 vBaseColor [[user(locn2)]];
|
||||||
float vTileCtrl [[user(locn3)]];
|
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()
|
// 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;
|
ts = ts.yx;
|
||||||
}
|
}
|
||||||
float _555;
|
float _569;
|
||||||
if (ts.x >= 0.0)
|
if (ts.x >= 0.0)
|
||||||
{
|
{
|
||||||
_555 = ts.x;
|
_569 = ts.x;
|
||||||
}
|
}
|
||||||
else
|
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)));
|
color = colorTexture.sample(colorTextureSmplr, (uvOrigin + float2(fast::clamp(t, 0.0, 1.0), 0.0)));
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
|
@ -94,19 +98,19 @@ float4 filterBlur(thread const float2& colorTexCoord, thread const texture2d<flo
|
||||||
float3 gaussCoeff = filterParams1.xyz;
|
float3 gaussCoeff = filterParams1.xyz;
|
||||||
float gaussSum = gaussCoeff.x;
|
float gaussSum = gaussCoeff.x;
|
||||||
float4 color = colorTexture.sample(colorTextureSmplr, colorTexCoord) * gaussCoeff.x;
|
float4 color = colorTexture.sample(colorTextureSmplr, colorTexCoord) * gaussCoeff.x;
|
||||||
float2 _600 = gaussCoeff.xy * gaussCoeff.yz;
|
float2 _614 = gaussCoeff.xy * gaussCoeff.yz;
|
||||||
gaussCoeff = float3(_600.x, _600.y, gaussCoeff.z);
|
gaussCoeff = float3(_614.x, _614.y, gaussCoeff.z);
|
||||||
for (int i = 1; i <= support; i += 2)
|
for (int i = 1; i <= support; i += 2)
|
||||||
{
|
{
|
||||||
float gaussPartialSum = gaussCoeff.x;
|
float gaussPartialSum = gaussCoeff.x;
|
||||||
float2 _620 = gaussCoeff.xy * gaussCoeff.yz;
|
float2 _634 = gaussCoeff.xy * gaussCoeff.yz;
|
||||||
gaussCoeff = float3(_620.x, _620.y, gaussCoeff.z);
|
gaussCoeff = float3(_634.x, _634.y, gaussCoeff.z);
|
||||||
gaussPartialSum += gaussCoeff.x;
|
gaussPartialSum += gaussCoeff.x;
|
||||||
float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum));
|
float2 srcOffset = srcOffsetScale * (float(i) + (gaussCoeff.x / gaussPartialSum));
|
||||||
color += ((colorTexture.sample(colorTextureSmplr, (colorTexCoord - srcOffset)) + colorTexture.sample(colorTextureSmplr, (colorTexCoord + srcOffset))) * gaussPartialSum);
|
color += ((colorTexture.sample(colorTextureSmplr, (colorTexCoord - srcOffset)) + colorTexture.sample(colorTextureSmplr, (colorTexCoord + srcOffset))) * gaussPartialSum);
|
||||||
gaussSum += (2.0 * gaussPartialSum);
|
gaussSum += (2.0 * gaussPartialSum);
|
||||||
float2 _660 = gaussCoeff.xy * gaussCoeff.yz;
|
float2 _674 = gaussCoeff.xy * gaussCoeff.yz;
|
||||||
gaussCoeff = float3(_660.x, _660.y, gaussCoeff.z);
|
gaussCoeff = float3(_674.x, _674.y, gaussCoeff.z);
|
||||||
}
|
}
|
||||||
return color / float4(gaussSum);
|
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)
|
void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCenter, thread float4& outAlphaRight, thread const texture2d<float> colorTexture, thread const sampler colorTextureSmplr, thread const float2& colorTexCoord, thread const float4& kernel0, thread const float& onePixel)
|
||||||
{
|
{
|
||||||
bool wide = kernel0.x > 0.0;
|
bool wide = kernel0.x > 0.0;
|
||||||
float _236;
|
float _250;
|
||||||
if (wide)
|
if (wide)
|
||||||
{
|
{
|
||||||
float param = (-4.0) * onePixel;
|
float param = (-4.0) * onePixel;
|
||||||
float2 param_1 = colorTexCoord;
|
float2 param_1 = colorTexCoord;
|
||||||
_236 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1);
|
_250 = filterTextSample1Tap(param, colorTexture, colorTextureSmplr, param_1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_236 = 0.0;
|
_250 = 0.0;
|
||||||
}
|
}
|
||||||
float param_2 = (-3.0) * onePixel;
|
float param_2 = (-3.0) * onePixel;
|
||||||
float2 param_3 = colorTexCoord;
|
float2 param_3 = colorTexCoord;
|
||||||
|
@ -138,7 +142,7 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen
|
||||||
float2 param_5 = colorTexCoord;
|
float2 param_5 = colorTexCoord;
|
||||||
float param_6 = (-1.0) * onePixel;
|
float param_6 = (-1.0) * onePixel;
|
||||||
float2 param_7 = colorTexCoord;
|
float2 param_7 = colorTexCoord;
|
||||||
outAlphaLeft = float4(_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;
|
float param_8 = 0.0;
|
||||||
float2 param_9 = colorTexCoord;
|
float2 param_9 = colorTexCoord;
|
||||||
outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9);
|
outAlphaCenter = filterTextSample1Tap(param_8, colorTexture, colorTextureSmplr, param_9);
|
||||||
|
@ -148,18 +152,18 @@ void filterTextSample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCen
|
||||||
float2 param_13 = colorTexCoord;
|
float2 param_13 = colorTexCoord;
|
||||||
float param_14 = 3.0 * onePixel;
|
float param_14 = 3.0 * onePixel;
|
||||||
float2 param_15 = colorTexCoord;
|
float2 param_15 = colorTexCoord;
|
||||||
float _296;
|
float _310;
|
||||||
if (wide)
|
if (wide)
|
||||||
{
|
{
|
||||||
float param_16 = 4.0 * onePixel;
|
float param_16 = 4.0 * onePixel;
|
||||||
float2 param_17 = colorTexCoord;
|
float2 param_17 = colorTexCoord;
|
||||||
_296 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17);
|
_310 = filterTextSample1Tap(param_16, colorTexture, colorTextureSmplr, param_17);
|
||||||
}
|
}
|
||||||
else
|
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))
|
static inline __attribute__((always_inline))
|
||||||
|
@ -309,34 +313,34 @@ float3 compositeScreen(thread const float3& destColor, thread const float3& srcC
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse)
|
float3 compositeSelect(thread const bool3& cond, thread const float3& ifTrue, thread const float3& ifFalse)
|
||||||
{
|
{
|
||||||
float _726;
|
float _740;
|
||||||
if (cond.x)
|
if (cond.x)
|
||||||
{
|
{
|
||||||
_726 = ifTrue.x;
|
_740 = ifTrue.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_726 = ifFalse.x;
|
_740 = ifFalse.x;
|
||||||
}
|
}
|
||||||
float _737;
|
float _751;
|
||||||
if (cond.y)
|
if (cond.y)
|
||||||
{
|
{
|
||||||
_737 = ifTrue.y;
|
_751 = ifTrue.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_737 = ifFalse.y;
|
_751 = ifFalse.y;
|
||||||
}
|
}
|
||||||
float _748;
|
float _762;
|
||||||
if (cond.z)
|
if (cond.z)
|
||||||
{
|
{
|
||||||
_748 = ifTrue.z;
|
_762 = ifTrue.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_748 = ifFalse.z;
|
_762 = ifFalse.z;
|
||||||
}
|
}
|
||||||
return float3(_726, _737, _748);
|
return float3(_740, _751, _762);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
|
@ -381,16 +385,16 @@ float3 compositeSoftLight(thread const float3& destColor, thread const float3& s
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
float compositeDivide(thread const float& num, thread const float& denom)
|
float compositeDivide(thread const float& num, thread const float& denom)
|
||||||
{
|
{
|
||||||
float _762;
|
float _776;
|
||||||
if (denom != 0.0)
|
if (denom != 0.0)
|
||||||
{
|
{
|
||||||
_762 = num / denom;
|
_776 = num / denom;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_762 = 0.0;
|
_776 = 0.0;
|
||||||
}
|
}
|
||||||
return _762;
|
return _776;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
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 xMin = fast::min(fast::min(rgb.x, rgb.y), rgb.z);
|
||||||
float c = v - xMin;
|
float c = v - xMin;
|
||||||
float l = mix(xMin, v, 0.5);
|
float l = mix(xMin, v, 0.5);
|
||||||
float3 _868;
|
float3 _882;
|
||||||
if (rgb.x == v)
|
if (rgb.x == v)
|
||||||
{
|
{
|
||||||
_868 = float3(0.0, rgb.yz);
|
_882 = float3(0.0, rgb.yz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float3 _881;
|
float3 _895;
|
||||||
if (rgb.y == v)
|
if (rgb.y == v)
|
||||||
{
|
{
|
||||||
_881 = float3(2.0, rgb.zx);
|
_895 = float3(2.0, rgb.zx);
|
||||||
}
|
}
|
||||||
else
|
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 = ((terms.x * c) + terms.y) - terms.z;
|
||||||
float param_1 = c;
|
float param_1 = c;
|
||||||
float h = 1.0471975803375244140625 * compositeDivide(param, param_1);
|
float h = 1.0471975803375244140625 * compositeDivide(param, param_1);
|
||||||
|
@ -555,29 +559,29 @@ float4 composite(thread const float4& srcColor, thread const texture2d<float> de
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread texture2d<float> uMaskTexture0, thread const sampler uMaskTexture0Smplr, thread 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;
|
int maskCtrl0 = (tileCtrl >> 0) & 3;
|
||||||
float maskAlpha = 1.0;
|
float maskAlpha = 1.0;
|
||||||
float param = maskAlpha;
|
float param = maskAlpha;
|
||||||
float2 param_1 = uMaskTextureSize0;
|
float2 param_1 = maskTextureSize0;
|
||||||
float3 param_2 = vMaskTexCoord0;
|
float3 param_2 = maskTexCoord0;
|
||||||
int param_3 = maskCtrl0;
|
int param_3 = maskCtrl0;
|
||||||
maskAlpha = sampleMask(param, uMaskTexture0, uMaskTexture0Smplr, param_1, param_2, param_3);
|
maskAlpha = sampleMask(param, maskTexture0, maskTexture0Smplr, param_1, param_2, param_3);
|
||||||
float4 color = vBaseColor;
|
float4 color = baseColor;
|
||||||
int color0Combine = (ctrl >> 6) & 3;
|
int color0Combine = (ctrl >> 6) & 3;
|
||||||
if (color0Combine != 0)
|
if (color0Combine != 0)
|
||||||
{
|
{
|
||||||
int color0Filter = (ctrl >> 4) & 3;
|
int color0Filter = (ctrl >> 4) & 3;
|
||||||
float2 param_4 = vColorTexCoord0;
|
float2 param_4 = colorTexCoord0;
|
||||||
float2 param_5 = uColorTextureSize0;
|
float2 param_5 = colorTextureSize0;
|
||||||
float2 param_6 = gl_FragCoord.xy;
|
float2 param_6 = fragCoord;
|
||||||
float2 param_7 = uFramebufferSize;
|
float2 param_7 = framebufferSize;
|
||||||
float4 param_8 = uFilterParams0;
|
float4 param_8 = filterParams0;
|
||||||
float4 param_9 = uFilterParams1;
|
float4 param_9 = filterParams1;
|
||||||
float4 param_10 = uFilterParams2;
|
float4 param_10 = filterParams2;
|
||||||
int param_11 = color0Filter;
|
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_12 = color;
|
||||||
float4 param_13 = color0;
|
float4 param_13 = color0;
|
||||||
int param_14 = color0Combine;
|
int param_14 = color0Combine;
|
||||||
|
@ -586,21 +590,31 @@ void calculateColor(thread const int& tileCtrl, thread const int& ctrl, thread t
|
||||||
color.w *= maskAlpha;
|
color.w *= maskAlpha;
|
||||||
int compositeOp = (ctrl >> 8) & 15;
|
int compositeOp = (ctrl >> 8) & 15;
|
||||||
float4 param_15 = color;
|
float4 param_15 = color;
|
||||||
float2 param_16 = uFramebufferSize;
|
float2 param_16 = framebufferSize;
|
||||||
float2 param_17 = gl_FragCoord.xy;
|
float2 param_17 = fragCoord;
|
||||||
int param_18 = compositeOp;
|
int param_18 = compositeOp;
|
||||||
color = composite(param_15, uDestTexture, uDestTextureSmplr, param_16, param_17, param_18);
|
color = composite(param_15, destTexture, destTextureSmplr, param_16, param_17, param_18);
|
||||||
float3 _1347 = color.xyz * color.w;
|
float3 _1340 = color.xyz * color.w;
|
||||||
color = float4(_1347.x, _1347.y, _1347.z, color.w);
|
color = float4(_1340.x, _1340.y, _1340.z, color.w);
|
||||||
oFragColor = color;
|
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 = {};
|
main0_out out = {};
|
||||||
int param = int(in.vTileCtrl);
|
float2 param = gl_FragCoord.xy;
|
||||||
int param_1 = uCtrl;
|
float2 param_1 = uColorTextureSize0;
|
||||||
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_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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -12,13 +12,12 @@ struct main0_out
|
||||||
struct main0_in
|
struct main0_in
|
||||||
{
|
{
|
||||||
float2 vTexCoord [[user(locn0)]];
|
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)]])
|
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSrc [[texture(0)]], sampler uSrcSmplr [[sampler(0)]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ precision highp float;
|
||||||
precision highp sampler2D;
|
precision highp sampler2D;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fill.inc.glsl"
|
#include "fill_area.inc.glsl"
|
||||||
|
|
||||||
uniform sampler2D uAreaLUT;
|
uniform sampler2D uAreaLUT;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
|
@ -20,36 +22,39 @@ uniform vec2 uFramebufferSize;
|
||||||
uniform vec2 uTileSize;
|
uniform vec2 uTileSize;
|
||||||
|
|
||||||
in uvec2 aTessCoord;
|
in uvec2 aTessCoord;
|
||||||
in uint aFromPx;
|
in uvec4 aLineSegment;
|
||||||
in uint aToPx;
|
in int aTileIndex;
|
||||||
in vec2 aFromSubpx;
|
|
||||||
in vec2 aToSubpx;
|
|
||||||
in uint aTileIndex;
|
|
||||||
|
|
||||||
out vec2 vFrom;
|
out vec2 vFrom;
|
||||||
out vec2 vTo;
|
out vec2 vTo;
|
||||||
|
|
||||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth, vec2 tileSize) {
|
||||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
uint tilesPerRow = uint(stencilTextureWidth / tileSize.x);
|
||||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
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() {
|
vec4 computeVertexPosition(uint tileIndex,
|
||||||
vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x);
|
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;
|
vec4 lineSegment = vec4(packedLineSegment) / 256.0;
|
||||||
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
|
vec2 from = lineSegment.xy, to = lineSegment.zw;
|
||||||
|
|
||||||
vec2 position;
|
vec2 position;
|
||||||
if (aTessCoord.x == 0u)
|
if (tessCoord.x == 0u)
|
||||||
position.x = floor(min(from.x, to.x));
|
position.x = floor(min(from.x, to.x));
|
||||||
else
|
else
|
||||||
position.x = ceil(max(from.x, to.x));
|
position.x = ceil(max(from.x, to.x));
|
||||||
if (aTessCoord.y == 0u)
|
if (tessCoord.y == 0u)
|
||||||
position.y = floor(min(from.y, to.y));
|
position.y = floor(min(from.y, to.y));
|
||||||
else
|
else
|
||||||
position.y = uTileSize.y;
|
position.y = tileSize.y;
|
||||||
position.y = floor(position.y * 0.25);
|
position.y = floor(position.y * 0.25);
|
||||||
|
|
||||||
// Since each fragment corresponds to 4 pixels on a scanline, the varying interpolation will
|
// 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
|
// 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.
|
// offset 0.5. This adjustment of 1.5 accomplishes that.
|
||||||
vec2 offset = vec2(0.0, 1.5) - position * vec2(1.0, 4.0);
|
vec2 offset = vec2(0.0, 1.5) - position * vec2(1.0, 4.0);
|
||||||
vFrom = from + offset;
|
outFrom = from + offset;
|
||||||
vTo = to + 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
|
#ifdef PF_ORIGIN_UPPER_LEFT
|
||||||
globalPosition.y = -globalPosition.y;
|
globalPosition.y = -globalPosition.y;
|
||||||
#endif
|
#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);
|
||||||
}
|
}
|
|
@ -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));
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/tile_clip.fs.glsl
|
// pathfinder/shaders/tile_clip_copy.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2020 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
@ -19,10 +19,9 @@ precision highp sampler2D;
|
||||||
uniform sampler2D uSrc;
|
uniform sampler2D uSrc;
|
||||||
|
|
||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
in float vBackdrop;
|
|
||||||
|
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
oFragColor = clamp(abs(texture(uSrc, vTexCoord) + vBackdrop), 0.0, 1.0);
|
oFragColor = texture(uSrc, vTexCoord);
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/tile_clip.vs.glsl
|
// pathfinder/shaders/tile_clip_copy.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2020 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
@ -16,18 +16,24 @@ precision highp float;
|
||||||
precision highp sampler2D;
|
precision highp sampler2D;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in ivec2 aTileOffset;
|
in ivec2 aTileOffset;
|
||||||
in ivec2 aDestTileOrigin;
|
in int aTileIndex;
|
||||||
in ivec2 aSrcTileOrigin;
|
|
||||||
in int aSrcBackdrop;
|
|
||||||
|
|
||||||
out vec2 vTexCoord;
|
out vec2 vTexCoord;
|
||||||
out float vBackdrop;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 destPosition = vec2(aDestTileOrigin + aTileOffset) / vec2(256.0);
|
vec2 position = vec2(ivec2(aTileIndex % 256, aTileIndex / 256) + aTileOffset);
|
||||||
vec2 srcPosition = vec2(aSrcTileOrigin + aTileOffset) / vec2(256.0);
|
position *= vec2(16.0, 4.0) / uFramebufferSize;
|
||||||
vTexCoord = srcPosition;
|
|
||||||
vBackdrop = float(aSrcBackdrop);
|
vTexCoord = position;
|
||||||
gl_Position = vec4(mix(vec2(-1.0), vec2(1.0), destPosition), 0.0, 1.0);
|
|
||||||
|
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);
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -1,6 +1,4 @@
|
||||||
#version 330
|
// pathfinder/shaders/tile_fragment.inc.glsl
|
||||||
|
|
||||||
// pathfinder/shaders/tile.fs.glsl
|
|
||||||
//
|
//
|
||||||
// Copyright © 2020 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
@ -31,14 +29,6 @@
|
||||||
// + +
|
// + +
|
||||||
// Color UV 0 Color UV 1
|
// 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 EPSILON 0.00001
|
||||||
|
|
||||||
#define FRAC_6_PI 1.9098593171027443
|
#define FRAC_6_PI 1.9098593171027443
|
||||||
|
@ -81,25 +71,6 @@ precision highp sampler2D;
|
||||||
#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6
|
#define COMBINER_CTRL_COLOR_COMBINE_SHIFT 6
|
||||||
#define COMBINER_CTRL_COMPOSITE_SHIFT 8
|
#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
|
// Color sampling
|
||||||
|
|
||||||
vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord) {
|
vec4 sampleColor(sampler2D colorTexture, vec2 colorTexCoord) {
|
||||||
|
@ -565,27 +536,42 @@ float sampleMask(float maskAlpha,
|
||||||
|
|
||||||
// Main function
|
// 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.
|
// Sample mask.
|
||||||
int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK;
|
int maskCtrl0 = (tileCtrl >> TILE_CTRL_MASK_0_SHIFT) & TILE_CTRL_MASK_MASK;
|
||||||
float maskAlpha = 1.0;
|
float maskAlpha = 1.0;
|
||||||
maskAlpha = sampleMask(maskAlpha, uMaskTexture0, uMaskTextureSize0, vMaskTexCoord0, maskCtrl0);
|
maskAlpha = sampleMask(maskAlpha, maskTexture0, maskTextureSize0, maskTexCoord0, maskCtrl0);
|
||||||
|
|
||||||
// Sample color.
|
// Sample color.
|
||||||
vec4 color = vBaseColor;
|
vec4 color = baseColor;
|
||||||
int color0Combine = (ctrl >> COMBINER_CTRL_COLOR_COMBINE_SHIFT) &
|
int color0Combine = (ctrl >> COMBINER_CTRL_COLOR_COMBINE_SHIFT) &
|
||||||
COMBINER_CTRL_COLOR_COMBINE_MASK;
|
COMBINER_CTRL_COLOR_COMBINE_MASK;
|
||||||
if (color0Combine != 0) {
|
if (color0Combine != 0) {
|
||||||
int color0Filter = (ctrl >> COMBINER_CTRL_COLOR_FILTER_SHIFT) & COMBINER_CTRL_FILTER_MASK;
|
int color0Filter = (ctrl >> COMBINER_CTRL_COLOR_FILTER_SHIFT) & COMBINER_CTRL_FILTER_MASK;
|
||||||
vec4 color0 = filterColor(vColorTexCoord0,
|
vec4 color0 = filterColor(colorTexCoord0,
|
||||||
uColorTexture0,
|
colorTexture0,
|
||||||
uGammaLUT,
|
gammaLUT,
|
||||||
uColorTextureSize0,
|
colorTextureSize0,
|
||||||
gl_FragCoord.xy,
|
fragCoord,
|
||||||
uFramebufferSize,
|
framebufferSize,
|
||||||
uFilterParams0,
|
filterParams0,
|
||||||
uFilterParams1,
|
filterParams1,
|
||||||
uFilterParams2,
|
filterParams2,
|
||||||
color0Filter);
|
color0Filter);
|
||||||
color = combineColor0(color, color0, color0Combine);
|
color = combineColor0(color, color0, color0Combine);
|
||||||
}
|
}
|
||||||
|
@ -595,17 +581,9 @@ void calculateColor(int tileCtrl, int ctrl) {
|
||||||
|
|
||||||
// Apply composite.
|
// Apply composite.
|
||||||
int compositeOp = (ctrl >> COMBINER_CTRL_COMPOSITE_SHIFT) & COMBINER_CTRL_COMPOSITE_MASK;
|
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.
|
// Premultiply alpha.
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
oFragColor = color;
|
return color;
|
||||||
}
|
|
||||||
|
|
||||||
// Entry point
|
|
||||||
//
|
|
||||||
// TODO(pcwalton): Generate this dynamically.
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
calculateColor(int(vTileCtrl), uCtrl);
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue