Skip to main content

impeller_hal_gles/
hal.rs

1//! The backend's implementation of the rendering HAL.
2
3use crate::context::GlesContext;
4use crate::render::GlesTexture;
5use impeller_hal::{
6    Batch, Capabilities, Extent2D, Hal, HalContext, HalTexture, PassDescriptor, PixelFormat,
7    Result, TextureDescriptor,
8};
9
10/// Marker naming the GLES backend's family of types.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct GlesHal;
13
14impl Hal for GlesHal {
15    type Context = GlesContext;
16    type Texture = GlesTexture;
17    /// A fence type exists to satisfy the trait, but nothing constructs one:
18    /// deferred submission is not implemented here, so the default returns
19    /// unsupported and this is never produced. Naming an uninhabited type is
20    /// more honest than naming one that could be built but never signals.
21    type Fence = crate::fence::GlesFence;
22
23    const NAME: &'static str = "gles";
24}
25
26impl HalTexture for GlesTexture {
27    fn extent(&self) -> Extent2D {
28        GlesTexture::extent(self)
29    }
30
31    fn format(&self) -> PixelFormat {
32        GlesTexture::format(self)
33    }
34}
35
36impl HalContext for GlesContext {
37    type Hal = GlesHal;
38
39    fn capabilities(&self) -> &Capabilities {
40        GlesContext::capabilities(self)
41    }
42
43    fn create_texture(&mut self, desc: &TextureDescriptor) -> Result<GlesTexture> {
44        GlesContext::create_texture(self, desc)
45    }
46
47    fn destroy_texture(&mut self, texture: GlesTexture) {
48        GlesContext::destroy_texture(self, texture)
49    }
50
51    fn register_program(&mut self, program: &impeller_hal::RuntimeProgram) -> Result<u32> {
52        GlesContext::register_program(self, program)
53    }
54
55    fn submit_batch(
56        &mut self,
57        target: &mut GlesTexture,
58        batch: &Batch,
59        pass: PassDescriptor,
60    ) -> Result<()> {
61        GlesContext::submit_batch(self, target, batch, pass)
62    }
63
64    fn submit_batch_textured(
65        &mut self,
66        target: &mut GlesTexture,
67        batch: &Batch,
68        pass: PassDescriptor,
69        textures: &[&GlesTexture],
70    ) -> Result<()> {
71        GlesContext::submit_batch_textured(self, target, batch, pass, textures)
72    }
73
74    /// Submit without waiting, handing back the fence the work signals.
75    ///
76    /// The rendering is the same call the waiting form makes; what differs is
77    /// what happens after it. A native fence is placed in the command stream
78    /// and then the stream is flushed, in that order and both of them
79    /// necessary: `eglCreateSync` marks a point in the stream rather than
80    /// submitting it, so a fence created and never flushed is one the driver
81    /// has not been told about and which therefore never signals. That failure
82    /// looks like a hang at the far end of a page flip rather than an error
83    /// here.
84    fn submit_batch_deferred_textured(
85        &mut self,
86        target: &mut GlesTexture,
87        batch: &Batch,
88        pass: PassDescriptor,
89        textures: &[&GlesTexture],
90    ) -> Result<crate::fence::GlesFence> {
91        GlesContext::submit_batch_textured(self, target, batch, pass, textures)?;
92        GlesContext::fence_after_submission(self)
93    }
94
95    fn read_texture(&mut self, texture: &mut GlesTexture) -> Result<Vec<u8>> {
96        GlesContext::read_texture(self, texture)
97    }
98
99    fn write_texture(&mut self, texture: &mut GlesTexture, pixels: &[u8]) -> Result<()> {
100        GlesContext::write_texture(self, texture, pixels)
101    }
102}