More progress exposing interface

Much of the surface area exists for rendering now.

WIP of course still
This commit is contained in:
Raph Levien 2022-01-18 18:41:28 -08:00
parent 5e221d2e91
commit 833d993a4e
7 changed files with 137 additions and 5 deletions

View file

@ -401,6 +401,33 @@ impl Session {
pub fn backend_type(&self) -> BackendType {
self.0.device.backend_type()
}
#[cfg(target_os = "macos")]
pub unsafe fn cmd_buf_from_raw_mtl(&self, raw_cmd_buf: &::metal::CommandBufferRef) -> CmdBuf {
let cmd_buf = Some(self.0.device.cmd_buf_from_raw_mtl(raw_cmd_buf));
let resources = Vec::new();
// Expect client to do cleanup manually.
let session = Weak::new();
CmdBuf {
cmd_buf,
fence: None,
resources,
session,
}
}
#[cfg(target_os = "macos")]
pub unsafe fn image_from_raw_mtl(
&self,
raw_texture: &::metal::TextureRef,
width: u32,
height: u32,
) -> Image {
let image = self.0.device.image_from_raw_mtl(raw_texture, width, height);
// Expect client to do cleanup manually.
let session = Weak::new();
Image(Arc::new(ImageInner { image, session }))
}
}
impl SessionInner {

View file

@ -16,8 +16,8 @@ mod macros;
mod mux;
pub use crate::mux::{
DescriptorSet, Device, Fence, Instance, Pipeline, QueryPool, Sampler, Semaphore, ShaderCode, Surface,
Swapchain,
DescriptorSet, Device, Fence, Instance, Pipeline, QueryPool, Sampler, Semaphore, ShaderCode,
Surface, Swapchain,
};
pub use bufwrite::BufWrite;
pub use hub::{

View file

@ -216,6 +216,20 @@ impl MtlDevice {
helpers,
}
}
pub fn cmd_buf_from_raw_mtl(&self, raw_cmd_buf: metal::CommandBuffer) -> CmdBuf {
let cmd_buf = raw_cmd_buf;
let helpers = self.helpers.clone();
CmdBuf { cmd_buf, helpers }
}
pub fn image_from_raw_mtl(&self, texture: metal::Texture, width: u32, height: u32) -> Image {
Image {
texture,
width,
height,
}
}
}
impl crate::backend::Device for MtlDevice {

View file

@ -209,8 +209,35 @@ impl Instance {
// missing functionality).
impl Device {
#[cfg(target_os = "macos")]
pub fn new_from_raw_mtl(device: &::metal::DeviceRef, queue: &::metal::CommandQueueRef) -> Device {
Device::Mtl(metal::MtlDevice::new_from_raw_mtl(device.to_owned(), queue.to_owned()))
pub fn new_from_raw_mtl(
device: &::metal::DeviceRef,
queue: &::metal::CommandQueueRef,
) -> Device {
Device::Mtl(metal::MtlDevice::new_from_raw_mtl(
device.to_owned(),
queue.to_owned(),
))
}
#[cfg(target_os = "macos")]
pub fn cmd_buf_from_raw_mtl(&self, raw_cmd_buf: &::metal::CommandBufferRef) -> CmdBuf {
// Note: this will cause problems if we support multiple back-ends on mac. But it will
// be a compile error;
let Device::Mtl(d) = self;
CmdBuf::Mtl(d.cmd_buf_from_raw_mtl(raw_cmd_buf.to_owned()))
}
#[cfg(target_os = "macos")]
pub fn image_from_raw_mtl(
&self,
raw_texture: &::metal::TextureRef,
width: u32,
height: u32,
) -> Image {
// Note: this will cause problems if we support multiple back-ends on mac. But it will
// be a compile error;
let Device::Mtl(d) = self;
Image::Mtl(d.image_from_raw_mtl(raw_texture.to_owned(), width, height))
}
pub fn query_gpu_info(&self) -> GpuInfo {

View file

@ -0,0 +1,63 @@
// Copyright 2022 The piet-gpu authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Also licensed under MIT license, at your choice.
//! An experimental API for glyph rendering.
use swash::{scale::ScaleContext, CacheKey, FontRef};
use crate::{encoder::GlyphEncoder, PietGpuRenderContext};
pub struct GlyphRenderer {
pub render_ctx: PietGpuRenderContext,
scale_context: ScaleContext,
}
#[repr(transparent)]
pub struct FontId(CacheKey);
impl GlyphRenderer {
pub fn new() -> GlyphRenderer {
GlyphRenderer {
render_ctx: PietGpuRenderContext::new(),
scale_context: ScaleContext::new(),
}
}
pub unsafe fn add_glyph(&mut self, font_data: &[u8], font_id: u64, glyph_id: u16) {
// This transmute is dodgy because the definition in swash isn't repr(transparent).
// I think the best solution is to have a from_u64 method, but we'll work that out
// later.
let font_id = FontId(std::mem::transmute(font_id));
let encoder = self.make_glyph(font_data, font_id, glyph_id);
self.render_ctx.encode_glyph(&encoder);
// TODO: don't fill glyph if RGBA
self.render_ctx.fill_glyph(0xff_ff_ff_ff);
}
fn make_glyph(&mut self, font_data: &[u8], font_id: FontId, glyph_id: u16) -> GlyphEncoder {
let mut encoder = GlyphEncoder::default();
let font_ref = FontRef {
data: font_data,
offset: 0,
key: font_id.0,
};
let mut scaler = self.scale_context.builder(font_ref).size(2048.).build();
if let Some(outline) = scaler.scale_outline(glyph_id) {
crate::text::append_outline(&mut encoder, outline.verbs(), outline.points());
}
encoder
}
}

View file

@ -1,4 +1,5 @@
mod encoder;
pub mod glyph_render;
mod gradient;
mod pico_svg;
mod render_ctx;

View file

@ -260,7 +260,7 @@ impl TextLayoutBuilder for PietGpuTextLayoutBuilder {
}
}
fn append_outline(encoder: &mut GlyphEncoder, verbs: &[Verb], points: &[Vector]) {
pub(crate) fn append_outline(encoder: &mut GlyphEncoder, verbs: &[Verb], points: &[Vector]) {
let mut path_encoder = encoder.path_encoder();
let mut i = 0;
for verb in verbs {