diff --git a/src/backend/renderer/element/texture.rs b/src/backend/renderer/element/texture.rs index 94abae1f3506..621c45048b61 100644 --- a/src/backend/renderer/element/texture.rs +++ b/src/backend/renderer/element/texture.rs @@ -627,7 +627,7 @@ pub struct TextureRenderElement { location: Point, id: Id, renderer_id: usize, - texture: T, + pub(crate) texture: T, scale: i32, transform: Transform, alpha: f32, diff --git a/src/backend/renderer/gles/element.rs b/src/backend/renderer/gles/element.rs index 3d0c1537694c..4885a0118678 100644 --- a/src/backend/renderer/gles/element.rs +++ b/src/backend/renderer/gles/element.rs @@ -2,13 +2,13 @@ use crate::{ backend::renderer::{ - element::{Element, Id, Kind, RenderElement, UnderlyingStorage}, - utils::{CommitCounter, OpaqueRegions}, + element::{texture::TextureRenderElement, Element, Id, Kind, RenderElement, UnderlyingStorage}, + utils::{CommitCounter, DamageSet, OpaqueRegions}, }, - utils::{Buffer, Logical, Physical, Rectangle, Scale, Transform}, + utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Transform}, }; -use super::{GlesError, GlesFrame, GlesPixelProgram, GlesRenderer, Uniform}; +use super::{GlesError, GlesFrame, GlesPixelProgram, GlesRenderer, GlesTexProgram, GlesTexture, Uniform}; /// Render element for drawing with a gles2 pixel shader #[derive(Debug, Clone)] @@ -129,3 +129,93 @@ impl RenderElement for PixelShaderElement { None } } + +#[derive(Debug)] +pub struct TextureShaderElement { + inner: TextureRenderElement, + program: GlesTexProgram, + id: Id, + additional_uniforms: Vec>, +} + +impl TextureShaderElement { + pub fn new( + inner: TextureRenderElement, + program: GlesTexProgram, + additional_uniforms: Vec>, + ) -> Self { + Self { + inner, + program, + id: Id::new(), + + additional_uniforms: additional_uniforms.into_iter().map(|u| u.into_owned()).collect(), + } + } +} + +impl Element for TextureShaderElement { + fn id(&self) -> &Id { + &self.id + } + + fn current_commit(&self) -> CommitCounter { + self.inner.current_commit() + } + + fn geometry(&self, scale: Scale) -> Rectangle { + self.inner.geometry(scale) + } + + fn transform(&self) -> Transform { + self.inner.transform() + } + + fn src(&self) -> Rectangle { + self.inner.src() + } + + fn damage_since(&self, scale: Scale, commit: Option) -> DamageSet { + self.inner.damage_since(scale, commit) + } + + fn opaque_regions(&self, scale: Scale) -> OpaqueRegions { + self.inner.opaque_regions(scale) + } + + fn alpha(&self) -> f32 { + self.inner.alpha() + } + + fn kind(&self) -> Kind { + self.inner.kind() + } + + fn location(&self, scale: Scale) -> Point { + self.inner.location(scale) + } +} + +impl RenderElement for TextureShaderElement { + #[profiling::function] + fn draw( + &self, + frame: &mut GlesFrame<'_>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + opaque_regions: &[Rectangle], + ) -> Result<(), GlesError> { + frame.render_texture_from_to( + &self.inner.texture, + src, + dst, + damage, + opaque_regions, + self.transform(), + self.alpha(), + Some(&self.program), + &self.additional_uniforms, + ) + } +} diff --git a/src/backend/renderer/glow.rs b/src/backend/renderer/glow.rs index cf30e6130226..3b1cd6bd0d5c 100644 --- a/src/backend/renderer/glow.rs +++ b/src/backend/renderer/glow.rs @@ -553,3 +553,21 @@ impl RenderElement for PixelShaderElement { RenderElement::::underlying_storage(self, renderer.borrow_mut()) } } + +impl RenderElement for TextureShaderElement { + #[profiling::function] + fn draw( + &self, + frame: &mut GlowFrame<'_>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + opaque_regions: &[Rectangle], + ) -> Result<(), GlesError> { + RenderElement::::draw(self, frame.borrow_mut(), src, dst, damage, opaque_regions) + } + + fn underlying_storage(&self, renderer: &mut GlowRenderer) -> Option> { + RenderElement::::underlying_storage(self, renderer.borrow_mut()) + } +}