mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Make the GPU render and dispatch pipelines synchronous
This commit is contained in:
@@ -9,7 +9,7 @@ use crate::texture_cache::TextureCache;
|
||||
use anyhow::Result;
|
||||
use core_types::Color;
|
||||
use core_types::color::SRGBA8;
|
||||
use futures::lock::Mutex;
|
||||
use std::sync::Mutex;
|
||||
use glam::UVec2;
|
||||
use graphene_application_io::{ApplicationIo, EditorApi};
|
||||
use raster_types::Texture;
|
||||
@@ -19,7 +19,6 @@ use wgpu::{Origin3d, TextureAspect};
|
||||
|
||||
pub use context::Context as WgpuContext;
|
||||
pub use context::ContextBuilder as WgpuContextBuilder;
|
||||
pub use pipeline::AsyncPipeline as AsyncWgpuPipeline;
|
||||
pub use pipeline::Pipeline as WgpuPipeline;
|
||||
pub use pipeline::PipelineCache as WgpuPipelineCache;
|
||||
pub use rendering::RenderContext;
|
||||
@@ -68,8 +67,8 @@ impl<'a, T: ApplicationIo<Executor = WgpuExecutor>> From<&'a EditorApi<T>> for &
|
||||
}
|
||||
|
||||
impl WgpuExecutor {
|
||||
pub async fn render_vello_scene(&self, scene: &Scene, size: UVec2, context: &RenderContext, background: Option<Color>) -> Result<Texture> {
|
||||
let texture = self.request_texture(size).await;
|
||||
pub fn render_vello_scene(&self, scene: &Scene, size: UVec2, context: &RenderContext, background: Option<Color>) -> Result<Texture> {
|
||||
let texture = self.request_texture(size);
|
||||
|
||||
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
@@ -82,7 +81,7 @@ impl WgpuExecutor {
|
||||
};
|
||||
|
||||
{
|
||||
let mut renderer = self.inner.vello_renderer.lock().await;
|
||||
let mut renderer = self.inner.vello_renderer.lock().unwrap();
|
||||
for (image_brush, texture) in context.resource_overrides.iter() {
|
||||
let texture_view = wgpu::TexelCopyTextureInfoBase {
|
||||
texture: (**texture).clone(),
|
||||
@@ -109,8 +108,8 @@ impl WgpuExecutor {
|
||||
pipeline.init::<P>(self);
|
||||
}
|
||||
|
||||
pub async fn request_texture(&self, size: UVec2) -> Texture {
|
||||
self.inner.texture_cache.lock().await.request_texture(&self.context().device, size)
|
||||
pub fn request_texture(&self, size: UVec2) -> Texture {
|
||||
self.inner.texture_cache.lock().unwrap().request_texture(&self.context().device, size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +1,16 @@
|
||||
use dyn_any::DynAny;
|
||||
use std::any::Any;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
use crate::WgpuExecutor;
|
||||
|
||||
pub type PipelineFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
|
||||
pub trait Pipeline: Any + Send + Sync + Sized {
|
||||
type Args<'a>;
|
||||
type Out: Send;
|
||||
|
||||
fn create(executor: &WgpuExecutor) -> Self;
|
||||
|
||||
fn run<'a>(&'a self, executor: &'a WgpuExecutor, args: &'a Self::Args<'_>) -> PipelineFuture<'a, Self::Out>;
|
||||
}
|
||||
|
||||
pub trait AsyncPipeline: Any + Send + Sync + Sized {
|
||||
type Args<'a>;
|
||||
type Out: Send;
|
||||
|
||||
fn create(executor: &WgpuExecutor) -> Self;
|
||||
|
||||
fn run<'a>(&'a self, executor: &'a WgpuExecutor, args: &'a Self::Args<'_>) -> impl Future<Output = Self::Out> + Send + 'a;
|
||||
}
|
||||
|
||||
impl<P: AsyncPipeline> Pipeline for P {
|
||||
type Args<'a> = <P as AsyncPipeline>::Args<'a>;
|
||||
type Out = <P as AsyncPipeline>::Out;
|
||||
|
||||
fn create(executor: &WgpuExecutor) -> Self {
|
||||
<P as AsyncPipeline>::create(executor)
|
||||
}
|
||||
|
||||
fn run<'a>(&'a self, executor: &'a WgpuExecutor, args: &'a Self::Args<'_>) -> PipelineFuture<'a, Self::Out> {
|
||||
Box::pin(<P as AsyncPipeline>::run(self, executor, args))
|
||||
}
|
||||
fn run<'a>(&'a self, executor: &'a WgpuExecutor, args: &'a Self::Args<'_>) -> Self::Out;
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, DynAny)]
|
||||
@@ -51,13 +25,13 @@ impl PipelineCache {
|
||||
self.pipeline.get_or_init(|| Box::new(P::create(executor)));
|
||||
}
|
||||
|
||||
pub async fn run<P: Pipeline>(&self, args: &P::Args<'_>) -> P::Out {
|
||||
pub fn run<P: Pipeline>(&self, args: &P::Args<'_>) -> P::Out {
|
||||
let executor = self.executor.get().expect("PipelineCache not initialized");
|
||||
let entry = self.pipeline.get().expect("PipelineCache not initialized");
|
||||
let pipeline = (&**entry)
|
||||
.downcast_ref::<P>()
|
||||
.unwrap_or_else(|| panic!("PipelineCache type mismatch: run::<{}>() but init used a different pipeline type", std::any::type_name::<P>(),));
|
||||
pipeline.run(executor, args).await
|
||||
pipeline.run(executor, args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::WgpuContext;
|
||||
use crate::shader_runtime::{FULLSCREEN_VERTEX_SHADER_NAME, ShaderRuntime};
|
||||
use core_types::list::{Item, List};
|
||||
use core_types::shaders::buffer_struct::BufferStruct;
|
||||
use futures::lock::Mutex;
|
||||
use std::sync::Mutex;
|
||||
use raster_types::{GPU, Raster};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
@@ -33,8 +33,8 @@ impl PerPixelAdjustShaderRuntime {
|
||||
}
|
||||
|
||||
impl ShaderRuntime {
|
||||
pub async fn run_per_pixel_adjust<T: BufferStruct>(&self, shaders: &Shaders<'_>, textures: List<Raster<GPU>>, args: Option<&T>) -> List<Raster<GPU>> {
|
||||
let mut cache = self.per_pixel_adjust.pipeline_cache.lock().await;
|
||||
pub fn run_per_pixel_adjust<T: BufferStruct>(&self, shaders: &Shaders<'_>, textures: List<Raster<GPU>>, args: Option<&T>) -> List<Raster<GPU>> {
|
||||
let mut cache = self.per_pixel_adjust.pipeline_cache.lock().unwrap();
|
||||
let pipeline = cache
|
||||
.entry(shaders.fragment_shader_name.to_owned())
|
||||
.or_insert_with(|| PerPixelAdjustGraphicsPipeline::new(&self.context, shaders));
|
||||
|
||||
Reference in New Issue
Block a user