Add some more features to blending, and expand texture upload features
This commit is contained in:
parent
9124d9856a
commit
7c655246ae
|
@ -333,6 +333,20 @@ dependencies = [
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cocoa"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color-backtrace"
|
name = "color-backtrace"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -1260,6 +1274,20 @@ dependencies = [
|
||||||
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "metal"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nfd"
|
name = "nfd"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
|
@ -1631,10 +1659,10 @@ dependencies = [
|
||||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_geometry 0.3.0",
|
"pathfinder_geometry 0.3.0",
|
||||||
"pathfinder_gpu 0.1.0",
|
"pathfinder_gpu 0.1.0",
|
||||||
|
@ -2791,6 +2819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
|
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
|
||||||
"checksum cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54"
|
"checksum cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54"
|
||||||
|
"checksum cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400"
|
||||||
"checksum color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90242aff9b6439332beb77ee416126367adcd6376b0dc80b39250e7debdd913d"
|
"checksum color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90242aff9b6439332beb77ee416126367adcd6376b0dc80b39250e7debdd913d"
|
||||||
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||||
"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
|
"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
|
||||||
|
@ -2891,6 +2920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
||||||
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
||||||
"checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157"
|
"checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157"
|
||||||
|
"checksum metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f83c7dcc2038e12f68493fa3de44235df27b2497178e257185b4b5b5d028a1e4"
|
||||||
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
|
||||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
|
|
@ -17,10 +17,10 @@ use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr,
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{RenderTarget, BlendState, BufferData, BufferTarget, BufferUploadMode};
|
use pathfinder_gpu::{RenderTarget, BlendFunc, BlendOp, BufferData, BufferTarget, BufferUploadMode};
|
||||||
use pathfinder_gpu::{ClearOps, DepthFunc, Device, Primitive, RenderOptions, RenderState};
|
use pathfinder_gpu::{ClearOps, DepthFunc, Device, Primitive, RenderOptions, RenderState};
|
||||||
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureFormat, UniformData};
|
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureDataRef, TextureFormat};
|
||||||
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -86,28 +86,35 @@ impl GLDevice {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Set blend.
|
// Set blend.
|
||||||
match render_options.blend {
|
match render_options.blend {
|
||||||
BlendState::Off => {
|
None => {
|
||||||
gl::Disable(gl::BLEND); ck();
|
gl::Disable(gl::BLEND); ck();
|
||||||
}
|
}
|
||||||
BlendState::RGBOneAlphaOne => {
|
Some(ref blend) => {
|
||||||
gl::BlendEquation(gl::FUNC_ADD); ck();
|
match blend.func {
|
||||||
gl::BlendFunc(gl::ONE, gl::ONE); ck();
|
BlendFunc::RGBOneAlphaOne => {
|
||||||
gl::Enable(gl::BLEND); ck();
|
gl::BlendFunc(gl::ONE, gl::ONE); ck();
|
||||||
}
|
}
|
||||||
BlendState::RGBOneAlphaOneMinusSrcAlpha => {
|
BlendFunc::RGBOneAlphaOneMinusSrcAlpha => {
|
||||||
gl::BlendEquation(gl::FUNC_ADD); ck();
|
gl::BlendFuncSeparate(gl::ONE,
|
||||||
gl::BlendFuncSeparate(gl::ONE,
|
gl::ONE_MINUS_SRC_ALPHA,
|
||||||
gl::ONE_MINUS_SRC_ALPHA,
|
gl::ONE,
|
||||||
gl::ONE,
|
gl::ONE); ck();
|
||||||
gl::ONE); ck();
|
}
|
||||||
gl::Enable(gl::BLEND); ck();
|
BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
|
||||||
}
|
gl::BlendFuncSeparate(gl::SRC_ALPHA,
|
||||||
BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
|
gl::ONE_MINUS_SRC_ALPHA,
|
||||||
gl::BlendEquation(gl::FUNC_ADD); ck();
|
gl::ONE,
|
||||||
gl::BlendFuncSeparate(gl::SRC_ALPHA,
|
gl::ONE); ck();
|
||||||
gl::ONE_MINUS_SRC_ALPHA,
|
}
|
||||||
gl::ONE,
|
}
|
||||||
gl::ONE); ck();
|
match blend.op {
|
||||||
|
BlendOp::Add => {
|
||||||
|
gl::BlendEquation(gl::FUNC_ADD); ck();
|
||||||
|
}
|
||||||
|
BlendOp::Subtract => {
|
||||||
|
gl::BlendEquation(gl::FUNC_SUBTRACT); ck();
|
||||||
|
}
|
||||||
|
}
|
||||||
gl::Enable(gl::BLEND); ck();
|
gl::Enable(gl::BLEND); ck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,13 +205,8 @@ impl GLDevice {
|
||||||
|
|
||||||
fn reset_render_options(&self, render_options: &RenderOptions) {
|
fn reset_render_options(&self, render_options: &RenderOptions) {
|
||||||
unsafe {
|
unsafe {
|
||||||
match render_options.blend {
|
if render_options.blend.is_some() {
|
||||||
BlendState::Off => {}
|
gl::Disable(gl::BLEND); ck();
|
||||||
BlendState::RGBOneAlphaOneMinusSrcAlpha |
|
|
||||||
BlendState::RGBOneAlphaOne |
|
|
||||||
BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
|
|
||||||
gl::Disable(gl::BLEND); ck();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if render_options.depth.is_some() {
|
if render_options.depth.is_some() {
|
||||||
|
@ -252,8 +254,26 @@ impl Device for GLDevice {
|
||||||
texture
|
texture
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> GLTexture {
|
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
||||||
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
-> GLTexture {
|
||||||
|
let channels = match (format, data) {
|
||||||
|
(TextureFormat::R8, TextureDataRef::U8(_)) => 1,
|
||||||
|
(TextureFormat::RGBA8, TextureDataRef::U8(_)) => 4,
|
||||||
|
(TextureFormat::RGBA32F, TextureDataRef::F32(_)) => 4,
|
||||||
|
_ => panic!("Unimplemented texture format in `create_texture_from_data`!"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let area = size.x() as usize * size.y() as usize;
|
||||||
|
let data_ptr = match data {
|
||||||
|
TextureDataRef::U8(data) => {
|
||||||
|
assert!(data.len() >= area * channels);
|
||||||
|
data.as_ptr() as *const GLvoid
|
||||||
|
}
|
||||||
|
TextureDataRef::F32(data) => {
|
||||||
|
assert!(data.len() >= area * channels);
|
||||||
|
data.as_ptr() as *const GLvoid
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
|
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -261,13 +281,13 @@ impl Device for GLDevice {
|
||||||
self.bind_texture(&texture, 0);
|
self.bind_texture(&texture, 0);
|
||||||
gl::TexImage2D(gl::TEXTURE_2D,
|
gl::TexImage2D(gl::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
gl::R8 as GLint,
|
format.gl_internal_format(),
|
||||||
size.x() as GLsizei,
|
size.x() as GLsizei,
|
||||||
size.y() as GLsizei,
|
size.y() as GLsizei,
|
||||||
0,
|
0,
|
||||||
gl::RED,
|
format.gl_format(),
|
||||||
gl::UNSIGNED_BYTE,
|
format.gl_type(),
|
||||||
data.as_ptr() as *const GLvoid); ck();
|
data_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_texture_parameters(&texture);
|
self.set_texture_parameters(&texture);
|
||||||
|
|
|
@ -33,7 +33,8 @@ pub trait Device: Sized {
|
||||||
type VertexAttr;
|
type VertexAttr;
|
||||||
|
|
||||||
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture;
|
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture;
|
||||||
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> Self::Texture;
|
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
||||||
|
-> Self::Texture;
|
||||||
fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
|
fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
|
||||||
-> Self::Shader;
|
-> Self::Shader;
|
||||||
fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind)
|
fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind)
|
||||||
|
@ -88,7 +89,7 @@ pub trait Device: Sized {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_luma();
|
.to_luma();
|
||||||
let size = Vector2I::new(image.width() as i32, image.height() as i32);
|
let size = Vector2I::new(image.width() as i32, image.height() as i32);
|
||||||
self.create_texture_from_data(size, &image)
|
self.create_texture_from_data(TextureFormat::R8, size, TextureDataRef::U8(&image))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_program_from_shader_names(
|
fn create_program_from_shader_names(
|
||||||
|
@ -181,7 +182,7 @@ pub struct RenderState<'a, D> where D: Device {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RenderOptions {
|
pub struct RenderOptions {
|
||||||
pub blend: BlendState,
|
pub blend: Option<BlendState>,
|
||||||
pub depth: Option<DepthState>,
|
pub depth: Option<DepthState>,
|
||||||
pub stencil: Option<StencilState>,
|
pub stencil: Option<StencilState>,
|
||||||
pub clear_ops: ClearOps,
|
pub clear_ops: ClearOps,
|
||||||
|
@ -201,14 +202,25 @@ pub enum RenderTarget<'a, D> where D: Device {
|
||||||
Framebuffer(&'a D::Framebuffer),
|
Framebuffer(&'a D::Framebuffer),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||||
|
pub struct BlendState {
|
||||||
|
pub func: BlendFunc,
|
||||||
|
pub op: BlendOp,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum BlendState {
|
pub enum BlendFunc {
|
||||||
Off,
|
|
||||||
RGBOneAlphaOne,
|
RGBOneAlphaOne,
|
||||||
RGBOneAlphaOneMinusSrcAlpha,
|
RGBOneAlphaOneMinusSrcAlpha,
|
||||||
RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub enum BlendOp {
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, Debug)]
|
#[derive(Clone, Copy, Default, Debug)]
|
||||||
pub struct DepthState {
|
pub struct DepthState {
|
||||||
pub func: DepthFunc,
|
pub func: DepthFunc,
|
||||||
|
@ -239,7 +251,7 @@ impl Default for RenderOptions {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> RenderOptions {
|
fn default() -> RenderOptions {
|
||||||
RenderOptions {
|
RenderOptions {
|
||||||
blend: BlendState::default(),
|
blend: None,
|
||||||
depth: None,
|
depth: None,
|
||||||
stencil: None,
|
stencil: None,
|
||||||
clear_ops: ClearOps::default(),
|
clear_ops: ClearOps::default(),
|
||||||
|
@ -248,10 +260,17 @@ impl Default for RenderOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BlendState {
|
impl Default for BlendFunc {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> BlendState {
|
fn default() -> BlendFunc {
|
||||||
BlendState::Off
|
BlendFunc::RGBOneAlphaOneMinusSrcAlpha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BlendOp {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> BlendOp {
|
||||||
|
BlendOp::Add
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +307,12 @@ pub enum TextureData {
|
||||||
F32(Vec<f32>),
|
F32(Vec<f32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum TextureDataRef<'a> {
|
||||||
|
U8(&'a [u8]),
|
||||||
|
F32(&'a [f32]),
|
||||||
|
}
|
||||||
|
|
||||||
impl UniformData {
|
impl UniformData {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_transform_3d(transform: &Transform4F) -> UniformData {
|
pub fn from_transform_3d(transform: &Transform4F) -> UniformData {
|
||||||
|
|
|
@ -8,10 +8,10 @@ edition = "2018"
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
byteorder = "1.3"
|
byteorder = "1.3"
|
||||||
block = "0.1"
|
block = "0.1"
|
||||||
cocoa = "0.18"
|
cocoa = "0.19"
|
||||||
core-foundation = "0.6"
|
core-foundation = "0.6"
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.3"
|
||||||
metal = "0.14"
|
metal = "0.17"
|
||||||
objc = "0.2"
|
objc = "0.2"
|
||||||
|
|
||||||
[dependencies.pathfinder_geometry]
|
[dependencies.pathfinder_geometry]
|
||||||
|
|
112
metal/src/lib.rs
112
metal/src/lib.rs
|
@ -26,9 +26,9 @@ use foreign_types::{ForeignType, ForeignTypeRef};
|
||||||
use metal::{self, Argument, ArgumentEncoder, Buffer, CommandBuffer, CommandBufferRef};
|
use metal::{self, Argument, ArgumentEncoder, Buffer, CommandBuffer, CommandBufferRef};
|
||||||
use metal::{CommandQueue, CompileOptions, CoreAnimationDrawable, CoreAnimationDrawableRef};
|
use metal::{CommandQueue, CompileOptions, CoreAnimationDrawable, CoreAnimationDrawableRef};
|
||||||
use metal::{CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Function, Library};
|
use metal::{CoreAnimationLayer, CoreAnimationLayerRef, DepthStencilDescriptor, Function, Library};
|
||||||
use metal::{MTLArgument, MTLArgumentEncoder, MTLBlendFactor, MTLClearColor, MTLColorWriteMask};
|
use metal::{MTLArgument, MTLArgumentEncoder, MTLBlendFactor, MTLBlendOperation, MTLClearColor};
|
||||||
use metal::{MTLCompareFunction, MTLDataType, MTLDevice, MTLFunctionType, MTLIndexType};
|
use metal::{MTLColorWriteMask, MTLCompareFunction, MTLDataType, MTLDevice, MTLFunctionType};
|
||||||
use metal::{MTLLoadAction, MTLOrigin, MTLPixelFormat, MTLPrimitiveType, MTLRegion};
|
use metal::{MTLIndexType, MTLLoadAction, MTLOrigin, MTLPixelFormat, MTLPrimitiveType, MTLRegion};
|
||||||
use metal::{MTLRenderPipelineReflection, MTLRenderPipelineState, MTLResourceOptions};
|
use metal::{MTLRenderPipelineReflection, MTLRenderPipelineState, MTLResourceOptions};
|
||||||
use metal::{MTLResourceUsage, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSize};
|
use metal::{MTLResourceUsage, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSize};
|
||||||
use metal::{MTLStencilOperation, MTLStorageMode, MTLStoreAction, MTLTextureType, MTLTextureUsage};
|
use metal::{MTLStencilOperation, MTLStorageMode, MTLStoreAction, MTLTextureType, MTLTextureUsage};
|
||||||
|
@ -43,9 +43,9 @@ use objc::runtime::{Class, Object};
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, DepthFunc, Device};
|
use pathfinder_gpu::{BlendFunc, BlendOp, BufferData, BufferTarget, BufferUploadMode, DepthFunc};
|
||||||
use pathfinder_gpu::{Primitive, RenderState, RenderTarget, ShaderKind, StencilFunc, TextureData};
|
use pathfinder_gpu::{Device, Primitive, RenderState, RenderTarget, ShaderKind, StencilFunc};
|
||||||
use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrClass};
|
use pathfinder_gpu::{TextureData, TextureDataRef, TextureFormat, UniformData, VertexAttrClass};
|
||||||
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
||||||
use pathfinder_simd::default::{F32x2, F32x4};
|
use pathfinder_simd::default::{F32x2, F32x4};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
@ -196,6 +196,7 @@ impl Device for MetalDevice {
|
||||||
TextureFormat::R8 => descriptor.set_pixel_format(MTLPixelFormat::R8Unorm),
|
TextureFormat::R8 => descriptor.set_pixel_format(MTLPixelFormat::R8Unorm),
|
||||||
TextureFormat::R16F => descriptor.set_pixel_format(MTLPixelFormat::R16Float),
|
TextureFormat::R16F => descriptor.set_pixel_format(MTLPixelFormat::R16Float),
|
||||||
TextureFormat::RGBA8 => descriptor.set_pixel_format(MTLPixelFormat::RGBA8Unorm),
|
TextureFormat::RGBA8 => descriptor.set_pixel_format(MTLPixelFormat::RGBA8Unorm),
|
||||||
|
TextureFormat::RGBA32F => descriptor.set_pixel_format(MTLPixelFormat::RGBA32Float),
|
||||||
}
|
}
|
||||||
descriptor.set_width(size.x() as u64);
|
descriptor.set_width(size.x() as u64);
|
||||||
descriptor.set_height(size.y() as u64);
|
descriptor.set_height(size.y() as u64);
|
||||||
|
@ -204,11 +205,18 @@ impl Device for MetalDevice {
|
||||||
MetalTexture { texture: self.device.new_texture(&descriptor), dirty: Cell::new(false) }
|
MetalTexture { texture: self.device.new_texture(&descriptor), dirty: Cell::new(false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> MetalTexture {
|
fn create_texture_from_data(&self, format: TextureFormat, size: Vector2I, data: TextureDataRef)
|
||||||
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
-> MetalTexture {
|
||||||
let texture = self.create_texture(TextureFormat::R8, size);
|
match (format, data) {
|
||||||
self.upload_to_texture(&texture, size, data);
|
(TextureFormat::R8, TextureDataRef::U8(data)) => {
|
||||||
texture
|
assert!(data.len() >= size.x() as usize * size.y() as usize);
|
||||||
|
let texture = self.create_texture(TextureFormat::R8, size);
|
||||||
|
self.upload_to_texture(&texture, size, data);
|
||||||
|
texture
|
||||||
|
}
|
||||||
|
_ => panic!("Unimplemented texture format in `create_texture_from_data`!"),
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_shader_from_source(&self, _: &str, source: &[u8], _: ShaderKind) -> MetalShader {
|
fn create_shader_from_source(&self, _: &str, source: &[u8], _: ShaderKind) -> MetalShader {
|
||||||
|
@ -455,6 +463,16 @@ impl Device for MetalDevice {
|
||||||
stride as u64 * 2);
|
stride as u64 * 2);
|
||||||
TextureData::U16(pixels)
|
TextureData::U16(pixels)
|
||||||
}
|
}
|
||||||
|
TextureFormat::RGBA32F => {
|
||||||
|
let channels = format.channels();
|
||||||
|
let stride = size.x() as usize * channels;
|
||||||
|
let mut pixels = vec![0.0; stride * size.y() as usize];
|
||||||
|
texture.get_bytes(pixels.as_mut_ptr() as *mut _,
|
||||||
|
metal_region,
|
||||||
|
0,
|
||||||
|
stride as u64 * 4);
|
||||||
|
TextureData::F32(pixels)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,29 +940,53 @@ impl MetalDevice {
|
||||||
let pixel_format = self.render_target_color_texture(&render_state.target).pixel_format();
|
let pixel_format = self.render_target_color_texture(&render_state.target).pixel_format();
|
||||||
pipeline_color_attachment.set_pixel_format(pixel_format);
|
pipeline_color_attachment.set_pixel_format(pixel_format);
|
||||||
|
|
||||||
let blending_enabled = render_state.options.blend != BlendState::Off;
|
|
||||||
pipeline_color_attachment.set_blending_enabled(blending_enabled);
|
|
||||||
match render_state.options.blend {
|
match render_state.options.blend {
|
||||||
BlendState::Off => {}
|
None => pipeline_color_attachment.set_blending_enabled(false),
|
||||||
BlendState::RGBOneAlphaOne => {
|
Some(ref blend) => {
|
||||||
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
|
pipeline_color_attachment.set_blending_enabled(true);
|
||||||
pipeline_color_attachment.set_destination_rgb_blend_factor(MTLBlendFactor::One);
|
match blend.func {
|
||||||
pipeline_color_attachment.set_source_alpha_blend_factor(MTLBlendFactor::One);
|
BlendFunc::RGBOneAlphaOne => {
|
||||||
pipeline_color_attachment.set_destination_alpha_blend_factor(MTLBlendFactor::One);
|
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
|
||||||
}
|
pipeline_color_attachment.set_destination_rgb_blend_factor(
|
||||||
BlendState::RGBOneAlphaOneMinusSrcAlpha => {
|
MTLBlendFactor::One);
|
||||||
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
|
pipeline_color_attachment.set_source_alpha_blend_factor(
|
||||||
pipeline_color_attachment.set_destination_rgb_blend_factor(
|
MTLBlendFactor::One);
|
||||||
MTLBlendFactor::OneMinusSourceAlpha);
|
pipeline_color_attachment.set_destination_alpha_blend_factor(
|
||||||
pipeline_color_attachment.set_source_alpha_blend_factor(MTLBlendFactor::One);
|
MTLBlendFactor::One);
|
||||||
pipeline_color_attachment.set_destination_alpha_blend_factor(MTLBlendFactor::One);
|
}
|
||||||
}
|
BlendFunc::RGBOneAlphaOneMinusSrcAlpha => {
|
||||||
BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
|
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
|
||||||
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::SourceAlpha);
|
pipeline_color_attachment.set_destination_rgb_blend_factor(
|
||||||
pipeline_color_attachment.set_destination_rgb_blend_factor(
|
MTLBlendFactor::OneMinusSourceAlpha);
|
||||||
MTLBlendFactor::OneMinusSourceAlpha);
|
pipeline_color_attachment.set_source_alpha_blend_factor(
|
||||||
pipeline_color_attachment.set_source_alpha_blend_factor(MTLBlendFactor::One);
|
MTLBlendFactor::One);
|
||||||
pipeline_color_attachment.set_destination_alpha_blend_factor(MTLBlendFactor::One);
|
pipeline_color_attachment.set_destination_alpha_blend_factor(
|
||||||
|
MTLBlendFactor::One);
|
||||||
|
}
|
||||||
|
BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
|
||||||
|
pipeline_color_attachment.set_source_rgb_blend_factor(
|
||||||
|
MTLBlendFactor::SourceAlpha);
|
||||||
|
pipeline_color_attachment.set_destination_rgb_blend_factor(
|
||||||
|
MTLBlendFactor::OneMinusSourceAlpha);
|
||||||
|
pipeline_color_attachment.set_source_alpha_blend_factor(
|
||||||
|
MTLBlendFactor::One);
|
||||||
|
pipeline_color_attachment.set_destination_alpha_blend_factor(
|
||||||
|
MTLBlendFactor::One);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match blend.op {
|
||||||
|
BlendOp::Add => {
|
||||||
|
pipeline_color_attachment.set_rgb_blend_operation(MTLBlendOperation::Add);
|
||||||
|
pipeline_color_attachment.set_alpha_blend_operation(
|
||||||
|
MTLBlendOperation::Add);
|
||||||
|
}
|
||||||
|
BlendOp::Subtract => {
|
||||||
|
pipeline_color_attachment.set_rgb_blend_operation(
|
||||||
|
MTLBlendOperation::Subtract);
|
||||||
|
pipeline_color_attachment.set_alpha_blend_operation(
|
||||||
|
MTLBlendOperation::Subtract);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1228,7 +1270,7 @@ impl SharedEvent {
|
||||||
*mut BlockBase<(*mut Object, u64), ()>;
|
*mut BlockBase<(*mut Object, u64), ()>;
|
||||||
(*block).flags |= BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE;
|
(*block).flags |= BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE;
|
||||||
(*block).extra = &BLOCK_EXTRA;
|
(*block).extra = &BLOCK_EXTRA;
|
||||||
msg_send![self.0, notifyListener:listener.0 atValue:value block:block];
|
let () = msg_send![self.0, notifyListener:listener.0 atValue:value block:block];
|
||||||
mem::forget(block);
|
mem::forget(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,7 +1418,7 @@ impl FunctionExt for Function {
|
||||||
let encoder: *mut MTLArgumentEncoder =
|
let encoder: *mut MTLArgumentEncoder =
|
||||||
msg_send![self.as_ptr(), newArgumentEncoderWithBufferIndex:buffer_index
|
msg_send![self.as_ptr(), newArgumentEncoderWithBufferIndex:buffer_index
|
||||||
reflection:&mut reflection];
|
reflection:&mut reflection];
|
||||||
msg_send![reflection, retain];
|
let () = msg_send![reflection, retain];
|
||||||
(ArgumentEncoder::from_ptr(encoder), Argument::from_ptr(reflection))
|
(ArgumentEncoder::from_ptr(encoder), Argument::from_ptr(reflection))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::transform3d::Transform4F;
|
use pathfinder_geometry::transform3d::Transform4F;
|
||||||
use pathfinder_content::color::ColorF;
|
use pathfinder_content::color::ColorF;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, ClearOps};
|
||||||
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderOptions, RenderState};
|
||||||
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureFormat, UniformData};
|
use pathfinder_gpu::{RenderTarget, StencilFunc, StencilState, TextureFormat, UniformData};
|
||||||
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||||
|
@ -455,7 +455,10 @@ where
|
||||||
],
|
],
|
||||||
viewport: self.mask_viewport(),
|
viewport: self.mask_viewport(),
|
||||||
options: RenderOptions {
|
options: RenderOptions {
|
||||||
blend: BlendState::RGBOneAlphaOne,
|
blend: Some(BlendState {
|
||||||
|
func: BlendFunc::RGBOneAlphaOne,
|
||||||
|
..BlendState::default()
|
||||||
|
}),
|
||||||
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
},
|
},
|
||||||
|
@ -523,7 +526,10 @@ where
|
||||||
uniforms: &uniforms,
|
uniforms: &uniforms,
|
||||||
viewport: self.draw_viewport(),
|
viewport: self.draw_viewport(),
|
||||||
options: RenderOptions {
|
options: RenderOptions {
|
||||||
blend: BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
blend: Some(BlendState {
|
||||||
|
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
}),
|
||||||
stencil: self.stencil_state(),
|
stencil: self.stencil_state(),
|
||||||
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
|
@ -754,7 +760,10 @@ where
|
||||||
],
|
],
|
||||||
viewport: self.draw_viewport(),
|
viewport: self.draw_viewport(),
|
||||||
options: RenderOptions {
|
options: RenderOptions {
|
||||||
blend: BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
blend: Some(BlendState {
|
||||||
|
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
}),
|
||||||
depth: Some(DepthState { func: DepthFunc::Less, write: false, }),
|
depth: Some(DepthState { func: DepthFunc::Less, write: false, }),
|
||||||
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
|
|
|
@ -21,9 +21,9 @@ use pathfinder_content::color::ColorU;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, Device, Primitive};
|
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, Device};
|
||||||
use pathfinder_gpu::{RenderOptions, RenderState, RenderTarget, UniformData, VertexAttrClass};
|
use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, UniformData};
|
||||||
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -187,7 +187,10 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
textures: &[],
|
textures: &[],
|
||||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||||
options: RenderOptions {
|
options: RenderOptions {
|
||||||
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
|
blend: Some(BlendState {
|
||||||
|
func: BlendFunc::RGBOneAlphaOneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
}),
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -422,7 +425,10 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
],
|
],
|
||||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||||
options: RenderOptions {
|
options: RenderOptions {
|
||||||
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
|
blend: Some(BlendState {
|
||||||
|
func: BlendFunc::RGBOneAlphaOneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
}),
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue