Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TargetPixelBuffer functions being called with regions not clipped… #7794

Merged
merged 7 commits into from
Mar 31, 2025
75 changes: 40 additions & 35 deletions internal/core/software_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,28 +1180,33 @@ impl<B: target_pixel_buffer::TargetPixelBuffer> RenderToBuffer<'_, B> {
}

fn process_texture_impl(&mut self, geometry: PhysicalRect, texture: SceneTexture<'_>) {
if !self.buffer.draw_texture(
geometry.origin.x,
geometry.origin.y,
geometry.size.width,
geometry.size.height,
target_pixel_buffer::Texture {
bytes: texture.data,
pixel_format: texture.format,
pixel_stride: texture.pixel_stride,
width: texture.source_size().width as u16,
height: texture.source_size().height as u16,
delta_x: texture.extra.dx.0,
delta_y: texture.extra.dy.0,
source_offset_x: texture.extra.off_x.0,
source_offset_y: texture.extra.off_y.0,
},
texture.extra.colorize.as_argb_encoded(),
texture.extra.alpha,
texture.extra.rotation,
CompositionMode::default(),
) {
self.foreach_region(&geometry, |buffer, rect, extra_left_clip, extra_right_clip| {
self.foreach_region(&geometry, |buffer, rect, extra_left_clip, extra_right_clip| {
let tex_src_off_x = (texture.extra.off_x + Fixed::from_integer(extra_left_clip as u16))
* Fixed::from_fixed(texture.extra.dx);
let tex_src_off_y = (texture.extra.off_y
+ Fixed::from_integer((rect.origin.y - geometry.origin.y) as u16))
* Fixed::from_fixed(texture.extra.dy);
if !buffer.draw_texture(
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height,
target_pixel_buffer::Texture {
bytes: texture.data,
pixel_format: texture.format,
pixel_stride: texture.pixel_stride,
width: texture.source_size().width as u16,
height: texture.source_size().height as u16,
delta_x: texture.extra.dx.0,
delta_y: texture.extra.dy.0,
source_offset_x: tex_src_off_x.0,
source_offset_y: tex_src_off_y.0,
},
texture.extra.colorize.as_argb_encoded(),
texture.extra.alpha,
texture.extra.rotation,
CompositionMode::default(),
) {
let begin = rect.min_x();
let end = rect.max_x();
for l in rect.y_range() {
Expand All @@ -1214,8 +1219,8 @@ impl<B: target_pixel_buffer::TargetPixelBuffer> RenderToBuffer<'_, B> {
extra_right_clip,
);
}
});
}
}
});
}

fn process_rectangle_impl(
Expand All @@ -1224,15 +1229,15 @@ impl<B: target_pixel_buffer::TargetPixelBuffer> RenderToBuffer<'_, B> {
color: PremultipliedRgbaColor,
composition_mode: CompositionMode,
) {
if !self.buffer.fill_rectangle(
geometry.origin.x,
geometry.origin.y,
geometry.size.width,
geometry.size.height,
color,
composition_mode,
) {
self.foreach_region(&geometry, |buffer, rect, _extra_left_clip, _extra_right_clip| {
self.foreach_region(&geometry, |buffer, rect, _extra_left_clip, _extra_right_clip| {
if !buffer.fill_rectangle(
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height,
color,
composition_mode,
) {
let begin = rect.min_x();
let end = rect.max_x();

Expand All @@ -1254,8 +1259,8 @@ impl<B: target_pixel_buffer::TargetPixelBuffer> RenderToBuffer<'_, B> {
}
}
}
})
};
}
})
}
}

Expand Down
14 changes: 14 additions & 0 deletions internal/core/software_renderer/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,20 @@ impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<T> for Fi
}
}

impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<Fixed<T, SHIFT>>
for Fixed<T, SHIFT>
where
T: TryFrom<i64> + Into<i64>,
<T as TryFrom<i64>>::Error: core::fmt::Debug,
{
type Output = Self;
fn mul(self, rhs: Fixed<T, SHIFT>) -> Self::Output {
let lhs_i64: i64 = self.0.into();
let rhs_i64: i64 = rhs.0.into();
Self(T::try_from((lhs_i64 * rhs_i64) >> SHIFT).expect("attempt to multiply with overflow"))
}
}

impl<T: core::ops::Neg<Output = T>, const SHIFT: usize> core::ops::Neg for Fixed<T, SHIFT> {
type Output = Self;
fn neg(self) -> Self::Output {
Expand Down
Loading