Instance tables refactor part 6: unwrap VectorData and ImageFrame from single-row to multi-row tables (#2684)

* Start refactoring the boolean operations code

* Switch to iterators in the boolean operations code

* Make boolean operations work on rows of a table, not Vecs of single-row tables

* Remove more .transform()

* Simplify brush code

* Attempt to remove .transform() by using Instance<Image<Color>> in brush code, but a regression is introduced

* Improve blend_image_closure

* Simplify

* Remove leading underscore from type arguments

* Remove .transform() from ImageFrameTable<P> and fix Mask node behavior on stencils not fully overlapping its target image

* Remove more .one_instance_ref()

* Fully remove .one_instance_ref() and improve the 'Combine Channels' node robustness

* Fully remove .once_instance_mut()

* Fix tests

* Remove .one_empty_image()

* Make Instances<T>::default() return an empty table for images, but still not yet vector

---------

Co-authored-by: hypercube <0hypercube@gmail.com>
This commit is contained in:
Keavon Chambers 2025-06-04 20:40:15 -07:00 committed by GitHub
parent 76ecdc8f1b
commit cb4289169d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 882 additions and 811 deletions

View file

@ -9,6 +9,7 @@ use futures::Future;
use glam::{DAffine2, UVec2};
use gpu_executor::{ComputePassDimensions, GPUConstant, StorageBufferOptions, TextureBufferOptions, TextureBufferType, ToStorageBuffer, ToUniformBuffer};
use graphene_core::application_io::{ApplicationIo, EditorApi, ImageTexture, SurfaceHandle, TextureFrameTable};
use graphene_core::instances::Instance;
use graphene_core::raster::image::ImageFrameTable;
use graphene_core::raster::{Image, SRGBA8};
use graphene_core::transform::{Footprint, Transform};
@ -911,36 +912,32 @@ async fn render_texture<'a: 'n>(
#[node_macro::node(category(""))]
async fn upload_texture<'a: 'n>(_: impl ExtractFootprint + Ctx, input: ImageFrameTable<Color>, executor: &'a WgpuExecutor) -> TextureFrameTable {
// let new_data: Vec<RGBA16F> = input.image.data.into_iter().map(|c| c.into()).collect();
let image = input.one_instance_ref().instance;
let new_data: Vec<SRGBA8> = image.data.iter().map(|x| (*x).into()).collect();
let new_image = Image {
width: image.width,
height: image.height,
data: new_data,
base64_string: None,
};
let shader_input = executor.create_texture_buffer(new_image, TextureBufferOptions::Texture).unwrap();
let texture = match shader_input {
ShaderInput::TextureBuffer(buffer, _) => buffer,
ShaderInput::StorageTextureBuffer(buffer, _) => buffer,
_ => unreachable!("Unsupported ShaderInput type"),
};
let texture = ImageTexture {
texture: texture.into(),
// TODO: Find an alternate way to encode the transform and alpha_blend now that these fields have been moved up out of ImageTexture
// transform: input.transform,
// alpha_blend: Default::default(),
};
let mut result_table = TextureFrameTable::empty();
result_table.push(graphene_core::instances::Instance {
instance: texture,
transform: input.transform(),
alpha_blending: *input.one_instance_ref().alpha_blending,
source_node_id: *input.one_instance_ref().source_node_id,
});
for instance in input.instance_ref_iter() {
let image = instance.instance;
let new_data: Vec<SRGBA8> = image.data.iter().map(|x| (*x).into()).collect();
let new_image = Image {
width: image.width,
height: image.height,
data: new_data,
base64_string: None,
};
let shader_input = executor.create_texture_buffer(new_image, TextureBufferOptions::Texture).unwrap();
let texture = match shader_input {
ShaderInput::TextureBuffer(buffer, _) => buffer,
ShaderInput::StorageTextureBuffer(buffer, _) => buffer,
_ => unreachable!("Unsupported ShaderInput type"),
};
result_table.push(Instance {
instance: ImageTexture { texture: texture.into() },
transform: *instance.transform,
alpha_blending: *instance.alpha_blending,
source_node_id: *instance.source_node_id,
});
}
result_table
}