Merge branch 'master' of https://github.com/servo/pathfinder into swf_renderer

This commit is contained in:
Jon Hardie 2019-06-21 10:58:52 +12:00
commit ba1ff45cb2
107 changed files with 3453 additions and 1093 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@ target
/site/dist
node_modules
/examples/c_canvas_minimal/build
/shaders/build
# Editors
*.swp

89
Cargo.lock generated
View File

@ -161,6 +161,24 @@ dependencies = [
"pathfinder_renderer 0.1.0",
]
[[package]]
name = "canvas_metal_minimal"
version = "0.1.0"
dependencies = [
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_canvas 0.1.0",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_metal 0.1.0",
"pathfinder_renderer 0.1.0",
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2-sys 0.32.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "canvas_minimal"
version = "0.1.0"
@ -419,13 +437,16 @@ name = "demo"
version = "0.1.0"
dependencies = [
"color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_demo 0.1.0",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_metal 0.1.0",
"pathfinder_simd 0.3.0",
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1083,6 +1104,23 @@ name = "memoffset"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "metal"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.18.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.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"objc-foundation 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 = "nfd"
version = "0.0.4"
@ -1187,6 +1225,33 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.6 (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 = "objc_exception"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "objc_id"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1280,9 +1345,11 @@ dependencies = [
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_metal 0.1.0",
"pathfinder_renderer 0.1.0",
"pathfinder_simd 0.3.0",
"pathfinder_svg 0.1.0",
@ -1356,10 +1423,28 @@ dependencies = [
"usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinder_metal"
version = "0.1.0"
dependencies = [
"bitflags 1.0.4 (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.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.18.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)",
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_geometry 0.3.0",
"pathfinder_gpu 0.1.0",
"pathfinder_simd 0.3.0",
]
[[package]]
name = "pathfinder_renderer"
version = "0.1.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2374,6 +2459,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157"
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
@ -2387,6 +2473,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "31d20fd2b37e07cf5125be68357b588672e8cefe9a96f8c17a9d46053b3e590d"
"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
"checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc"
"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"

View File

@ -7,6 +7,7 @@ members = [
"demo/magicleap",
"demo/native",
"examples/canvas_glutin_minimal",
"examples/canvas_metal_minimal",
"examples/canvas_minimal",
"examples/canvas_moire",
"examples/canvas_text",
@ -17,6 +18,7 @@ members = [
"gpu",
"flash",
"lottie",
"metal",
"renderer",
"simd",
"svg",

View File

@ -25,17 +25,23 @@ extern "C" {
#define PF_LINE_CAP_SQUARE 1
#define PF_LINE_CAP_ROUND 2
#define PF_LINE_JOIN_MITER 0
#define PF_LINE_JOIN_BEVEL 1
#define PF_LINE_JOIN_ROUND 2
// `geometry`
#define PF_ARC_DIRECTION_CW 0
#define PF_ARC_DIRECTION_CCW 1
// `gl`
#define PF_GL_VERSION_GL3 0
#define PF_GL_VERSION_GLES3 1
// `gpu`
// `renderer`
#define PF_CLEAR_FLAGS_HAS_COLOR 0x1
#define PF_CLEAR_FLAGS_HAS_DEPTH 0x2
#define PF_CLEAR_FLAGS_HAS_STENCIL 0x4
#define PF_CLEAR_FLAGS_HAS_RECT 0x8
#define PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR 0x1
// Types
@ -48,6 +54,8 @@ typedef struct PFPath *PFPathRef;
struct PFCanvasFontContext;
typedef struct PFCanvasFontContext *PFCanvasFontContextRef;
typedef uint8_t PFLineCap;
typedef uint8_t PFLineJoin;
typedef uint8_t PFArcDirection;
// `geometry`
@ -85,24 +93,21 @@ typedef uint32_t PFGLVersion;
// `gpu`
typedef uint8_t PFClearFlags;
struct PFClearParams {
PFColorF color;
float depth;
uint8_t stencil;
PFRectI rect;
PFClearFlags flags;
};
typedef struct PFClearParams PFClearParams;
struct PFResourceLoader;
typedef struct PFResourceLoader *PFResourceLoaderRef;
// `renderer`
struct PFRenderOptions {
typedef uint8_t PFRendererOptionsFlags;
struct PFRendererOptions {
PFColorF background_color;
PFRendererOptionsFlags flags;
};
struct PFBuildOptions {
uint32_t placeholder;
};
typedef struct PFRenderOptions PFRenderOptions;
typedef struct PFRendererOptions PFRendererOptions;
typedef struct PFBuildOptions PFBuildOptions;
struct PFScene;
typedef struct PFScene *PFSceneRef;
struct PFSceneProxy;
@ -122,6 +127,12 @@ void PFCanvasFillRect(PFCanvasRef canvas, const PFRectF *rect);
void PFCanvasStrokeRect(PFCanvasRef canvas, const PFRectF *rect);
void PFCanvasSetLineWidth(PFCanvasRef canvas, float new_line_width);
void PFCanvasSetLineCap(PFCanvasRef canvas, PFLineCap new_line_cap);
void PFCanvasSetLineJoin(PFCanvasRef canvas, PFLineJoin new_line_join);
void PFCanvasSetMiterLimit(PFCanvasRef canvas, float new_miter_limit);
void PFCanvasSetLineDash(PFCanvasRef canvas,
const float *new_line_dashes,
size_t new_line_dash_count);
void PFCanvasSetLineDashOffset(PFCanvasRef canvas, float offset);
void PFCanvasFillPath(PFCanvasRef canvas, PFPathRef path);
void PFCanvasStrokePath(PFCanvasRef canvas, PFPathRef path);
PFPathRef PFPathCreate();
@ -134,6 +145,20 @@ void PFPathBezierCurveTo(PFPathRef path,
const PFVector2F *ctrl0,
const PFVector2F *ctrl1,
const PFVector2F *to);
void PFPathArc(PFPathRef path,
const PFVector2F *center,
float radius,
float start_angle,
float end_angle,
PFArcDirection direction);
void PFPathArcTo(PFPathRef path, const PFVector2F *ctrl, const PFVector2F *to, float radius);
void PFPathRect(PFPathRef path, const PFRectF *rect);
void PFPathEllipse(PFPathRef path,
const PFVector2F *center,
const PFVector2F *axes,
float rotation,
float start_angle,
float end_angle);
void PFPathClosePath(PFPathRef path);
// `gl`
@ -142,17 +167,17 @@ PFGLDestFramebufferRef PFGLDestFramebufferCreateFullWindow(const PFVector2I *win
void PFGLDestFramebufferDestroy(PFGLDestFramebufferRef dest_framebuffer);
PFGLDeviceRef PFGLDeviceCreate(PFGLVersion version, uint32_t default_framebuffer);
void PFGLDeviceDestroy(PFGLDeviceRef device);
void PFGLDeviceClear(PFGLDeviceRef device, const PFClearParams *params);
void PFGLLoadWith(PFGLFunctionLoader loader, void *userdata);
PFGLRendererRef PFGLRendererCreate(PFGLDeviceRef device,
PFResourceLoaderRef resources,
PFGLDestFramebufferRef dest_framebuffer);
PFGLDestFramebufferRef dest_framebuffer,
const PFRendererOptions *options);
void PFGLRendererDestroy(PFGLRendererRef renderer);
/// Returns a borrowed reference to the device.
PFGLDeviceRef PFGLRendererGetDevice(PFGLRendererRef renderer);
void PFSceneProxyBuildAndRenderGL(PFSceneProxyRef scene_proxy,
PFGLRendererRef renderer,
const PFRenderOptions *options);
const PFBuildOptions *build_options);
// `gpu`

View File

@ -11,33 +11,45 @@
//! C bindings to Pathfinder.
use gl;
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, LineJoin, Path2D};
use pathfinder_geometry::basic::rect::{RectF, RectI};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::color::ColorF;
use pathfinder_geometry::outline::ArcDirection;
use pathfinder_geometry::stroke::LineCap;
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use pathfinder_renderer::scene::Scene;
use pathfinder_simd::default::F32x4;
use std::ffi::CString;
use std::os::raw::{c_char, c_void};
use std::slice;
// Constants
// `canvas`
pub const PF_LINE_CAP_BUTT: u8 = 0;
pub const PF_LINE_CAP_SQUARE: u8 = 1;
pub const PF_LINE_CAP_ROUND: u8 = 2;
pub const PF_CLEAR_FLAGS_HAS_COLOR: u8 = 0x1;
pub const PF_CLEAR_FLAGS_HAS_DEPTH: u8 = 0x2;
pub const PF_CLEAR_FLAGS_HAS_STENCIL: u8 = 0x4;
pub const PF_CLEAR_FLAGS_HAS_RECT: u8 = 0x8;
pub const PF_LINE_JOIN_MITER: u8 = 0;
pub const PF_LINE_JOIN_BEVEL: u8 = 1;
pub const PF_LINE_JOIN_ROUND: u8 = 2;
// `geometry`
pub const PF_ARC_DIRECTION_CW: u8 = 0;
pub const PF_ARC_DIRECTION_CCW: u8 = 1;
// `renderer`
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
// Types
@ -46,6 +58,8 @@ pub type PFCanvasRef = *mut CanvasRenderingContext2D;
pub type PFPathRef = *mut Path2D;
pub type PFCanvasFontContextRef = *mut CanvasFontContext;
pub type PFLineCap = u8;
pub type PFLineJoin = u8;
pub type PFArcDirection = u8;
// `geometry`
#[repr(C)]
@ -87,22 +101,19 @@ pub type PFGLRendererRef = *mut Renderer<GLDevice>;
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
// stable?
pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>;
#[repr(C)]
pub struct PFClearParams {
pub color: PFColorF,
pub depth: f32,
pub stencil: u8,
pub rect: PFRectI,
pub flags: PFClearFlags,
}
pub type PFClearFlags = u8;
// `renderer`
pub type PFSceneRef = *mut Scene;
pub type PFSceneProxyRef = *mut SceneProxy;
#[repr(C)]
pub struct PFRendererOptions {
pub background_color: PFColorF,
pub flags: PFRendererOptionsFlags,
}
pub type PFRendererOptionsFlags = u8;
// TODO(pcwalton)
#[repr(C)]
pub struct PFRenderOptions {
pub struct PFBuildOptions {
pub placeholder: u32,
}
@ -168,6 +179,32 @@ pub unsafe extern "C" fn PFCanvasSetLineCap(canvas: PFCanvasRef, new_line_cap: P
});
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasSetLineJoin(canvas: PFCanvasRef, new_line_join: PFLineJoin) {
(*canvas).set_line_join(match new_line_join {
PF_LINE_JOIN_BEVEL => LineJoin::Bevel,
PF_LINE_JOIN_ROUND => LineJoin::Round,
_ => LineJoin::Miter,
});
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasSetMiterLimit(canvas: PFCanvasRef, new_miter_limit: f32) {
(*canvas).set_miter_limit(new_miter_limit);
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasSetLineDash(canvas: PFCanvasRef,
new_line_dashes: *const f32,
new_line_dash_count: usize) {
(*canvas).set_line_dash(slice::from_raw_parts(new_line_dashes, new_line_dash_count).to_vec())
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offset: f32) {
(*canvas).set_line_dash_offset(new_offset)
}
/// Consumes the path.
#[no_mangle]
pub unsafe extern "C" fn PFCanvasFillPath(canvas: PFCanvasRef, path: PFPathRef) {
@ -220,6 +257,40 @@ pub unsafe extern "C" fn PFPathBezierCurveTo(path: PFPathRef,
(*path).bezier_curve_to((*ctrl0).to_rust(), (*ctrl1).to_rust(), (*to).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFPathArc(path: PFPathRef,
center: *const PFVector2F,
radius: f32,
start_angle: f32,
end_angle: f32,
direction: PFArcDirection) {
let direction = if direction == 0 { ArcDirection::CW } else { ArcDirection::CCW };
(*path).arc((*center).to_rust(), radius, start_angle, end_angle, direction)
}
#[no_mangle]
pub unsafe extern "C" fn PFPathArcTo(path: PFPathRef,
ctrl: *const PFVector2F,
to: *const PFVector2F,
radius: f32) {
(*path).arc_to((*ctrl).to_rust(), (*to).to_rust(), radius)
}
#[no_mangle]
pub unsafe extern "C" fn PFPathRect(path: PFPathRef, rect: *const PFRectF) {
(*path).rect((*rect).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFPathEllipse(path: PFPathRef,
center: *const PFVector2F,
axes: *const PFVector2F,
rotation: f32,
start_angle: f32,
end_angle: f32) {
(*path).ellipse((*center).to_rust(), (*axes).to_rust(), rotation, start_angle, end_angle)
}
#[no_mangle]
pub unsafe extern "C" fn PFPathClosePath(path: PFPathRef) {
(*path).close_path()
@ -252,11 +323,6 @@ pub unsafe extern "C" fn PFGLDeviceDestroy(device: PFGLDeviceRef) {
drop(Box::from_raw(device))
}
#[no_mangle]
pub unsafe extern "C" fn PFGLDeviceClear(device: PFGLDeviceRef, params: *const PFClearParams) {
(*device).clear(&(*params).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFResourceLoaderDestroy(loader: PFResourceLoaderRef) {
drop(Box::from_raw(loader))
@ -279,11 +345,13 @@ pub unsafe extern "C" fn PFGLDestFramebufferDestroy(dest_framebuffer: PFGLDestFr
#[no_mangle]
pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef,
resources: PFResourceLoaderRef,
dest_framebuffer: PFGLDestFramebufferRef)
dest_framebuffer: PFGLDestFramebufferRef,
options: *const PFRendererOptions)
-> PFGLRendererRef {
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
&**resources,
*Box::from_raw(dest_framebuffer))))
*Box::from_raw(dest_framebuffer),
(*options).to_rust())))
}
#[no_mangle]
@ -299,8 +367,8 @@ pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFG
#[no_mangle]
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
renderer: PFGLRendererRef,
options: *const PFRenderOptions) {
(*scene_proxy).build_and_render(&mut *renderer, (*options).to_rust())
build_options: *const PFBuildOptions) {
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
}
// `renderer`
@ -358,28 +426,14 @@ impl PFVector2I {
}
}
// Helpers for `gpu`
// Helpers for `renderer`
impl PFClearParams {
pub fn to_rust(&self) -> ClearParams {
ClearParams {
color: if (self.flags & PF_CLEAR_FLAGS_HAS_COLOR) != 0 {
Some(self.color.to_rust())
} else {
None
},
rect: if (self.flags & PF_CLEAR_FLAGS_HAS_RECT) != 0 {
Some(self.rect.to_rust())
} else {
None
},
depth: if (self.flags & PF_CLEAR_FLAGS_HAS_DEPTH) != 0 {
Some(self.depth)
} else {
None
},
stencil: if (self.flags & PF_CLEAR_FLAGS_HAS_STENCIL) != 0 {
Some(self.stencil)
impl PFRendererOptions {
pub fn to_rust(&self) -> RendererOptions {
let has_background_color = self.flags & PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR;
RendererOptions {
background_color: if has_background_color != 0 {
Some(self.background_color.to_rust())
} else {
None
},
@ -387,10 +441,8 @@ impl PFClearParams {
}
}
// Helpers for `renderer`
impl PFRenderOptions {
pub fn to_rust(&self) -> RenderOptions {
RenderOptions::default()
impl PFBuildOptions {
pub fn to_rust(&self) -> BuildOptions {
BuildOptions::default()
}
}

View File

@ -4,6 +4,9 @@ version = "0.1.0"
edition = "2018"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
[features]
pf-gl = []
[dependencies]
clap = "2.32"
gl = "0.6"
@ -39,3 +42,9 @@ path = "../../svg"
[dependencies.pathfinder_ui]
path = "../../ui"
[target.'cfg(target_os = "macos")'.dependencies]
metal = "0.14"
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
path = "../../metal"

View File

@ -63,20 +63,19 @@ where
) -> GroundVertexArray<D> {
let vertex_array = device.create_vertex_array();
let position_attr = device.get_vertex_attr(&ground_program.program, "Position");
let position_attr = device.get_vertex_attr(&ground_program.program, "Position").unwrap();
device.bind_vertex_array(&vertex_array);
device.use_program(&ground_program.program);
device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Float,
attr_type: VertexAttrType::U8,
stride: 0,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: 4,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.bind_buffer(quad_vertex_indices_buffer, BufferTarget::Index);
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
GroundVertexArray { vertex_array }
}

View File

@ -27,12 +27,12 @@ use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::basic::transform2d::Transform2DF;
use pathfinder_geometry::basic::transform3d::Transform3DF;
use pathfinder_geometry::color::ColorU;
use pathfinder_gl::GLDevice;
use pathfinder_gpu::Device;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::Device;
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderStats, RenderTime, Renderer};
use pathfinder_renderer::options::{RenderOptions, RenderTransform};
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::{RenderStats, RenderTime, Renderer};
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
use pathfinder_renderer::post::STEM_DARKENING_FACTORS;
use pathfinder_renderer::scene::Scene;
use pathfinder_svg::BuiltSVG;
@ -44,6 +44,11 @@ use std::thread;
use std::time::Duration;
use usvg::{Options as UsvgOptions, Tree};
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
use pathfinder_gl::GLDevice as DeviceImpl;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice as DeviceImpl;
static DEFAULT_SVG_VIRTUAL_PATH: &'static str = "svg/Ghostscript_Tiger.svg";
const MOUSELOOK_ROTATION_SPEED: f32 = 0.007;
@ -112,22 +117,31 @@ pub struct DemoApp<W> where W: Window {
build_time: Option<Duration>,
ui_model: DemoUIModel,
ui_presenter: DemoUIPresenter<GLDevice>,
ui_presenter: DemoUIPresenter<DeviceImpl>,
scene_proxy: SceneProxy,
renderer: Renderer<GLDevice>,
renderer: Renderer<DeviceImpl>,
scene_framebuffer: Option<<GLDevice as Device>::Framebuffer>,
scene_framebuffer: Option<<DeviceImpl as Device>::Framebuffer>,
ground_program: GroundProgram<GLDevice>,
ground_vertex_array: GroundVertexArray<GLDevice>,
ground_program: GroundProgram<DeviceImpl>,
ground_vertex_array: GroundVertexArray<DeviceImpl>,
}
impl<W> DemoApp<W> where W: Window {
pub fn new(window: W, window_size: WindowSize, mut options: Options) -> DemoApp<W> {
let expire_message_event_id = window.create_user_event_id();
let device = GLDevice::new(window.gl_version(), window.gl_default_framebuffer());
let device;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
{
device = DeviceImpl::new(window.metal_layer());
}
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
{
device = DeviceImpl::new(window.gl_version(), window.gl_default_framebuffer());
}
let resources = window.resource_loader();
// Read command line options.
@ -144,8 +158,12 @@ impl<W> DemoApp<W> where W: Window {
viewport,
window_size: window_size.device_size(),
};
// FIXME(pcwalton)
let render_options = RendererOptions {
background_color: None,
};
let renderer = Renderer::new(device, resources, dest_framebuffer);
let renderer = Renderer::new(device, resources, dest_framebuffer, render_options);
let scene_metadata = SceneMetadata::new_clipping_view_box(&mut built_svg.scene,
viewport.size());
let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size());
@ -246,7 +264,7 @@ impl<W> DemoApp<W> where W: Window {
Camera::TwoD(transform) => Some(RenderTransform::Transform2D(transform)),
};
let render_options = RenderOptions {
let build_options = BuildOptions {
transform: self.render_transform.clone().unwrap(),
dilation: if self.ui_model.stem_darkening_effect_enabled {
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
@ -258,7 +276,7 @@ impl<W> DemoApp<W> where W: Window {
subpixel_aa_enabled: self.ui_model.subpixel_aa_effect_enabled,
};
self.render_command_stream = Some(self.scene_proxy.build_with_stream(render_options));
self.render_command_stream = Some(self.scene_proxy.build_with_stream(build_options));
}
fn handle_events(&mut self, events: Vec<Event>) -> Vec<UIEvent> {
@ -488,7 +506,9 @@ impl<W> DemoApp<W> where W: Window {
self.handle_ui_events(frame, &mut ui_action);
self.window.present();
self.renderer.device.end_commands();
self.window.present(&mut self.renderer.device);
self.frame_counter += 1;
}

View File

@ -15,10 +15,13 @@ use crate::window::{View, Window};
use crate::{BackgroundColor, DemoApp, UIVisibility};
use image::ColorType;
use pathfinder_geometry::color::{ColorF, ColorU};
use pathfinder_gpu::{ClearParams, DepthFunc, DepthState, Device, Primitive, RenderState};
use pathfinder_gpu::{TextureFormat, UniformData};
use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions};
use pathfinder_gpu::{RenderState, RenderTarget, TextureData, TextureFormat, UniformData};
use pathfinder_geometry::basic::rect::RectI;
use pathfinder_geometry::basic::transform3d::Transform3DF;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode};
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::RenderMode;
use pathfinder_renderer::gpu_data::RenderCommand;
use pathfinder_renderer::options::RenderTransform;
use pathfinder_renderer::post::DEFRINGING_KERNEL_CORE_GRAPHICS;
@ -42,13 +45,14 @@ const GRIDLINE_COUNT: i32 = 10;
impl<W> DemoApp<W> where W: Window {
pub fn prepare_frame_rendering(&mut self) -> u32 {
// Make the GL context current.
// Make the context current.
let view = self.ui_model.mode.view(0);
self.window.make_current(view);
// Set up framebuffers.
let window_size = self.window_size.device_size();
let scene_count = match self.camera.mode() {
let mode = self.camera.mode();
let scene_count = match mode {
Mode::VR => {
let viewport = self.window.viewport(View::Stereo(0));
if self.scene_framebuffer.is_none()
@ -82,49 +86,47 @@ impl<W> DemoApp<W> where W: Window {
}
};
// Begin drawing the scene.
self.renderer.bind_dest_framebuffer();
// Clear to the appropriate color.
let clear_color = if scene_count == 2 {
ColorF::transparent_black()
} else {
self.background_color().to_f32()
let clear_color = match mode {
Mode::TwoD => Some(self.background_color().to_f32()),
Mode::ThreeD => None,
Mode::VR => Some(ColorF::transparent_black()),
};
self.renderer.device.clear(&ClearParams {
color: Some(clear_color),
depth: Some(1.0),
stencil: Some(0),
..ClearParams::default()
});
self.renderer.set_options(RendererOptions { background_color: clear_color });
scene_count
}
pub fn draw_scene(&mut self) {
self.renderer.device.begin_commands();
let view = self.ui_model.mode.view(0);
self.window.make_current(view);
if self.camera.mode() != Mode::VR {
self.draw_environment();
self.draw_environment(0);
}
self.renderer.device.end_commands();
self.render_vector_scene();
// Reattach default framebuffer.
if self.camera.mode() != Mode::VR {
return;
if self.camera.mode() == Mode::VR {
if let DestFramebuffer::Other(scene_framebuffer) =
self.renderer
.replace_dest_framebuffer(DestFramebuffer::Default {
viewport: self.window.viewport(View::Mono),
window_size: self.window_size.device_size(),
})
{
self.scene_framebuffer = Some(scene_framebuffer);
}
}
}
if let DestFramebuffer::Other(scene_framebuffer) =
self.renderer
.replace_dest_framebuffer(DestFramebuffer::Default {
viewport: self.window.viewport(View::Mono),
window_size: self.window_size.device_size(),
})
{
self.scene_framebuffer = Some(scene_framebuffer);
}
pub fn begin_compositing(&mut self) {
self.renderer.device.begin_commands();
}
pub fn composite_scene(&mut self, render_scene_index: u32) {
@ -151,21 +153,12 @@ impl<W> DemoApp<W> where W: Window {
let viewport = self.window.viewport(View::Stereo(render_scene_index));
self.window.make_current(View::Stereo(render_scene_index));
self.renderer
.replace_dest_framebuffer(DestFramebuffer::Default {
viewport,
window_size: self.window_size.device_size(),
});
self.renderer.bind_draw_framebuffer();
self.renderer.device.clear(&ClearParams {
color: Some(self.background_color().to_f32()),
depth: Some(1.0),
stencil: Some(0),
rect: Some(viewport),
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
viewport,
window_size: self.window_size.device_size(),
});
self.draw_environment();
self.draw_environment(render_scene_index);
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
let scene_texture = self.renderer.device.framebuffer_texture(scene_framebuffer);
@ -207,7 +200,7 @@ impl<W> DemoApp<W> where W: Window {
}
// Draws the ground, if applicable.
fn draw_environment(&self) {
fn draw_environment(&self, render_scene_index: u32) {
let frame = &self.current_frame.as_ref().unwrap();
let perspective = match frame.transform {
@ -233,31 +226,35 @@ impl<W> DemoApp<W> where W: Window {
transform =
transform.post_mul(&Transform3DF::from_scale(ground_scale, 1.0, ground_scale));
let device = &self.renderer.device;
device.bind_vertex_array(&self.ground_vertex_array.vertex_array);
device.use_program(&self.ground_program.program);
device.set_uniform(
&self.ground_program.transform_uniform,
UniformData::from_transform_3d(&transform),
);
device.set_uniform(
&self.ground_program.ground_color_uniform,
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0),
);
device.set_uniform(
&self.ground_program.gridline_color_uniform,
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0),
);
device.set_uniform(&self.ground_program.gridline_count_uniform,
UniformData::Int(GRIDLINE_COUNT));
device.draw_elements(
Primitive::Triangles,
6,
&RenderState {
// Don't clear the first scene after drawing it.
let clear_color = if render_scene_index == 0 {
Some(self.background_color().to_f32())
} else {
None
};
self.renderer.device.draw_elements(6, &RenderState {
target: &self.renderer.draw_render_target(),
program: &self.ground_program.program,
vertex_array: &self.ground_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &[],
uniforms: &[
(&self.ground_program.transform_uniform,
UniformData::from_transform_3d(&transform)),
(&self.ground_program.ground_color_uniform,
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0)),
(&self.ground_program.gridline_color_uniform,
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0)),
(&self.ground_program.gridline_count_uniform, UniformData::Int(GRIDLINE_COUNT)),
],
viewport: self.renderer.draw_viewport(),
options: RenderOptions {
depth: Some(DepthState { func: DepthFunc::Less, write: true }),
..RenderState::default()
clear_ops: ClearOps { color: clear_color, depth: Some(1.0), stencil: Some(0) },
..RenderOptions::default()
},
);
});
}
fn render_vector_scene(&mut self) {
@ -305,10 +302,11 @@ impl<W> DemoApp<W> where W: Window {
pub fn take_raster_screenshot(&mut self, path: PathBuf) {
let drawable_size = self.window_size.device_size();
let pixels = self
.renderer
.device
.read_pixels_from_default_framebuffer(drawable_size);
let viewport = RectI::new(Vector2I::default(), drawable_size);
let pixels = match self.renderer.device.read_pixels(&RenderTarget::Default, viewport) {
TextureData::U8(pixels) => pixels,
TextureData::U16(_) => panic!("Unexpected pixel format for default framebuffer!"),
};
image::save_buffer(
path,
&pixels,

View File

@ -500,9 +500,7 @@ where
Vector2I::new(widget_x, slider_track_y),
Vector2I::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT),
);
debug_ui_presenter
.ui_presenter
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
debug_ui_presenter.ui_presenter.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
let slider_knob_rect = RectI::new(
@ -528,7 +526,11 @@ where
let widget_origin = panel_position + Vector2I::new(0, widget_size.y() * index);
let widget_rect = RectI::new(widget_origin, widget_size);
if self.draw_menu_item(device, debug_ui_presenter, &text, widget_rect, false) {
if self.draw_menu_item(device,
debug_ui_presenter,
&text,
widget_rect,
false) {
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
// the contents of the file.
if let Ok(path) = window.run_save_dialog(screenshot_type.extension()) {
@ -554,7 +556,11 @@ where
let widget_rect = RectI::new(widget_origin, widget_size);
let selected = color == model.background_color;
if self.draw_menu_item(device, debug_ui_presenter, text, widget_rect, selected) {
if self.draw_menu_item(device,
debug_ui_presenter,
text,
widget_rect,
selected) {
model.background_color = color;
*action = UIAction::ModelChanged;
}

View File

@ -10,24 +10,38 @@
//! A minimal cross-platform windowing layer.
use gl::types::GLuint;
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_geometry::basic::rect::RectI;
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF};
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::ResourceLoader;
use rayon::ThreadPoolBuilder;
use std::path::PathBuf;
pub trait Window {
fn gl_version(&self) -> GLVersion;
fn gl_default_framebuffer(&self) -> GLuint {
0
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use metal::CoreAnimationLayerRef;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice;
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
use gl::types::GLuint;
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
use pathfinder_gl::{GLDevice, GLVersion};
pub trait Window {
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn gl_version(&self) -> GLVersion;
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn gl_default_framebuffer(&self) -> GLuint { 0 }
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn present(&mut self, device: &mut GLDevice);
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn metal_layer(&self) -> &CoreAnimationLayerRef;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn present(&mut self, device: &mut MetalDevice);
fn viewport(&self, view: View) -> RectI;
fn make_current(&mut self, view: View);
fn present(&mut self);
fn viewport(&self, view: View) -> RectI;
fn resource_loader(&self) -> &dyn ResourceLoader;
fn create_user_event_id(&self) -> u32;
fn push_user_event(message_type: u32, message_data: u32);

View File

@ -113,6 +113,7 @@ pub unsafe extern "C" fn magicleap_pathfinder_demo_run(app: *mut c_void) {
}
let scene_count = app.demo.prepare_frame(events);
app.demo.draw_scene();
app.demo.begin_compositing();
for scene_index in 0..scene_count {
app.demo.composite_scene(scene_index);
}

View File

@ -5,6 +5,7 @@ edition = "2018"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
[features]
pf-gl = ["pathfinder_demo/pf-gl"]
pf-no-simd = ["pathfinder_simd/pf-no-simd"]
[dependencies]
@ -30,5 +31,12 @@ path = "../../gpu"
[dependencies.pathfinder_simd]
path = "../../simd"
[target.'cfg(target_os = "macos")'.dependencies]
foreign-types = "0.3"
metal = "0.14"
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
path = "../../metal"
[target.'cfg(not(windows))'.dependencies]
jemallocator = "0.1"

View File

@ -15,16 +15,33 @@ use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize}
use pathfinder_demo::{DemoApp, Options};
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_geometry::basic::rect::RectI;
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
use sdl2::event::{Event as SDLEvent, WindowEvent};
use sdl2::keyboard::Keycode as SDLKeycode;
use sdl2::video::{GLContext, GLProfile, Window as SDLWindow};
use sdl2::video::Window as SDLWindow;
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
use sdl2_sys::{SDL_Event, SDL_UserEvent};
use std::path::PathBuf;
use std::ptr;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use foreign_types::ForeignTypeRef;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use metal::{CAMetalLayer, CoreAnimationLayerRef};
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use sdl2::hint;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use sdl2::render::Canvas;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use sdl2_sys::SDL_RenderGetMetalLayer;
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
use pathfinder_gl::{GLDevice, GLVersion};
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
use sdl2::video::{GLContext, GLProfile};
#[cfg(not(windows))]
use jemallocator;
@ -55,6 +72,7 @@ fn main() {
let scene_count = app.prepare_frame(events);
app.draw_scene();
app.begin_compositing();
for scene_index in 0..scene_count {
app.composite_scene(scene_index);
}
@ -69,22 +87,36 @@ thread_local! {
}
struct WindowImpl {
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
window: SDLWindow,
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
gl_context: GLContext,
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
canvas: Canvas<SDLWindow>,
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
metal_layer: *mut CAMetalLayer,
event_pump: EventPump,
#[allow(dead_code)]
gl_context: GLContext,
resource_loader: FilesystemResourceLoader,
selected_file: Option<PathBuf>,
open_svg_message_type: u32,
}
impl Window for WindowImpl {
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn gl_version(&self) -> GLVersion {
GLVersion::GL3
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn metal_layer(&self) -> &CoreAnimationLayerRef {
unsafe { CoreAnimationLayerRef::from_ptr(self.metal_layer) }
}
fn viewport(&self, view: View) -> RectI {
let (width, height) = self.window.drawable_size();
let (width, height) = self.window().drawable_size();
let mut width = width as i32;
let height = height as i32;
let mut x_offset = 0;
@ -95,12 +127,22 @@ impl Window for WindowImpl {
RectI::new(Vector2I::new(x_offset, 0), Vector2I::new(width, height))
}
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn make_current(&mut self, _view: View) {
self.window.gl_make_current(&self.gl_context).unwrap();
self.window().gl_make_current(&self.gl_context).unwrap();
}
fn present(&mut self) {
self.window.gl_swap_window();
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn make_current(&mut self, _: View) {}
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn present(&mut self, _: &mut GLDevice) {
self.window().gl_swap_window();
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn present(&mut self, device: &mut MetalDevice) {
device.present_drawable();
}
fn resource_loader(&self) -> &dyn ResourceLoader {
@ -141,6 +183,7 @@ impl Window for WindowImpl {
}
impl WindowImpl {
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn new() -> WindowImpl {
SDL_VIDEO.with(|sdl_video| {
SDL_EVENT.with(|sdl_event| {
@ -185,9 +228,55 @@ impl WindowImpl {
})
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn new() -> WindowImpl {
assert!(hint::set("SDL_RENDER_DRIVER", "metal"));
SDL_VIDEO.with(|sdl_video| {
SDL_EVENT.with(|sdl_event| {
let window = sdl_video
.window(
"Pathfinder Demo",
DEFAULT_WINDOW_WIDTH,
DEFAULT_WINDOW_HEIGHT,
)
.opengl()
.resizable()
.allow_highdpi()
.build()
.unwrap();
let canvas = window.into_canvas().present_vsync().build().unwrap();
let metal_layer = unsafe {
SDL_RenderGetMetalLayer(canvas.raw()) as *mut CAMetalLayer
};
let event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap());
let resource_loader = FilesystemResourceLoader::locate();
let open_svg_message_type = unsafe { sdl_event.register_event().unwrap() };
WindowImpl {
event_pump,
canvas,
metal_layer,
resource_loader,
open_svg_message_type,
selected_file: None,
}
})
})
}
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
fn window(&self) -> &SDLWindow { &self.window }
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn window(&self) -> &SDLWindow { self.canvas.window() }
fn size(&self) -> WindowSize {
let (logical_width, logical_height) = self.window.size();
let (drawable_width, _) = self.window.drawable_size();
let (logical_width, logical_height) = self.window().size();
let (drawable_width, _) = self.window().drawable_size();
WindowSize {
logical_size: Vector2I::new(logical_width as i32, logical_height as i32),
backing_scale_factor: drawable_width as f32 / logical_width as f32,

View File

@ -58,11 +58,9 @@ int main(int argc, const char **argv) {
PFGLDestFramebufferCreateFullWindow(&(PFVector2I){640, 480});
PFGLRendererRef renderer = PFGLRendererCreate(PFGLDeviceCreate(PF_GL_VERSION_GL3, 0),
PFFilesystemResourceLoaderLocate(),
dest_framebuffer);
// Clear to white.
PFGLDeviceClear(PFGLRendererGetDevice(renderer), &(PFClearParams){
(PFColorF){1.0, 1.0, 1.0, 1.0}, 0.0, 0, {0}, PF_CLEAR_FLAGS_HAS_COLOR
dest_framebuffer,
&(PFRendererOptions){
(PFColorF){1.0, 1.0, 1.0, 1.0}, PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR
});
// Make a canvas. We're going to draw a house.
@ -89,7 +87,7 @@ int main(int argc, const char **argv) {
// Render the canvas to screen.
PFSceneRef scene = PFCanvasCreateScene(canvas);
PFSceneProxyRef scene_proxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFRenderOptions){0});
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFBuildOptions){0});
SDL_GL_SwapWindow(window);
// Wait for a keypress.

View File

@ -12,18 +12,18 @@
use glutin::dpi::PhysicalSize;
use glutin::{ContextBuilder, ControlFlow, Event, EventsLoop, GlProfile, GlRequest, KeyboardInput};
use glutin::{VirtualKeyCode, WindowBuilder, WindowEvent};
use glutin::{VirtualKeyCode, WindowBuilder, WindowEvent};
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::color::ColorF;
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::options::BuildOptions;
fn main() {
// Calculate the right logical size of the window.
@ -50,10 +50,8 @@ fn main() {
// Create a Pathfinder renderer.
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(window_size));
// Clear to white.
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
DestFramebuffer::full_window(window_size),
RendererOptions { background_color: Some(ColorF::white()) });
// Make a canvas. We're going to draw a house.
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
@ -77,7 +75,7 @@ fn main() {
// Render the canvas to screen.
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
scene.build_and_render(&mut renderer, RenderOptions::default());
scene.build_and_render(&mut renderer, BuildOptions::default());
gl_context.swap_buffers().unwrap();
// Wait for a keypress.

View File

@ -0,0 +1,31 @@
[package]
name = "canvas_metal_minimal"
version = "0.1.0"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018"
[dependencies]
foreign-types = "0.3"
gl = "0.6"
metal = "0.14"
objc = "0.2"
sdl2 = "0.32"
sdl2-sys = "0.32"
[dependencies.pathfinder_canvas]
path = "../../canvas"
[dependencies.pathfinder_geometry]
path = "../../geometry"
[dependencies.pathfinder_gl]
path = "../../gl"
[dependencies.pathfinder_gpu]
path = "../../gpu"
[dependencies.pathfinder_metal]
path = "../../metal"
[dependencies.pathfinder_renderer]
path = "../../renderer"

View File

@ -0,0 +1,87 @@
// pathfinder/examples/canvas_metal_minimal/src/main.rs
//
// Copyright © 2019 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 foreign_types::ForeignTypeRef;
use metal::{CAMetalLayer, CoreAnimationLayerRef};
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::color::ColorF;
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_metal::MetalDevice;
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use sdl2::event::Event;
use sdl2::hint;
use sdl2::keyboard::Keycode;
use sdl2_sys::SDL_RenderGetMetalLayer;
fn main() {
// Set up SDL2.
assert!(hint::set("SDL_RENDER_DRIVER", "metal"));
let sdl_context = sdl2::init().unwrap();
let video = sdl_context.video().unwrap();
// Open a window.
let window_size = Vector2I::new(640, 480);
let window = video.window("Minimal example", window_size.x() as u32, window_size.y() as u32)
.opengl()
.build()
.unwrap();
// Create a Metal context.
let canvas = window.into_canvas().present_vsync().build().unwrap();
let metal_layer = unsafe {
CoreAnimationLayerRef::from_ptr(SDL_RenderGetMetalLayer(canvas.raw()) as *mut CAMetalLayer)
};
// Create a Pathfinder renderer.
let mut renderer = Renderer::new(MetalDevice::new(metal_layer),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(window_size),
RendererOptions { background_color: Some(ColorF::white()) });
// Make a canvas. We're going to draw a house.
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
// Set line width.
canvas.set_line_width(10.0);
// Draw walls.
canvas.stroke_rect(RectF::new(Vector2F::new(75.0, 140.0), Vector2F::new(150.0, 110.0)));
// Draw door.
canvas.fill_rect(RectF::new(Vector2F::new(130.0, 190.0), Vector2F::new(40.0, 60.0)));
// Draw roof.
let mut path = Path2D::new();
path.move_to(Vector2F::new(50.0, 140.0));
path.line_to(Vector2F::new(150.0, 60.0));
path.line_to(Vector2F::new(250.0, 140.0));
path.close_path();
canvas.stroke_path(path);
// Render the canvas to screen.
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
scene.build_and_render(&mut renderer, BuildOptions::default());
renderer.device.present_drawable();
// Wait for a keypress.
let mut event_pump = sdl_context.event_pump().unwrap();
loop {
match event_pump.wait_event() {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return,
_ => {}
}
}
}

View File

@ -14,11 +14,11 @@ use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::color::ColorF;
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
@ -48,10 +48,8 @@ fn main() {
// Create a Pathfinder renderer.
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(window_size));
// Clear to white.
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
DestFramebuffer::full_window(window_size),
RendererOptions { background_color: Some(ColorF::white()) });
// Make a canvas. We're going to draw a house.
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
@ -75,7 +73,7 @@ fn main() {
// Render the canvas to screen.
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
scene.build_and_render(&mut renderer, RenderOptions::default());
scene.build_and_render(&mut renderer, BuildOptions::default());
window.gl_swap_window();
// Wait for a keypress.

View File

@ -13,11 +13,11 @@ use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::color::{ColorF, ColorU};
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
@ -67,7 +67,8 @@ fn main() {
// Create our renderers.
let renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(drawable_size));
DestFramebuffer::full_window(drawable_size),
RendererOptions { background_color: Some(ColorF::white()) });
let mut moire_renderer = MoireRenderer::new(renderer, window_size, drawable_size);
// Enter main render loop.
@ -124,10 +125,7 @@ impl MoireRenderer {
Vector2F::new(1.0, sin_time).scale(cos_time * INNER_RADIUS);
// Clear to background color.
self.renderer.device.clear(&ClearParams {
color: Some(background_color),
..ClearParams::default()
});
self.renderer.set_options(RendererOptions { background_color: Some(background_color) });
// Make a canvas.
let mut canvas = CanvasRenderingContext2D::new(self.font_context.clone(),
@ -142,7 +140,7 @@ impl MoireRenderer {
// Build and render scene.
self.scene.replace_scene(canvas.into_scene());
self.scene.build_and_render(&mut self.renderer, RenderOptions::default());
self.scene.build_and_render(&mut self.renderer, BuildOptions::default());
self.frame += 1;
}

View File

@ -13,11 +13,11 @@ use pathfinder_geometry::basic::vector::{Vector2F, Vector2I};
use pathfinder_geometry::color::ColorF;
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
@ -47,10 +47,8 @@ fn main() {
// Create a Pathfinder renderer.
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(window_size));
// Clear to white.
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
DestFramebuffer::full_window(window_size),
RendererOptions { background_color: Some(ColorF::white()) });
// Make a canvas. We're going to draw some text.
let mut canvas = CanvasRenderingContext2D::new(CanvasFontContext::new(), window_size.to_f32());
@ -63,7 +61,7 @@ fn main() {
// Render the canvas to screen.
let scene = SceneProxy::from_scene(canvas.into_scene(), RayonExecutor);
scene.build_and_render(&mut renderer, RenderOptions::default());
scene.build_and_render(&mut renderer, BuildOptions::default());
window.gl_swap_window();
// Wait for a keypress.

View File

@ -75,13 +75,18 @@ impl Debug for ColorU {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
pub struct ColorF(pub F32x4);
impl ColorF {
#[inline]
pub fn new(r: f32, g: f32, b: f32, a: f32) -> ColorF {
ColorF(F32x4::new(r, g, b, a))
}
#[inline]
pub fn transparent_black() -> ColorF {
ColorF(F32x4::default())
ColorF::default()
}
#[inline]
@ -120,3 +125,16 @@ impl ColorF {
self.0[3]
}
}
impl Debug for ColorF {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
write!(
formatter,
"rgba({}, {}, {}, {})",
self.r() * 255.0,
self.g() * 255.0,
self.b() * 255.0,
self.a()
)
}
}

View File

@ -14,13 +14,13 @@
extern crate log;
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_geometry::basic::rect::RectI;
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams};
use pathfinder_gpu::{DepthFunc, Device, Primitive, RenderState, ShaderKind, StencilFunc};
use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_gpu::{RenderTarget, BlendState, BufferData, BufferTarget, BufferUploadMode};
use pathfinder_gpu::{ClearOps, DepthFunc, Device, Primitive, RenderOptions, RenderState};
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureFormat, UniformData};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_simd::default::F32x4;
use std::ffi::CString;
use std::mem;
@ -60,10 +60,32 @@ impl GLDevice {
}
}
fn set_render_state(&self, render_state: &RenderState) {
fn set_render_state(&self, render_state: &RenderState<GLDevice>) {
self.bind_render_target(render_state.target);
unsafe {
let (origin, size) = (render_state.viewport.origin(), render_state.viewport.size());
gl::Viewport(origin.x(), origin.y(), size.x(), size.y());
}
if render_state.options.clear_ops.has_ops() {
self.clear(&render_state.options.clear_ops);
}
self.use_program(render_state.program);
self.bind_vertex_array(render_state.vertex_array);
for (texture_unit, texture) in render_state.textures.iter().enumerate() {
self.bind_texture(texture, texture_unit as u32);
}
render_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data));
self.set_render_options(&render_state.options);
}
fn set_render_options(&self, render_options: &RenderOptions) {
unsafe {
// Set blend.
match render_state.blend {
match render_options.blend {
BlendState::Off => {
gl::Disable(gl::BLEND); ck();
}
@ -91,7 +113,7 @@ impl GLDevice {
}
// Set depth.
match render_state.depth {
match render_options.depth {
None => {
gl::Disable(gl::DEPTH_TEST); ck();
}
@ -103,7 +125,7 @@ impl GLDevice {
}
// Set stencil.
match render_state.stencil {
match render_options.stencil {
None => {
gl::Disable(gl::STENCIL_TEST); ck();
}
@ -123,14 +145,50 @@ impl GLDevice {
}
// Set color mask.
let color_mask = render_state.color_mask as GLboolean;
let color_mask = render_options.color_mask as GLboolean;
gl::ColorMask(color_mask, color_mask, color_mask, color_mask); ck();
}
}
fn reset_render_state(&self, render_state: &RenderState) {
fn set_uniform(&self, uniform: &GLUniform, data: &UniformData) {
unsafe {
match render_state.blend {
match *data {
UniformData::Int(value) => {
gl::Uniform1i(uniform.location, value); ck();
}
UniformData::Mat4(data) => {
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
let data_ptr: *const F32x4 = data.as_ptr();
gl::UniformMatrix4fv(uniform.location,
1,
gl::FALSE,
data_ptr as *const GLfloat);
}
UniformData::Vec2(data) => {
gl::Uniform2f(uniform.location, data.x(), data.y()); ck();
}
UniformData::Vec4(data) => {
gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); ck();
}
UniformData::TextureUnit(unit) => {
gl::Uniform1i(uniform.location, unit as GLint); ck();
}
}
}
}
fn reset_render_state(&self, render_state: &RenderState<GLDevice>) {
self.reset_render_options(&render_state.options);
for texture_unit in 0..(render_state.textures.len() as u32) {
self.unbind_texture(texture_unit);
}
self.unuse_program();
self.unbind_vertex_array();
}
fn reset_render_options(&self, render_options: &RenderOptions) {
unsafe {
match render_options.blend {
BlendState::Off => {}
BlendState::RGBOneAlphaOneMinusSrcAlpha |
BlendState::RGBOneAlphaOne |
@ -139,11 +197,11 @@ impl GLDevice {
}
}
if render_state.depth.is_some() {
if render_options.depth.is_some() {
gl::Disable(gl::DEPTH_TEST); ck();
}
if render_state.stencil.is_some() {
if render_options.stencil.is_some() {
gl::StencilMask(!0); ck();
gl::Disable(gl::STENCIL_TEST); ck();
}
@ -165,37 +223,18 @@ impl Device for GLDevice {
type VertexAttr = GLVertexAttr;
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> GLTexture {
let (gl_internal_format, gl_format, gl_type);
match format {
TextureFormat::R8 => {
gl_internal_format = gl::R8 as GLint;
gl_format = gl::RED;
gl_type = gl::UNSIGNED_BYTE;
}
TextureFormat::R16F => {
gl_internal_format = gl::R16F as GLint;
gl_format = gl::RED;
gl_type = gl::HALF_FLOAT;
}
TextureFormat::RGBA8 => {
gl_internal_format = gl::RGBA as GLint;
gl_format = gl::RGBA;
gl_type = gl::UNSIGNED_BYTE;
}
}
let mut texture = GLTexture { gl_texture: 0, size };
let mut texture = GLTexture { gl_texture: 0, size, format };
unsafe {
gl::GenTextures(1, &mut texture.gl_texture); ck();
self.bind_texture(&texture, 0);
gl::TexImage2D(gl::TEXTURE_2D,
0,
gl_internal_format,
format.gl_internal_format(),
size.x() as GLsizei,
size.y() as GLsizei,
0,
gl_format,
gl_type,
format.gl_format(),
format.gl_type(),
ptr::null()); ck();
}
@ -206,7 +245,7 @@ impl Device for GLDevice {
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> GLTexture {
assert!(data.len() >= size.x() as usize * size.y() as usize);
let mut texture = GLTexture { gl_texture: 0, size };
let mut texture = GLTexture { gl_texture: 0, size, format: TextureFormat::R8 };
unsafe {
gl::GenTextures(1, &mut texture.gl_texture); ck();
self.bind_texture(&texture, 0);
@ -324,13 +363,14 @@ impl Device for GLDevice {
GLUniform { location }
}
fn use_program(&self, program: &Self::Program) {
unsafe {
gl::UseProgram(program.gl_program); ck();
}
}
fn configure_vertex_attr(&self,
vertex_array: &GLVertexArray,
attr: &GLVertexAttr,
descriptor: &VertexAttrDescriptor) {
debug_assert_ne!(descriptor.stride, 0);
self.bind_vertex_array(vertex_array);
fn configure_vertex_attr(&self, attr: &GLVertexAttr, descriptor: &VertexAttrDescriptor) {
unsafe {
let attr_type = descriptor.attr_type.to_gl_type();
match descriptor.class {
@ -359,41 +399,8 @@ impl Device for GLDevice {
gl::VertexAttribDivisor(attr.attr, descriptor.divisor); ck();
gl::EnableVertexAttribArray(attr.attr); ck();
}
}
fn set_uniform(&self, uniform: &Self::Uniform, data: UniformData) {
unsafe {
match data {
UniformData::Int(value) => {
gl::Uniform1i(uniform.location, value); ck();
}
UniformData::Mat2(data) => {
assert_eq!(mem::size_of::<F32x4>(), 4 * 4);
let data_ptr: *const F32x4 = &data;
gl::UniformMatrix2fv(uniform.location,
1,
gl::FALSE,
data_ptr as *const GLfloat);
}
UniformData::Mat4(data) => {
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
let data_ptr: *const F32x4 = data.as_ptr();
gl::UniformMatrix4fv(uniform.location,
1,
gl::FALSE,
data_ptr as *const GLfloat);
}
UniformData::Vec2(data) => {
gl::Uniform2f(uniform.location, data.x(), data.y()); ck();
}
UniformData::Vec4(data) => {
gl::Uniform4f(uniform.location, data.x(), data.y(), data.z(), data.w()); ck();
}
UniformData::TextureUnit(unit) => {
gl::Uniform1i(uniform.location, unit as GLint); ck();
}
}
}
self.unbind_vertex_array();
}
fn create_framebuffer(&self, texture: GLTexture) -> GLFramebuffer {
@ -470,77 +477,67 @@ impl Device for GLDevice {
self.set_texture_parameters(texture);
}
fn read_pixels_from_default_framebuffer(&self, size: Vector2I) -> Vec<u8> {
let mut pixels = vec![0; size.x() as usize * size.y() as usize * 4];
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
gl::ReadPixels(0,
0,
size.x() as GLsizei,
size.y() as GLsizei,
gl::RGBA,
gl::UNSIGNED_BYTE,
pixels.as_mut_ptr() as *mut GLvoid); ck();
}
fn read_pixels(&self, render_target: &RenderTarget<GLDevice>, viewport: RectI) -> TextureData {
let (origin, size) = (viewport.origin(), viewport.size());
let format = self.render_target_format(render_target);
self.bind_render_target(render_target);
// Flip right-side-up.
let stride = size.x() as usize * 4;
for y in 0..(size.y() as usize / 2) {
let (index_a, index_b) = (y * stride, (size.y() as usize - y - 1) * stride);
for offset in 0..stride {
pixels.swap(index_a + offset, index_b + offset);
match format {
TextureFormat::R8 | TextureFormat::RGBA8 => {
let channels = format.channels();
let mut pixels = vec![0; size.x() as usize * size.y() as usize * channels];
unsafe {
gl::ReadPixels(origin.x(),
origin.y(),
size.x() as GLsizei,
size.y() as GLsizei,
format.gl_format(),
format.gl_type(),
pixels.as_mut_ptr() as *mut GLvoid); ck();
}
flip_y(&mut pixels, size, channels);
TextureData::U8(pixels)
}
}
pixels
}
fn clear(&self, params: &ClearParams) {
unsafe {
if let Some(rect) = params.rect {
let (origin, size) = (rect.origin(), rect.size());
gl::Scissor(origin.x(), origin.y(), size.x(), size.y()); ck();
gl::Enable(gl::SCISSOR_TEST); ck();
}
let mut flags = 0;
if let Some(color) = params.color {
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck();
flags |= gl::COLOR_BUFFER_BIT;
}
if let Some(depth) = params.depth {
gl::DepthMask(gl::TRUE); ck();
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
flags |= gl::DEPTH_BUFFER_BIT;
}
if let Some(stencil) = params.stencil {
gl::StencilMask(!0); ck();
gl::ClearStencil(stencil as GLint); ck();
flags |= gl::STENCIL_BUFFER_BIT;
}
if flags != 0 {
gl::Clear(flags); ck();
}
if params.rect.is_some() {
gl::Disable(gl::SCISSOR_TEST); ck();
TextureFormat::R16F => {
let mut pixels = vec![0; size.x() as usize * size.y() as usize];
unsafe {
gl::ReadPixels(origin.x(),
origin.y(),
size.x() as GLsizei,
size.y() as GLsizei,
format.gl_format(),
format.gl_type(),
pixels.as_mut_ptr() as *mut GLvoid); ck();
}
flip_y(&mut pixels, size, 1);
TextureData::U16(pixels)
}
}
}
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState) {
fn begin_commands(&self) {
// TODO(pcwalton): Add some checks in debug mode to make sure render commands are bracketed
// by these?
}
fn end_commands(&self) {
unsafe { gl::Flush(); }
}
fn draw_arrays(&self, index_count: u32, render_state: &RenderState<Self>) {
self.set_render_state(render_state);
unsafe {
gl::DrawArrays(primitive.to_gl_primitive(), 0, index_count as GLsizei); ck();
gl::DrawArrays(render_state.primitive.to_gl_primitive(),
0,
index_count as GLsizei); ck();
}
self.reset_render_state(render_state);
}
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState) {
fn draw_elements(&self, index_count: u32, render_state: &RenderState<Self>) {
self.set_render_state(render_state);
unsafe {
gl::DrawElements(primitive.to_gl_primitive(),
gl::DrawElements(render_state.primitive.to_gl_primitive(),
index_count as GLsizei,
gl::UNSIGNED_INT,
ptr::null()); ck();
@ -549,13 +546,12 @@ impl Device for GLDevice {
}
fn draw_elements_instanced(&self,
primitive: Primitive,
index_count: u32,
instance_count: u32,
render_state: &RenderState) {
render_state: &RenderState<Self>) {
self.set_render_state(render_state);
unsafe {
gl::DrawElementsInstanced(primitive.to_gl_primitive(),
gl::DrawElementsInstanced(render_state.primitive.to_gl_primitive(),
index_count as GLsizei,
gl::UNSIGNED_INT,
ptr::null(),
@ -588,66 +584,102 @@ impl Device for GLDevice {
}
#[inline]
fn timer_query_is_available(&self, query: &Self::TimerQuery) -> bool {
fn get_timer_query(&self, query: &Self::TimerQuery) -> Option<Duration> {
unsafe {
let mut result = 0;
gl::GetQueryObjectiv(query.gl_query, gl::QUERY_RESULT_AVAILABLE, &mut result); ck();
result != gl::FALSE as GLint
}
}
#[inline]
fn get_timer_query(&self, query: &Self::TimerQuery) -> Duration {
unsafe {
if result == gl::FALSE as GLint {
return None;
}
let mut result = 0;
gl::GetQueryObjectui64v(query.gl_query, gl::QUERY_RESULT, &mut result); ck();
Duration::from_nanos(result)
Some(Duration::from_nanos(result))
}
}
#[inline]
fn bind_buffer(&self, vertex_array: &GLVertexArray, buffer: &GLBuffer, target: BufferTarget) {
self.bind_vertex_array(vertex_array);
unsafe {
gl::BindBuffer(target.to_gl_target(), buffer.gl_buffer); ck();
}
self.unbind_vertex_array();
}
#[inline]
fn create_shader(
&self,
resources: &dyn ResourceLoader,
name: &str,
kind: ShaderKind,
) -> Self::Shader {
let suffix = match kind {
ShaderKind::Vertex => 'v',
ShaderKind::Fragment => 'f',
};
let path = format!("shaders/gl3/{}.{}s.glsl", name, suffix);
self.create_shader_from_source(name, &resources.slurp(&path).unwrap(), kind)
}
}
impl GLDevice {
fn bind_render_target(&self, attachment: &RenderTarget<GLDevice>) {
match *attachment {
RenderTarget::Default => self.bind_default_framebuffer(),
RenderTarget::Framebuffer(framebuffer) => self.bind_framebuffer(framebuffer),
}
}
fn bind_vertex_array(&self, vertex_array: &GLVertexArray) {
unsafe {
gl::BindVertexArray(vertex_array.gl_vertex_array); ck();
}
}
#[inline]
fn bind_buffer(&self, buffer: &GLBuffer, target: BufferTarget) {
fn unbind_vertex_array(&self) {
unsafe {
gl::BindBuffer(target.to_gl_target(), buffer.gl_buffer); ck();
gl::BindVertexArray(0); ck();
}
}
#[inline]
fn bind_default_framebuffer(&self, viewport: RectI) {
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
gl::Viewport(viewport.origin().x(),
viewport.origin().y(),
viewport.size().x(),
viewport.size().y()); ck();
}
}
#[inline]
fn bind_framebuffer(&self, framebuffer: &GLFramebuffer) {
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); ck();
gl::Viewport(0, 0, framebuffer.texture.size.x(), framebuffer.texture.size.y()); ck();
}
}
#[inline]
fn bind_texture(&self, texture: &GLTexture, unit: u32) {
unsafe {
gl::ActiveTexture(gl::TEXTURE0 + unit); ck();
gl::BindTexture(gl::TEXTURE_2D, texture.gl_texture); ck();
}
}
}
impl GLDevice {
fn unbind_texture(&self, unit: u32) {
unsafe {
gl::ActiveTexture(gl::TEXTURE0 + unit); ck();
gl::BindTexture(gl::TEXTURE_2D, 0); ck();
}
}
fn use_program(&self, program: &GLProgram) {
unsafe {
gl::UseProgram(program.gl_program); ck();
}
}
fn unuse_program(&self) {
unsafe {
gl::UseProgram(0); ck();
}
}
fn bind_default_framebuffer(&self) {
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, self.default_framebuffer); ck();
}
}
fn bind_framebuffer(&self, framebuffer: &GLFramebuffer) {
unsafe {
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.gl_framebuffer); ck();
}
}
fn preprocess(&self, output: &mut Vec<u8>, source: &[u8], version: &str) {
let mut index = 0;
while index < source.len() {
@ -669,6 +701,39 @@ impl GLDevice {
}
}
}
fn clear(&self, ops: &ClearOps) {
unsafe {
let mut flags = 0;
if let Some(color) = ops.color {
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck();
flags |= gl::COLOR_BUFFER_BIT;
}
if let Some(depth) = ops.depth {
gl::DepthMask(gl::TRUE); ck();
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
flags |= gl::DEPTH_BUFFER_BIT;
}
if let Some(stencil) = ops.stencil {
gl::StencilMask(!0); ck();
gl::ClearStencil(stencil as GLint); ck();
flags |= gl::STENCIL_BUFFER_BIT;
}
if flags != 0 {
gl::Clear(flags); ck();
}
}
}
fn render_target_format(&self, render_target: &RenderTarget<GLDevice>) -> TextureFormat {
match *render_target {
RenderTarget::Default => TextureFormat::RGBA8,
RenderTarget::Framebuffer(ref framebuffer) => {
self.framebuffer_texture(framebuffer).format
}
}
}
}
pub struct GLVertexArray {
@ -753,7 +818,7 @@ impl Drop for GLBuffer {
#[derive(Debug)]
pub struct GLUniform {
pub location: GLint,
location: GLint,
}
pub struct GLProgram {
@ -787,6 +852,7 @@ impl Drop for GLShader {
pub struct GLTexture {
gl_texture: GLuint,
pub size: Vector2I,
pub format: TextureFormat,
}
pub struct GLTimerQuery {
@ -863,7 +929,36 @@ impl StencilFuncExt for StencilFunc {
match self {
StencilFunc::Always => gl::ALWAYS,
StencilFunc::Equal => gl::EQUAL,
StencilFunc::NotEqual => gl::NOTEQUAL,
}
}
}
trait TextureFormatExt {
fn gl_internal_format(self) -> GLint;
fn gl_format(self) -> GLuint;
fn gl_type(self) -> GLuint;
}
impl TextureFormatExt for TextureFormat {
fn gl_internal_format(self) -> GLint {
match self {
TextureFormat::R8 => gl::R8 as GLint,
TextureFormat::R16F => gl::R16F as GLint,
TextureFormat::RGBA8 => gl::RGBA as GLint,
}
}
fn gl_format(self) -> GLuint {
match self {
TextureFormat::R8 | TextureFormat::R16F => gl::RED,
TextureFormat::RGBA8 => gl::RGBA,
}
}
fn gl_type(self) -> GLuint {
match self {
TextureFormat::R8 | TextureFormat::RGBA8 => gl::UNSIGNED_BYTE,
TextureFormat::R16F => gl::HALF_FLOAT,
}
}
}
@ -929,4 +1024,15 @@ fn ck() {
#[cfg(not(debug_assertions))]
fn ck() {}
// Shader preprocessing
// Utilities
// Flips a buffer of image data upside-down.
fn flip_y<T>(pixels: &mut [T], size: Vector2I, channels: usize) {
let stride = size.x() as usize * channels;
for y in 0..(size.y() as usize / 2) {
let (index_a, index_b) = (y * stride, (size.y() as usize - y - 1) * stride);
for offset in 0..stride {
pixels.swap(index_a + offset, index_b + offset);
}
}
}

View File

@ -21,7 +21,7 @@ use std::time::Duration;
pub mod resources;
pub trait Device {
pub trait Device: Sized {
type Buffer;
type Framebuffer;
type Program;
@ -34,6 +34,8 @@ pub trait Device {
fn create_texture(&self, format: TextureFormat, size: Vector2I) -> Self::Texture;
fn create_texture_from_data(&self, size: Vector2I, data: &[u8]) -> Self::Texture;
fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
-> Self::Shader;
fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind)
-> Self::Shader;
fn create_vertex_array(&self) -> Self::VertexArray;
@ -46,9 +48,14 @@ pub trait Device {
) -> Self::Program;
fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Option<Self::VertexAttr>;
fn get_uniform(&self, program: &Self::Program, name: &str) -> Self::Uniform;
fn use_program(&self, program: &Self::Program);
fn configure_vertex_attr(&self, attr: &Self::VertexAttr, descriptor: &VertexAttrDescriptor);
fn set_uniform(&self, uniform: &Self::Uniform, data: UniformData);
fn bind_buffer(&self,
vertex_array: &Self::VertexArray,
buffer: &Self::Buffer,
target: BufferTarget);
fn configure_vertex_attr(&self,
vertex_array: &Self::VertexArray,
attr: &Self::VertexAttr,
descriptor: &VertexAttrDescriptor);
fn create_framebuffer(&self, texture: Self::Texture) -> Self::Framebuffer;
fn create_buffer(&self) -> Self::Buffer;
fn allocate_buffer<T>(
@ -61,27 +68,19 @@ pub trait Device {
fn framebuffer_texture<'f>(&self, framebuffer: &'f Self::Framebuffer) -> &'f Self::Texture;
fn texture_size(&self, texture: &Self::Texture) -> Vector2I;
fn upload_to_texture(&self, texture: &Self::Texture, size: Vector2I, data: &[u8]);
fn read_pixels_from_default_framebuffer(&self, size: Vector2I) -> Vec<u8>;
fn clear(&self, params: &ClearParams);
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
fn read_pixels(&self, target: &RenderTarget<Self>, viewport: RectI) -> TextureData;
fn begin_commands(&self);
fn end_commands(&self);
fn draw_arrays(&self, index_count: u32, render_state: &RenderState<Self>);
fn draw_elements(&self, index_count: u32, render_state: &RenderState<Self>);
fn draw_elements_instanced(&self,
primitive: Primitive,
index_count: u32,
instance_count: u32,
render_state: &RenderState);
render_state: &RenderState<Self>);
fn create_timer_query(&self) -> Self::TimerQuery;
fn begin_timer_query(&self, query: &Self::TimerQuery);
fn end_timer_query(&self, query: &Self::TimerQuery);
fn timer_query_is_available(&self, query: &Self::TimerQuery) -> bool;
fn get_timer_query(&self, query: &Self::TimerQuery) -> Duration;
// TODO(pcwalton): Go bindless...
fn bind_vertex_array(&self, vertex_array: &Self::VertexArray);
fn bind_buffer(&self, buffer: &Self::Buffer, target: BufferTarget);
fn bind_default_framebuffer(&self, viewport: RectI);
fn bind_framebuffer(&self, framebuffer: &Self::Framebuffer);
fn bind_texture(&self, texture: &Self::Texture, unit: u32);
fn get_timer_query(&self, query: &Self::TimerQuery) -> Option<Duration>;
fn create_texture_from_png(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Texture {
let data = resources.slurp(&format!("textures/{}.png", name)).unwrap();
@ -92,20 +91,6 @@ pub trait Device {
self.create_texture_from_data(size, &image)
}
fn create_shader(
&self,
resources: &dyn ResourceLoader,
name: &str,
kind: ShaderKind,
) -> Self::Shader {
let suffix = match kind {
ShaderKind::Vertex => 'v',
ShaderKind::Fragment => 'f',
};
let source = resources.slurp(&format!("shaders/gl3/{}.{}s.glsl", name, suffix)).unwrap();
self.create_shader_from_source(name, &source, kind)
}
fn create_program_from_shader_names(
&self,
resources: &dyn ResourceLoader,
@ -124,7 +109,7 @@ pub trait Device {
}
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TextureFormat {
R8,
R16F,
@ -167,7 +152,6 @@ pub enum ShaderKind {
#[derive(Clone, Copy)]
pub enum UniformData {
Int(i32),
Mat2(F32x4),
Mat4([F32x4; 4]),
Vec2(F32x4),
Vec4(F32x4),
@ -180,23 +164,41 @@ pub enum Primitive {
Lines,
}
#[derive(Clone, Copy, Default)]
pub struct ClearParams {
#[derive(Clone)]
pub struct RenderState<'a, D> where D: Device {
pub target: &'a RenderTarget<'a, D>,
pub program: &'a D::Program,
pub vertex_array: &'a D::VertexArray,
pub primitive: Primitive,
pub uniforms: &'a [(&'a D::Uniform, UniformData)],
pub textures: &'a [&'a D::Texture],
pub viewport: RectI,
pub options: RenderOptions,
}
#[derive(Clone, Debug)]
pub struct RenderOptions {
pub blend: BlendState,
pub depth: Option<DepthState>,
pub stencil: Option<StencilState>,
pub clear_ops: ClearOps,
pub color_mask: bool,
}
#[derive(Clone, Copy, Debug, Default)]
pub struct ClearOps {
pub color: Option<ColorF>,
pub rect: Option<RectI>,
pub depth: Option<f32>,
pub stencil: Option<u8>,
}
#[derive(Clone, Debug)]
pub struct RenderState {
pub blend: BlendState,
pub depth: Option<DepthState>,
pub stencil: Option<StencilState>,
pub color_mask: bool,
#[derive(Clone, Copy, Debug)]
pub enum RenderTarget<'a, D> where D: Device {
Default,
Framebuffer(&'a D::Framebuffer),
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BlendState {
Off,
RGBOneAlphaOne,
@ -228,16 +230,16 @@ pub struct StencilState {
pub enum StencilFunc {
Always,
Equal,
NotEqual,
}
impl Default for RenderState {
impl Default for RenderOptions {
#[inline]
fn default() -> RenderState {
RenderState {
fn default() -> RenderOptions {
RenderOptions {
blend: BlendState::default(),
depth: None,
stencil: None,
clear_ops: ClearOps::default(),
color_mask: true,
}
}
@ -276,6 +278,12 @@ impl Default for StencilFunc {
}
}
#[derive(Clone, Debug)]
pub enum TextureData {
U8(Vec<u8>),
U16(Vec<u16>),
}
impl UniformData {
#[inline]
pub fn from_transform_3d(transform: &Transform3DF) -> UniformData {
@ -291,6 +299,7 @@ pub struct VertexAttrDescriptor {
pub stride: usize,
pub offset: usize,
pub divisor: u32,
pub buffer_index: u32,
}
#[derive(Clone, Copy, Debug, PartialEq)]
@ -299,3 +308,20 @@ pub enum VertexAttrClass {
FloatNorm,
Int,
}
impl TextureFormat {
#[inline]
pub fn channels(self) -> usize {
match self {
TextureFormat::R8 | TextureFormat::R16F => 1,
TextureFormat::RGBA8 => 4,
}
}
}
impl ClearOps {
#[inline]
pub fn has_ops(&self) -> bool {
self.color.is_some() || self.depth.is_some() || self.stencil.is_some()
}
}

24
metal/Cargo.toml Normal file
View File

@ -0,0 +1,24 @@
[package]
name = "pathfinder_metal"
version = "0.1.0"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018"
[dependencies]
bitflags = "1.0"
byteorder = "1.3"
block = "0.1"
cocoa = "0.18"
core-foundation = "0.6"
foreign-types = "0.3"
metal = "0.14"
objc = "0.2"
[dependencies.pathfinder_geometry]
path = "../geometry"
[dependencies.pathfinder_gpu]
path = "../gpu"
[dependencies.pathfinder_simd]
path = "../simd"

1484
metal/src/lib.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ edition = "2018"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
[dependencies]
bitflags = "1.0"
byteorder = "1.2"
fixedbitset = "0.1"
hashbrown = "0.1"

View File

@ -12,7 +12,7 @@
use crate::concurrent::executor::Executor;
use crate::gpu_data::{AlphaTileBatchPrimitive, BuiltObject, FillBatchPrimitive, RenderCommand};
use crate::options::{PreparedRenderOptions, RenderCommandListener};
use crate::options::{PreparedBuildOptions, RenderCommandListener};
use crate::scene::Scene;
use crate::tile_map::DenseTileMap;
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH, Tiler};
@ -28,7 +28,7 @@ use std::u16;
pub(crate) struct SceneBuilder<'a> {
scene: &'a Scene,
built_options: &'a PreparedRenderOptions,
built_options: &'a PreparedBuildOptions,
pub(crate) next_alpha_tile_index: AtomicUsize,
pub(crate) z_buffer: ZBuffer,
@ -38,7 +38,7 @@ pub(crate) struct SceneBuilder<'a> {
impl<'a> SceneBuilder<'a> {
pub(crate) fn new(
scene: &'a Scene,
built_options: &'a PreparedRenderOptions,
built_options: &'a PreparedBuildOptions,
listener: Box<dyn RenderCommandListener>,
) -> SceneBuilder<'a> {
let effective_view_box = scene.effective_view_box(built_options);
@ -76,7 +76,7 @@ impl<'a> SceneBuilder<'a> {
&self,
path_index: usize,
view_box: RectF,
built_options: &PreparedRenderOptions,
built_options: &PreparedBuildOptions,
scene: &Scene,
) -> Vec<AlphaTileBatchPrimitive> {
let path_object = &scene.paths[path_index];

View File

@ -22,7 +22,7 @@
use crate::concurrent::executor::Executor;
use crate::gpu::renderer::Renderer;
use crate::gpu_data::RenderCommand;
use crate::options::{RenderCommandListener, RenderOptions};
use crate::options::{BuildOptions, RenderCommandListener};
use crate::scene::Scene;
use pathfinder_geometry::basic::rect::RectF;
use pathfinder_gpu::Device;
@ -59,15 +59,15 @@ impl SceneProxy {
#[inline]
pub fn build_with_listener(&self,
options: RenderOptions,
options: BuildOptions,
listener: Box<dyn RenderCommandListener>) {
self.sender.send(MainToWorkerMsg::Build(options, listener)).unwrap();
}
#[inline]
pub fn build_with_stream(&self, options: RenderOptions) -> RenderCommandStream {
pub fn build_with_stream(&self, options: BuildOptions) -> RenderCommandStream {
let (sender, receiver) = mpsc::sync_channel(MAX_MESSAGES_IN_FLIGHT);
let listener = Box::new(move |command| sender.send(command).unwrap());
let listener = Box::new(move |command| drop(sender.send(command)));
self.build_with_listener(options, listener);
RenderCommandStream::new(receiver)
}
@ -81,11 +81,11 @@ impl SceneProxy {
/// renderer.render_command(&command)
/// }
#[inline]
pub fn build_and_render<D>(&self, renderer: &mut Renderer<D>, options: RenderOptions)
pub fn build_and_render<D>(&self, renderer: &mut Renderer<D>, build_options: BuildOptions)
where D: Device {
renderer.begin_scene();
for command in self.build_with_stream(options) {
renderer.render_command(&command)
for command in self.build_with_stream(build_options) {
renderer.render_command(&command);
}
renderer.end_scene();
}
@ -118,7 +118,7 @@ fn scene_thread<E>(mut scene: Scene,
enum MainToWorkerMsg {
ReplaceScene(Scene),
SetViewBox(RectF),
Build(RenderOptions, Box<dyn RenderCommandListener>),
Build(BuildOptions, Box<dyn RenderCommandListener>),
GetSVG(Sender<Vec<u8>>),
}

View File

@ -11,4 +11,5 @@
//! The GPU renderer for Pathfinder 3.
pub mod debug;
pub mod options;
pub mod renderer;

View File

@ -0,0 +1,60 @@
// pathfinder/renderer/src/gpu/options.rs
//
// Copyright © 2019 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 pathfinder_geometry::basic::rect::RectI;
use pathfinder_geometry::basic::vector::Vector2I;
use pathfinder_geometry::color::ColorF;
use pathfinder_gpu::Device;
/// Options that influence rendering.
#[derive(Default)]
pub struct RendererOptions {
pub background_color: Option<ColorF>,
}
#[derive(Clone)]
pub enum DestFramebuffer<D>
where
D: Device,
{
Default {
viewport: RectI,
window_size: Vector2I,
},
Other(D::Framebuffer),
}
impl<D> Default for DestFramebuffer<D> where D: Device {
#[inline]
fn default() -> DestFramebuffer<D> {
DestFramebuffer::Default { viewport: RectI::default(), window_size: Vector2I::default() }
}
}
impl<D> DestFramebuffer<D>
where
D: Device,
{
#[inline]
pub fn full_window(window_size: Vector2I) -> DestFramebuffer<D> {
let viewport = RectI::new(Vector2I::default(), window_size);
DestFramebuffer::Default { viewport, window_size }
}
#[inline]
pub fn window_size(&self, device: &D) -> Vector2I {
match *self {
DestFramebuffer::Default { window_size, .. } => window_size,
DestFramebuffer::Other(ref framebuffer) => {
device.texture_size(device.framebuffer_texture(framebuffer))
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -75,6 +75,7 @@ pub struct SolidTileBatchPrimitive {
pub origin_u: u16,
pub origin_v: u16,
pub object_index: u16,
pub pad: u16,
}
#[derive(Clone, Copy, Debug, Default)]

View File

@ -10,6 +10,8 @@
//! The CPU portion of Pathfinder's renderer.
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate log;

View File

@ -11,10 +11,10 @@
//! Options that control how rendering is to be performed.
use crate::gpu_data::RenderCommand;
use pathfinder_geometry::basic::vector::{Vector2F, Vector4F};
use pathfinder_geometry::basic::rect::RectF;
use pathfinder_geometry::basic::transform2d::Transform2DF;
use pathfinder_geometry::basic::transform3d::Perspective;
use pathfinder_geometry::basic::vector::{Vector2F, Vector4F};
use pathfinder_geometry::clip::PolygonClipper3D;
pub trait RenderCommandListener: Send + Sync {
@ -31,16 +31,17 @@ where
}
}
/// Options that influence scene building.
#[derive(Clone, Default)]
pub struct RenderOptions {
pub struct BuildOptions {
pub transform: RenderTransform,
pub dilation: Vector2F,
pub subpixel_aa_enabled: bool,
}
impl RenderOptions {
pub(crate) fn prepare(self, bounds: RectF) -> PreparedRenderOptions {
PreparedRenderOptions {
impl BuildOptions {
pub(crate) fn prepare(self, bounds: RectF) -> PreparedBuildOptions {
PreparedBuildOptions {
transform: self.transform.prepare(bounds),
dilation: self.dilation,
subpixel_aa_enabled: self.subpixel_aa_enabled,
@ -119,13 +120,13 @@ impl RenderTransform {
}
}
pub(crate) struct PreparedRenderOptions {
pub(crate) struct PreparedBuildOptions {
pub(crate) transform: PreparedRenderTransform,
pub(crate) dilation: Vector2F,
pub(crate) subpixel_aa_enabled: bool,
}
impl PreparedRenderOptions {
impl PreparedBuildOptions {
#[inline]
pub(crate) fn bounding_quad(&self) -> BoundingQuad {
match self.transform {

View File

@ -12,8 +12,8 @@
use crate::builder::SceneBuilder;
use crate::concurrent::executor::Executor;
use crate::options::{PreparedRenderOptions, PreparedRenderTransform};
use crate::options::{RenderCommandListener, RenderOptions};
use crate::options::{BuildOptions, PreparedBuildOptions};
use crate::options::{PreparedRenderTransform, RenderCommandListener};
use crate::paint::{Paint, PaintId};
use hashbrown::HashMap;
use pathfinder_geometry::basic::vector::Vector2F;
@ -89,7 +89,7 @@ impl Scene {
pub(crate) fn apply_render_options(
&self,
original_outline: &Outline,
options: &PreparedRenderOptions,
options: &PreparedBuildOptions,
) -> Outline {
let effective_view_box = self.effective_view_box(options);
@ -156,7 +156,7 @@ impl Scene {
}
#[inline]
pub(crate) fn effective_view_box(&self, render_options: &PreparedRenderOptions) -> RectF {
pub(crate) fn effective_view_box(&self, render_options: &PreparedBuildOptions) -> RectF {
if render_options.subpixel_aa_enabled {
self.view_box.scale_xy(Vector2F::new(3.0, 1.0))
} else {
@ -166,7 +166,7 @@ impl Scene {
#[inline]
pub fn build<E>(&self,
options: RenderOptions,
options: BuildOptions,
listener: Box<dyn RenderCommandListener>,
executor: &E)
where E: Executor {

View File

@ -91,6 +91,7 @@ impl SolidTileBatchPrimitive {
object_index: object_index,
origin_u: origin_uv.x() as u16,
origin_v: origin_uv.y() as u16,
pad: 0,
}
}
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -14,10 +16,10 @@ precision highp float;
uniform vec2 uFramebufferSize;
in vec2 aPosition;
in ivec2 aPosition;
void main(){
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -15,14 +17,14 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTextureSize;
in vec2 aPosition;
in vec2 aTexCoord;
in ivec2 aPosition;
in ivec2 aTexCoord;
out vec2 vTexCoord;
void main(){
vTexCoord = aTexCoord / uTextureSize;
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
vTexCoord = vec2(aTexCoord)/ uTextureSize;
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -15,12 +17,12 @@ precision highp float;
uniform mat4 uTransform;
uniform int uGridlineCount;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main(){
vTexCoord = aPosition * float(uGridlineCount);
gl_Position = uTransform * vec4(aPosition . x, 0.0, aPosition . y, 1.0);
vTexCoord = vec2(aPosition * uGridlineCount);
gl_Position = uTransform * vec4(ivec4(aPosition . x, 0, aPosition . y, 1));
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -15,7 +17,7 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in vec2 aTessCoord;
in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx;
@ -27,7 +29,7 @@ out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
uint tilesPerRow = uint(stencilTextureWidth / uTileSize . x);
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset)* uTileSize;
}
@ -38,11 +40,11 @@ void main(){
vec2 to = vec2(aToPx & 15u, aToPx >> 4u)+ aToSubpx;
vec2 position;
if(aTessCoord . x < 0.5)
if(aTessCoord . x == 0u)
position . x = floor(min(from . x, to . x));
else
position . x = ceil(max(from . x, to . x));
if(aTessCoord . y < 0.5)
if(aTessCoord . y == 0u)
position . y = floor(min(from . y, to . y));
else
position . y = uTileSize . y;
@ -50,6 +52,10 @@ void main(){
vFrom = from - position;
vTo = to - position;
gl_Position = vec4((tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
vec2 globalPosition =(tileOrigin + position)/ uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(globalPosition, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -12,12 +14,12 @@
precision highp float;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main(){
vTexCoord = aPosition;
gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);
vTexCoord = vec2(aPosition);
gl_Position = vec4(vec2(aPosition)* 2.0 - 1.0, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -14,12 +16,17 @@ precision highp float;
uniform mat4 uNewTransform;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main(){
vTexCoord = aPosition;
gl_Position = uNewTransform * vec4(aPosition, 0.0, 1.0);
vec2 position = vec2(aPosition);
vTexCoord = position;
gl_Position = uNewTransform * vec4(position, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -30,10 +32,10 @@ uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
in int aBackdrop;
in uint aTileIndex;
in int aTileIndex;
out vec2 vTexCoord;
out float vBackdrop;
@ -49,9 +51,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
void computeVaryings(){
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
vec2 pixelPosition =(origin + aTessCoord)* uTileSize + uViewBoxOrigin;
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize . x);
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -30,10 +32,10 @@ uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
in int aBackdrop;
in uint aTileIndex;
in int aTileIndex;
out vec2 vTexCoord;
out float vBackdrop;
@ -49,9 +51,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
void computeVaryings(){
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
vec2 pixelPosition =(origin + aTessCoord)* uTileSize + uViewBoxOrigin;
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize . x);
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -29,19 +31,18 @@ uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in vec2 aTileOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
out vec4 vColor;
vec4 getColor();
void computeVaryings(){
vec2 pixelPosition =(aTileOrigin + aTessCoord)* uTileSize + uViewBoxOrigin;
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
}

View File

@ -1,4 +1,6 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!
@ -29,19 +31,18 @@ uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in vec2 aTileOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
out vec4 vColor;
vec4 getColor();
void computeVaryings(){
vec2 pixelPosition =(aTileOrigin + aTessCoord)* uTileSize + uViewBoxOrigin;
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
}

View File

@ -1,17 +1,23 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4* uColor [[id(0)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
};
fragment main0_out main0(float4 uColor [[buffer(0)]])
fragment main0_out main0(constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.oFragColor = float4(uColor.xyz, 1.0) * uColor.w;
out.oFragColor = float4((*spvDescriptorSet0.uColor).xyz, 1.0) * (*spvDescriptorSet0.uColor).w;
return out;
}

View File

@ -1,8 +1,14 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uFramebufferSize [[id(0)]];
};
struct main0_out
{
float4 gl_Position [[position]];
@ -10,13 +16,13 @@ struct main0_out
struct main0_in
{
float2 aPosition [[attribute(0)]];
int2 aPosition [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], float2 uFramebufferSize [[buffer(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float2 position = ((in.aPosition / uFramebufferSize) * 2.0) - float2(1.0);
float2 position = ((float2(in.aPosition) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
out.gl_Position = float4(position.x, -position.y, 0.0, 1.0);
return out;
}

View File

@ -1,8 +1,16 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4* uColor [[id(0)]];
texture2d<float> uTexture [[id(1)]];
sampler uTextureSmplr [[id(2)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -13,11 +21,11 @@ struct main0_in
float2 vTexCoord [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], float4 uColor [[buffer(0)]], texture2d<float> uTexture [[texture(0)]], sampler uTextureSmplr [[sampler(0)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float alpha = uTexture.sample(uTextureSmplr, in.vTexCoord).x * uColor.w;
out.oFragColor = float4(uColor.xyz, 1.0) * alpha;
float alpha = spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, in.vTexCoord).x * (*spvDescriptorSet0.uColor).w;
out.oFragColor = float4((*spvDescriptorSet0.uColor).xyz, 1.0) * alpha;
return out;
}

View File

@ -1,8 +1,15 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTextureSize [[id(0)]];
constant float2* uFramebufferSize [[id(1)]];
};
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
@ -11,15 +18,15 @@ struct main0_out
struct main0_in
{
float2 aPosition [[attribute(0)]];
float2 aTexCoord [[attribute(1)]];
int2 aPosition [[attribute(0)]];
int2 aTexCoord [[attribute(1)]];
};
vertex main0_out main0(main0_in in [[stage_in]], float2 uTextureSize [[buffer(0)]], float2 uFramebufferSize [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.vTexCoord = in.aTexCoord / uTextureSize;
float2 position = ((in.aPosition / uFramebufferSize) * 2.0) - float2(1.0);
out.vTexCoord = float2(in.aTexCoord) / (*spvDescriptorSet0.uTextureSize);
float2 position = ((float2(in.aPosition) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
out.gl_Position = float4(position.x, -position.y, 0.0, 1.0);
return out;
}

View File

@ -1,8 +1,15 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4* uGridlineColor [[id(0)]];
constant float4* uGroundColor [[id(1)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -13,12 +20,12 @@ struct main0_in
float2 vTexCoord [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], float4 uGridlineColor [[buffer(0)]], float4 uGroundColor [[buffer(1)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float2 texCoordPx = fract(in.vTexCoord) / fwidth(in.vTexCoord);
bool4 _33 = bool4(any(texCoordPx <= float2(1.0)));
out.oFragColor = float4(_33.x ? uGridlineColor.x : uGroundColor.x, _33.y ? uGridlineColor.y : uGroundColor.y, _33.z ? uGridlineColor.z : uGroundColor.z, _33.w ? uGridlineColor.w : uGroundColor.w);
out.oFragColor = float4(_33.x ? (*spvDescriptorSet0.uGridlineColor).x : (*spvDescriptorSet0.uGroundColor).x, _33.y ? (*spvDescriptorSet0.uGridlineColor).y : (*spvDescriptorSet0.uGroundColor).y, _33.z ? (*spvDescriptorSet0.uGridlineColor).z : (*spvDescriptorSet0.uGroundColor).z, _33.w ? (*spvDescriptorSet0.uGridlineColor).w : (*spvDescriptorSet0.uGroundColor).w);
return out;
}

View File

@ -1,8 +1,15 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant int* uGridlineCount [[id(0)]];
constant float4x4* uTransform [[id(1)]];
};
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
@ -11,14 +18,14 @@ struct main0_out
struct main0_in
{
float2 aPosition [[attribute(0)]];
int2 aPosition [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], int uGridlineCount [[buffer(0)]], float4x4 uTransform [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.vTexCoord = in.aPosition * float(uGridlineCount);
out.gl_Position = uTransform * float4(in.aPosition.x, 0.0, in.aPosition.y, 1.0);
out.vTexCoord = float2(in.aPosition * int2((*spvDescriptorSet0.uGridlineCount)));
out.gl_Position = (*spvDescriptorSet0.uTransform) * float4(int4(in.aPosition.x, 0, in.aPosition.y, 1));
return out;
}

View File

@ -1,8 +1,15 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
texture2d<float> uAreaLUT [[id(0)]];
sampler uAreaLUTSmplr [[id(1)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -14,7 +21,7 @@ struct main0_in
float2 vTo [[user(locn1)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[texture(0)]], sampler uAreaLUTSmplr [[sampler(0)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float2 from = in.vFrom;
@ -29,7 +36,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uAreaLUT [[t
float y = mix(left.y, right.y, t);
float d = (right.y - left.y) / (right.x - left.x);
float dX = window.x - window.y;
out.oFragColor = float4(uAreaLUT.sample(uAreaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))).x * dX);
out.oFragColor = float4(spvDescriptorSet0.uAreaLUT.sample(spvDescriptorSet0.uAreaLUTSmplr, (float2(y + 8.0, abs(d * dX)) / float2(16.0))).x * dX);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,12 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uFramebufferSize [[id(1)]];
};
struct main0_out
{
float2 vFrom [[user(locn0)]];
@ -14,7 +21,7 @@ struct main0_out
struct main0_in
{
float2 aTessCoord [[attribute(0)]];
uint2 aTessCoord [[attribute(0)]];
uint aFromPx [[attribute(1)]];
uint aToPx [[attribute(2)]];
float2 aFromSubpx [[attribute(3)]];
@ -22,23 +29,23 @@ struct main0_in
uint aTileIndex [[attribute(5)]];
};
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize, thread uint& aTileIndex)
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize)
{
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uint2 tileOffset = uint2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
uint2 tileOffset = uint2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return float2(tileOffset) * uTileSize;
}
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uFramebufferSize [[buffer(1)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
uint param = in.aTileIndex;
float param_1 = uFramebufferSize.x;
float2 tileOrigin = computeTileOffset(param, param_1, uTileSize, in.aTileIndex);
float param_1 = (*spvDescriptorSet0.uFramebufferSize).x;
float2 tileOrigin = computeTileOffset(param, param_1, (*spvDescriptorSet0.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 < 0.5)
if (in.aTessCoord.x == 0u)
{
position.x = floor(fast::min(from.x, to.x));
}
@ -46,17 +53,19 @@ vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]],
{
position.x = ceil(fast::max(from.x, to.x));
}
if (in.aTessCoord.y < 0.5)
if (in.aTessCoord.y == 0u)
{
position.y = floor(fast::min(from.y, to.y));
}
else
{
position.y = uTileSize.y;
position.y = (*spvDescriptorSet0.uTileSize).y;
}
out.vFrom = from - position;
out.vTo = to - position;
out.gl_Position = float4((((tileOrigin + position) / uFramebufferSize) * 2.0) - float2(1.0), 0.0, 1.0);
float2 globalPosition = (((tileOrigin + position) / (*spvDescriptorSet0.uFramebufferSize)) * 2.0) - float2(1.0);
globalPosition.y = -globalPosition.y;
out.gl_Position = float4(globalPosition, 0.0, 1.0);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,19 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4* uKernel [[id(0)]];
texture2d<float> uGammaLUT [[id(1)]];
texture2d<float> uSource [[id(2)]];
constant float2* uSourceSize [[id(3)]];
sampler uSourceSmplr [[id(4)]];
sampler uGammaLUTSmplr [[id(5)]];
constant int* uGammaCorrectionEnabled [[id(6)]];
constant float4* uBGColor [[id(7)]];
constant float4* uFGColor [[id(8)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -78,42 +92,42 @@ float3 gammaCorrect(thread const float3& bgColor, thread const float3& fgColor,
return float3(gammaCorrectChannel(param, param_1, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_2, param_3, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_4, param_5, uGammaLUT, uGammaLUTSmplr));
}
fragment main0_out main0(main0_in in [[stage_in]], int uGammaCorrectionEnabled [[buffer(2)]], float4 uKernel [[buffer(0)]], float2 uSourceSize [[buffer(1)]], float4 uBGColor [[buffer(3)]], float4 uFGColor [[buffer(4)]], texture2d<float> uGammaLUT [[texture(0)]], texture2d<float> uSource [[texture(0)]], sampler uGammaLUTSmplr [[sampler(0)]], sampler uSourceSmplr [[sampler(0)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float3 alpha;
if (uKernel.w == 0.0)
if ((*spvDescriptorSet0.uKernel).w == 0.0)
{
alpha = uSource.sample(uSourceSmplr, in.vTexCoord).xxx;
alpha = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord).xxx;
}
else
{
float param_3 = 1.0 / uSourceSize.x;
float param_3 = 1.0 / (*spvDescriptorSet0.uSourceSize).x;
float4 param;
float param_1;
float4 param_2;
sample9Tap(param, param_1, param_2, param_3, uKernel, uSource, uSourceSmplr, in.vTexCoord);
sample9Tap(param, param_1, param_2, param_3, (*spvDescriptorSet0.uKernel), spvDescriptorSet0.uSource, spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
float4 alphaLeft = param;
float alphaCenter = param_1;
float4 alphaRight = param_2;
float4 param_4 = alphaLeft;
float3 param_5 = float3(alphaCenter, alphaRight.xy);
float r = convolve7Tap(param_4, param_5, uKernel);
float r = convolve7Tap(param_4, param_5, (*spvDescriptorSet0.uKernel));
float4 param_6 = float4(alphaLeft.yzw, alphaCenter);
float3 param_7 = alphaRight.xyz;
float g = convolve7Tap(param_6, param_7, uKernel);
float g = convolve7Tap(param_6, param_7, (*spvDescriptorSet0.uKernel));
float4 param_8 = float4(alphaLeft.zw, alphaCenter, alphaRight.x);
float3 param_9 = alphaRight.yzw;
float b = convolve7Tap(param_8, param_9, uKernel);
float b = convolve7Tap(param_8, param_9, (*spvDescriptorSet0.uKernel));
alpha = float3(r, g, b);
}
if (uGammaCorrectionEnabled != 0)
if ((*spvDescriptorSet0.uGammaCorrectionEnabled) != 0)
{
float3 param_10 = uBGColor.xyz;
float3 param_10 = (*spvDescriptorSet0.uBGColor).xyz;
float3 param_11 = alpha;
alpha = gammaCorrect(param_10, param_11, uGammaLUT, uGammaLUTSmplr);
alpha = gammaCorrect(param_10, param_11, spvDescriptorSet0.uGammaLUT, spvDescriptorSet0.uGammaLUTSmplr);
}
out.oFragColor = float4(mix(uBGColor.xyz, uFGColor.xyz, alpha), 1.0);
out.oFragColor = float4(mix((*spvDescriptorSet0.uBGColor).xyz, (*spvDescriptorSet0.uFGColor).xyz, alpha), 1.0);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
@ -11,14 +12,14 @@ struct main0_out
struct main0_in
{
float2 aPosition [[attribute(0)]];
int2 aPosition [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.vTexCoord = in.aPosition;
out.gl_Position = float4((in.aPosition * 2.0) - float2(1.0), 0.0, 1.0);
out.vTexCoord = float2(in.aPosition);
out.gl_Position = float4((float2(in.aPosition) * 2.0) - float2(1.0), 0.0, 1.0);
return out;
}

View File

@ -1,8 +1,16 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4x4* uOldTransform [[id(0)]];
texture2d<float> uTexture [[id(1)]];
sampler uTextureSmplr [[id(2)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -13,12 +21,12 @@ struct main0_in
float2 vTexCoord [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], float4x4 uOldTransform [[buffer(0)]], texture2d<float> uTexture [[texture(0)]], sampler uTextureSmplr [[sampler(0)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float4 normTexCoord = uOldTransform * float4(in.vTexCoord, 0.0, 1.0);
float4 normTexCoord = (*spvDescriptorSet0.uOldTransform) * float4(in.vTexCoord, 0.0, 1.0);
float2 texCoord = ((normTexCoord.xy / float2(normTexCoord.w)) + float2(1.0)) * 0.5;
out.oFragColor = uTexture.sample(uTextureSmplr, texCoord);
out.oFragColor = spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, texCoord);
return out;
}

View File

@ -1,8 +1,14 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float4x4* uNewTransform [[id(0)]];
};
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
@ -11,14 +17,16 @@ struct main0_out
struct main0_in
{
float2 aPosition [[attribute(0)]];
int2 aPosition [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], float4x4 uNewTransform [[buffer(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
out.vTexCoord = in.aPosition;
out.gl_Position = uNewTransform * float4(in.aPosition, 0.0, 1.0);
float2 position = float2(in.aPosition);
out.vTexCoord = position;
position.y = 1.0 - position.y;
out.gl_Position = (*spvDescriptorSet0.uNewTransform) * float4(position, 0.0, 1.0);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
@ -13,7 +14,7 @@ struct main0_in
float3 aPosition [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.gl_Position = float4(in.aPosition, 1.0);

View File

@ -1,8 +1,15 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct spvDescriptorSetBuffer0
{
texture2d<float> uStencilTexture [[id(0)]];
sampler uStencilTextureSmplr [[id(1)]];
};
struct main0_out
{
float4 oFragColor [[color(0)]];
@ -15,10 +22,10 @@ struct main0_in
float4 vColor [[user(locn2)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uStencilTexture [[texture(0)]], sampler uStencilTextureSmplr [[sampler(0)]])
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
float coverage = abs(uStencilTexture.sample(uStencilTextureSmplr, in.vTexCoord).x + in.vBackdrop);
float coverage = abs(spvDescriptorSet0.uStencilTexture.sample(spvDescriptorSet0.uStencilTextureSmplr, in.vTexCoord).x + in.vBackdrop);
out.oFragColor = float4(in.vColor.xyz, in.vColor.w * coverage);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,15 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
constant float2* uStencilTextureSize [[id(3)]];
constant float4* uColor [[id(4)]];
};
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
@ -15,10 +25,10 @@ struct main0_out
struct main0_in
{
float2 aTessCoord [[attribute(0)]];
uint2 aTessCoord [[attribute(0)]];
uint3 aTileOrigin [[attribute(1)]];
int aBackdrop [[attribute(2)]];
uint aTileIndex [[attribute(3)]];
int aTileIndex [[attribute(3)]];
};
float2 computeTileOffset(thread const uint& tileIndex, thread const float& stencilTextureWidth, thread float2 uTileSize)
@ -33,25 +43,25 @@ float4 getColor(thread float4 uColor)
return uColor;
}
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread float2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread uint& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
{
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
float2 pixelPosition = ((origin + aTessCoord) * uTileSize) + uViewBoxOrigin;
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
uint param = aTileIndex;
uint param = uint(aTileIndex);
float param_1 = uStencilTextureSize.x;
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
float2 maskTexCoord = maskTexCoordOrigin + (aTessCoord * uTileSize);
float2 maskTexCoord = maskTexCoordOrigin + (float2(aTessCoord) * uTileSize);
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor(uColor);
gl_Position = float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float2 uStencilTextureSize [[buffer(3)]], float4 uColor [[buffer(4)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(uTileSize, in.aTileOrigin, in.aTessCoord, uViewBoxOrigin, uFramebufferSize, in.aTileIndex, uStencilTextureSize, out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, uColor);
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,16 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
texture2d<float> uPaintTexture [[id(1)]];
constant float2* uViewBoxOrigin [[id(2)]];
sampler uPaintTextureSmplr [[id(3)]];
constant float2* uFramebufferSize [[id(4)]];
constant float2* uStencilTextureSize [[id(5)]];
};
struct main0_out
{
float2 vTexCoord [[user(locn0)]];
@ -15,10 +26,10 @@ struct main0_out
struct main0_in
{
float2 aTessCoord [[attribute(0)]];
uint2 aTessCoord [[attribute(0)]];
uint3 aTileOrigin [[attribute(1)]];
int aBackdrop [[attribute(2)]];
uint aTileIndex [[attribute(3)]];
int aTileIndex [[attribute(3)]];
float2 aColorTexCoord [[attribute(4)]];
};
@ -34,25 +45,25 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
}
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread float2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread uint& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
{
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
float2 pixelPosition = ((origin + aTessCoord) * uTileSize) + uViewBoxOrigin;
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
uint param = aTileIndex;
uint param = uint(aTileIndex);
float param_1 = uStencilTextureSize.x;
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
float2 maskTexCoord = maskTexCoordOrigin + (aTessCoord * uTileSize);
float2 maskTexCoord = maskTexCoordOrigin + (float2(aTessCoord) * uTileSize);
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
gl_Position = float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float2 uStencilTextureSize [[buffer(3)]], texture2d<float> uPaintTexture [[texture(0)]], sampler uPaintTextureSmplr [[sampler(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(uTileSize, in.aTileOrigin, in.aTessCoord, uViewBoxOrigin, uFramebufferSize, in.aTileIndex, uStencilTextureSize, out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, uPaintTexture, uPaintTextureSmplr, in.aColorTexCoord);
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#include <metal_stdlib>
#include <simd/simd.h>

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,14 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
constant float4* uColor [[id(3)]];
};
struct main0_out
{
float4 vColor [[user(locn0)]];
@ -13,8 +22,8 @@ struct main0_out
struct main0_in
{
float2 aTessCoord [[attribute(0)]];
float2 aTileOrigin [[attribute(1)]];
uint2 aTessCoord [[attribute(0)]];
int2 aTileOrigin [[attribute(1)]];
};
float4 getColor(thread float4 uColor)
@ -22,18 +31,18 @@ float4 getColor(thread float4 uColor)
return uColor;
}
void computeVaryings(thread float2& aTileOrigin, thread float2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
{
float2 pixelPosition = ((aTileOrigin + aTessCoord) * uTileSize) + uViewBoxOrigin;
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
vColor = getColor(uColor);
gl_Position = float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], float4 uColor [[buffer(3)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(in.aTileOrigin, in.aTessCoord, uTileSize, uViewBoxOrigin, uFramebufferSize, out.vColor, out.gl_Position, uColor);
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
return out;
}

View File

@ -1,3 +1,4 @@
// Automatically generated from files in pathfinder/shaders/. Do not edit!
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
@ -5,6 +6,15 @@
using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
texture2d<float> uPaintTexture [[id(1)]];
constant float2* uViewBoxOrigin [[id(2)]];
sampler uPaintTextureSmplr [[id(3)]];
constant float2* uFramebufferSize [[id(4)]];
};
struct main0_out
{
float4 vColor [[user(locn0)]];
@ -13,8 +23,8 @@ struct main0_out
struct main0_in
{
float2 aTessCoord [[attribute(0)]];
float2 aTileOrigin [[attribute(1)]];
uint2 aTessCoord [[attribute(0)]];
int2 aTileOrigin [[attribute(1)]];
float2 aColorTexCoord [[attribute(2)]];
};
@ -23,18 +33,18 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
}
void computeVaryings(thread float2& aTileOrigin, thread float2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
{
float2 pixelPosition = ((aTileOrigin + aTessCoord) * uTileSize) + uViewBoxOrigin;
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
gl_Position = float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], float2 uTileSize [[buffer(0)]], float2 uViewBoxOrigin [[buffer(1)]], float2 uFramebufferSize [[buffer(2)]], texture2d<float> uPaintTexture [[texture(0)]], sampler uPaintTextureSmplr [[sampler(0)]], uint gl_VertexID [[vertex_id]], uint gl_InstanceID [[instance_id]])
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(in.aTileOrigin, in.aTessCoord, uTileSize, uViewBoxOrigin, uFramebufferSize, out.vColor, out.gl_Position, uPaintTexture, uPaintTextureSmplr, in.aColorTexCoord);
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
return out;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -37,14 +37,20 @@ INCLUDES=\
OUT=\
$(SHADERS:%=$(TARGET_DIR)/gl3/%) \
$(SHADERS:%.glsl=$(TARGET_DIR)/metal/%.metal) \
$(SHADERS:%.glsl=build/metal/%.spv) \
$(EMPTY)
GLSL_VERSION=330
GLSLANGFLAGS=--auto-map-locations -I.
GLSLANGFLAGS_METAL=$(GLSLANGFLAGS) -DPF_ORIGIN_UPPER_LEFT=1
SPIRVCROSSFLAGS=--msl
SPIRVCROSS?=spirv-cross
SPIRVCROSSFLAGS=--msl --msl-version 020100 --msl-argument-buffers
SED_ARGS=-e "s/\#version 330/\#version \{\{version\}\}/" -e "s/\#line.*$$//"
GLSL_VERSION_HEADER="\#version {{version}}"
HEADER="// Automatically generated from files in pathfinder/shaders/. Do not edit!"
GLSL_SED_ARGS=-e "s/\#version 330//" -e "s/\#line.*$$//"
all: $(OUT)
@ -53,17 +59,17 @@ all: $(OUT)
clean:
rm -f $(OUT)
$(TARGET_DIR)/spirv/%.fs.spv: %.fs.glsl $(INCLUDES)
mkdir -p $(TARGET_DIR)/spirv && glslangValidator $(GLSLANGFLAGS) -G$(GLSL_VERSION) -S frag -o $@ $<
build/metal/%.fs.spv: %.fs.glsl $(INCLUDES)
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S frag -o $@ $<
$(TARGET_DIR)/gl3/%.fs.glsl: %.fs.glsl $(INCLUDES)
mkdir -p $(TARGET_DIR)/gl3 && glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(SED_ARGS) > $@
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
$(TARGET_DIR)/spirv/%.vs.spv: %.vs.glsl $(INCLUDES)
mkdir -p $(TARGET_DIR)/spirv && glslangValidator $(GLSLANGFLAGS) -G$(GLSL_VERSION) -S vert -o $@ $<
build/metal/%.vs.spv: %.vs.glsl $(INCLUDES)
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S vert -o $@ $<
$(TARGET_DIR)/gl3/%.vs.glsl: %.vs.glsl $(INCLUDES)
mkdir -p $(TARGET_DIR)/gl3 && glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(SED_ARGS) > $@
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
$(TARGET_DIR)/metal/%.metal: $(TARGET_DIR)/spirv/%.spv
mkdir -p $(TARGET_DIR)/metal && spirv-cross $(SPIRVCROSSFLAGS) --output $@ $<
$(TARGET_DIR)/metal/%.metal: build/metal/%.spv
mkdir -p $(TARGET_DIR)/metal && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< | sed $(METAL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )

View File

@ -14,9 +14,9 @@ precision highp float;
uniform vec2 uFramebufferSize;
in vec2 aPosition;
in ivec2 aPosition;
void main() {
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
vec2 position = vec2(aPosition) / uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position.x, -position.y, 0.0, 1.0);
}

View File

@ -15,13 +15,13 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTextureSize;
in vec2 aPosition;
in vec2 aTexCoord;
in ivec2 aPosition;
in ivec2 aTexCoord;
out vec2 vTexCoord;
void main() {
vTexCoord = aTexCoord / uTextureSize;
vec2 position = aPosition / uFramebufferSize * 2.0 - 1.0;
vTexCoord = vec2(aTexCoord) / uTextureSize;
vec2 position = vec2(aPosition) / uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position.x, -position.y, 0.0, 1.0);
}

View File

@ -15,11 +15,11 @@ precision highp float;
uniform mat4 uTransform;
uniform int uGridlineCount;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main() {
vTexCoord = aPosition * float(uGridlineCount);
gl_Position = uTransform * vec4(aPosition.x, 0.0, aPosition.y, 1.0);
vTexCoord = vec2(aPosition * uGridlineCount);
gl_Position = uTransform * vec4(ivec4(aPosition.x, 0, aPosition.y, 1));
}

View File

@ -1,6 +1,6 @@
#version 330
// pathfinder/resources/fill.vs.glsl
// pathfinder/shaders/fill.vs.glsl
//
// Copyright © 2019 The Pathfinder Project Developers.
//
@ -15,7 +15,7 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
in vec2 aTessCoord;
in uvec2 aTessCoord;
in uint aFromPx;
in uint aToPx;
in vec2 aFromSubpx;
@ -27,7 +27,7 @@ out vec2 vTo;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset) * uTileSize;
}
@ -38,11 +38,11 @@ void main() {
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
vec2 position;
if (aTessCoord.x < 0.5)
if (aTessCoord.x == 0u)
position.x = floor(min(from.x, to.x));
else
position.x = ceil(max(from.x, to.x));
if (aTessCoord.y < 0.5)
if (aTessCoord.y == 0u)
position.y = floor(min(from.y, to.y));
else
position.y = uTileSize.y;
@ -50,5 +50,9 @@ void main() {
vFrom = from - position;
vTo = to - position;
gl_Position = vec4((tileOrigin + position) / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
vec2 globalPosition = (tileOrigin + position) / uFramebufferSize * 2.0 - 1.0;
#ifdef PF_ORIGIN_UPPER_LEFT
globalPosition.y = -globalPosition.y;
#endif
gl_Position = vec4(globalPosition, 0.0, 1.0);
}

View File

@ -12,11 +12,11 @@
precision highp float;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main() {
vTexCoord = aPosition;
gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);
vTexCoord = vec2(aPosition);
gl_Position = vec4(vec2(aPosition) * 2.0 - 1.0, 0.0, 1.0);
}

View File

@ -14,11 +14,17 @@ precision highp float;
uniform mat4 uNewTransform;
in vec2 aPosition;
in ivec2 aPosition;
out vec2 vTexCoord;
void main() {
vTexCoord = aPosition;
gl_Position = uNewTransform * vec4(aPosition, 0.0, 1.0);
vec2 position = vec2(aPosition);
vTexCoord = position;
#ifdef PF_ORIGIN_UPPER_LEFT
// FIXME(pcwalton): This is wrong.
position.y = 1.0 - position.y;
#endif
gl_Position = uNewTransform * vec4(position, 0.0, 1.0);
}

View File

@ -13,10 +13,10 @@ uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
in int aBackdrop;
in uint aTileIndex;
in int aTileIndex;
out vec2 vTexCoord;
out float vBackdrop;
@ -32,9 +32,9 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
void computeVaryings() {
vec2 origin = vec2(aTileOrigin.xy) + vec2(aTileOrigin.z & 15u, aTileOrigin.z >> 4u) * 256.0;
vec2 pixelPosition = (origin + aTessCoord) * uTileSize + uViewBoxOrigin;
vec2 pixelPosition = (origin + vec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
vec2 maskTexCoordOrigin = computeTileOffset(aTileIndex, uStencilTextureSize.x);
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize.x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;

View File

@ -12,18 +12,17 @@ uniform vec2 uFramebufferSize;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in vec2 aTessCoord;
in vec2 aTileOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
out vec4 vColor;
vec4 getColor();
void computeVaryings() {
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
vColor = getColor();
//vColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_Position = vec4(position, 0.0, 1.0);
}

View File

@ -22,7 +22,7 @@ use pathfinder_geometry::basic::rect::RectI;
use pathfinder_geometry::color::ColorU;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, Device, Primitive};
use pathfinder_gpu::{RenderState, UniformData, VertexAttrClass};
use pathfinder_gpu::{RenderOptions, RenderState, RenderTarget, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_simd::default::F32x4;
use serde_json;
@ -131,7 +131,11 @@ impl<D> UIPresenter<D> where D: Device {
self.draw_rect(device, rect, color, false);
}
fn draw_rect(&self, device: &D, rect: RectI, color: ColorU, filled: bool) {
fn draw_rect(&self,
device: &D,
rect: RectI,
color: ColorU,
filled: bool) {
let vertex_data = [
DebugSolidVertex::new(rect.origin()),
DebugSolidVertex::new(rect.upper_right()),
@ -160,8 +164,6 @@ impl<D> UIPresenter<D> where D: Device {
index_data: &[u32],
color: ColorU,
filled: bool) {
device.bind_vertex_array(&self.solid_vertex_array.vertex_array);
device.allocate_buffer(&self.solid_vertex_array.vertex_buffer,
BufferData::Memory(vertex_data),
BufferTarget::Vertex,
@ -171,15 +173,23 @@ impl<D> UIPresenter<D> where D: Device {
BufferTarget::Index,
BufferUploadMode::Dynamic);
device.use_program(&self.solid_program.program);
device.set_uniform(&self.solid_program.framebuffer_size_uniform,
UniformData::Vec2(self.framebuffer_size.0.to_f32x4()));
set_color_uniform(device, &self.solid_program.color_uniform, color);
let primitive = if filled { Primitive::Triangles } else { Primitive::Lines };
device.draw_elements(primitive, index_data.len() as u32, &RenderState {
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
..RenderState::default()
device.draw_elements(index_data.len() as u32, &RenderState {
target: &RenderTarget::Default,
program: &self.solid_program.program,
vertex_array: &self.solid_vertex_array.vertex_array,
primitive,
uniforms: &[
(&self.solid_program.framebuffer_size_uniform,
UniformData::Vec2(self.framebuffer_size.0.to_f32x4())),
(&self.solid_program.color_uniform, get_color_uniform(color)),
],
textures: &[],
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
options: RenderOptions {
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
..RenderOptions::default()
},
});
}
@ -396,19 +406,25 @@ impl<D> UIPresenter<D> where D: Device {
BufferTarget::Index,
BufferUploadMode::Dynamic);
device.bind_vertex_array(&self.texture_vertex_array.vertex_array);
device.use_program(&self.texture_program.program);
device.set_uniform(&self.texture_program.framebuffer_size_uniform,
UniformData::Vec2(self.framebuffer_size.0.to_f32x4()));
device.set_uniform(&self.texture_program.texture_size_uniform,
UniformData::Vec2(device.texture_size(&texture).0.to_f32x4()));
set_color_uniform(device, &self.texture_program.color_uniform, color);
device.bind_texture(texture, 0);
device.set_uniform(&self.texture_program.texture_uniform, UniformData::TextureUnit(0));
device.draw_elements(Primitive::Triangles, index_data.len() as u32, &RenderState {
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
..RenderState::default()
device.draw_elements(index_data.len() as u32, &RenderState {
target: &RenderTarget::Default,
program: &self.texture_program.program,
vertex_array: &self.texture_vertex_array.vertex_array,
primitive: Primitive::Triangles,
textures: &[&texture],
uniforms: &[
(&self.texture_program.framebuffer_size_uniform,
UniformData::Vec2(self.framebuffer_size.0.to_f32x4())),
(&self.texture_program.color_uniform, get_color_uniform(color)),
(&self.texture_program.texture_uniform, UniformData::TextureUnit(0)),
(&self.texture_program.texture_size_uniform,
UniformData::Vec2(device.texture_size(&texture).0.to_f32x4()))
],
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
options: RenderOptions {
blend: BlendState::RGBOneAlphaOneMinusSrcAlpha,
..RenderOptions::default()
},
});
}
@ -508,9 +524,9 @@ impl<D> UIPresenter<D> where D: Device {
let highlight_size = Vector2I::new(SEGMENT_SIZE, BUTTON_HEIGHT);
let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1);
self.draw_solid_rounded_rect(device,
RectI::new(origin + Vector2I::new(x_offset, 0),
RectI::new(origin + Vector2I::new(x_offset, 0),
highlight_size),
TEXT_COLOR);
TEXT_COLOR);
}
let mut segment_origin = origin + Vector2I::new(SEGMENT_SIZE + 1, 0);
@ -520,9 +536,9 @@ impl<D> UIPresenter<D> where D: Device {
Some(value) if value == prev_segment_index || value == next_segment_index => {}
_ => {
self.draw_line(device,
segment_origin,
segment_origin + Vector2I::new(0, BUTTON_HEIGHT),
TEXT_COLOR);
segment_origin,
segment_origin + Vector2I::new(0, BUTTON_HEIGHT),
TEXT_COLOR);
}
}
segment_origin = segment_origin + Vector2I::new(SEGMENT_SIZE + 1, 0);
@ -590,25 +606,25 @@ impl<D> DebugTextureVertexArray<D> where D: Device {
let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord")
.unwrap();
device.bind_vertex_array(&vertex_array);
device.use_program(&debug_texture_program.program);
device.bind_buffer(&vertex_buffer, BufferTarget::Vertex);
device.bind_buffer(&index_buffer, BufferTarget::Index);
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Float,
attr_type: VertexAttrType::U16,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: DEBUG_TEXTURE_VERTEX_SIZE,
offset: 0,
divisor: 0,
buffer_index: 0,
});
device.configure_vertex_attr(&tex_coord_attr, &VertexAttrDescriptor {
device.configure_vertex_attr(&vertex_array, &tex_coord_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Float,
attr_type: VertexAttrType::U16,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: DEBUG_TEXTURE_VERTEX_SIZE,
offset: 4,
divisor: 0,
buffer_index: 0,
});
DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer }
@ -626,19 +642,18 @@ impl<D> DebugSolidVertexArray<D> where D: Device {
let (vertex_buffer, index_buffer) = (device.create_buffer(), device.create_buffer());
let vertex_array = device.create_vertex_array();
let position_attr = device.get_vertex_attr(&debug_solid_program.program, "Position")
.unwrap();
device.bind_vertex_array(&vertex_array);
device.use_program(&debug_solid_program.program);
device.bind_buffer(&vertex_buffer, BufferTarget::Vertex);
device.bind_buffer(&index_buffer, BufferTarget::Index);
device.configure_vertex_attr(&position_attr, &VertexAttrDescriptor {
let position_attr =
device.get_vertex_attr(&debug_solid_program.program, "Position").unwrap();
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
size: 2,
class: VertexAttrClass::Float,
attr_type: VertexAttrType::U16,
class: VertexAttrClass::Int,
attr_type: VertexAttrType::I16,
stride: DEBUG_SOLID_VERTEX_SIZE,
offset: 0,
divisor: 0,
buffer_index: 0,
});
DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer }
@ -714,9 +729,9 @@ impl CornerRects {
}
}
fn set_color_uniform<D>(device: &D, uniform: &D::Uniform, color: ColorU) where D: Device {
fn get_color_uniform(color: ColorU) -> UniformData {
let color = F32x4::new(color.r as f32, color.g as f32, color.b as f32, color.a as f32);
device.set_uniform(uniform, UniformData::Vec4(color * F32x4::splat(1.0 / 255.0)));
UniformData::Vec4(color * F32x4::splat(1.0 / 255.0))
}
#[derive(Clone, Copy)]