tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

render_pass.rs (4341B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 //! FFI-friendly mirrors of render pass APIs in [`wgc`].
      6 
      7 use crate::id;
      8 
      9 /// FFI-friendly analogue of [`std::option::Option`].
     10 ///
     11 /// In some cases, Rust's standard `Option` type is FFI-friendly, in that `T` and `Option<T>` map
     12 /// to the same C++ type. For example, both `&U` and `Option<&U>` can be represented as `U *` in
     13 /// C++.
     14 ///
     15 /// For other types, `Option<T>` may not be FFI-safe. For such cases, this type is a `repr(u8)`
     16 /// analog to the standard
     17 ///
     18 /// See also: <https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization>
     19 #[repr(u8)]
     20 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
     21 pub enum FfiOption<T> {
     22    Some(T),
     23    None,
     24 }
     25 
     26 impl<T> FfiOption<T> {
     27    pub fn to_std(self) -> std::option::Option<T> {
     28        match self {
     29            Self::Some(value) => Some(value),
     30            Self::None => None,
     31        }
     32    }
     33 }
     34 
     35 /// FFI-safe analogue of [`wgc::command::RenderPassColorAttachment`].
     36 #[repr(C)]
     37 #[derive(Clone, Debug, PartialEq)]
     38 pub struct FfiRenderPassColorAttachment {
     39    pub view: id::TextureViewId,
     40    pub depth_slice: FfiOption<u32>,
     41    pub resolve_target: Option<id::TextureViewId>,
     42    pub load_op: wgc::command::LoadOp<wgt::Color>,
     43    pub store_op: wgc::command::StoreOp,
     44 }
     45 
     46 impl FfiRenderPassColorAttachment {
     47    pub(crate) fn to_wgpu(self) -> wgc::command::RenderPassColorAttachment {
     48        let Self {
     49            view,
     50            depth_slice,
     51            resolve_target,
     52            load_op,
     53            store_op,
     54        } = self;
     55 
     56        wgc::command::RenderPassColorAttachment {
     57            view,
     58            depth_slice: depth_slice.to_std(),
     59            resolve_target,
     60            load_op,
     61            store_op,
     62        }
     63    }
     64 }
     65 
     66 /// FFI-safe analogue of [`wgc::command::RenderPassDepthStencilAttachment`].
     67 #[repr(C)]
     68 #[derive(Clone, Debug, PartialEq)]
     69 pub struct RenderPassDepthStencilAttachment {
     70    pub view: id::TextureViewId,
     71    pub depth: PassChannel<FfiOption<f32>>,
     72    pub stencil: PassChannel<FfiOption<u32>>,
     73 }
     74 
     75 impl RenderPassDepthStencilAttachment {
     76    pub(crate) fn to_wgpu(
     77        self,
     78    ) -> wgc::command::RenderPassDepthStencilAttachment<id::TextureViewId> {
     79        let Self {
     80            view,
     81            depth,
     82            stencil,
     83        } = self;
     84 
     85        wgc::command::RenderPassDepthStencilAttachment {
     86            view,
     87            depth: depth.to_wgpu().map_clear_value(|opt| opt.to_std()),
     88            stencil: stencil.to_wgpu().map_clear_value(|opt| opt.to_std()),
     89        }
     90    }
     91 }
     92 
     93 /// FFI-safe analogue of [`wgc::command::PassChannel`].
     94 #[repr(C)]
     95 #[derive(Clone, Debug, PartialEq)]
     96 pub struct PassChannel<V> {
     97    pub load_op: FfiOption<wgc::command::LoadOp<V>>,
     98    pub store_op: FfiOption<wgc::command::StoreOp>,
     99    pub read_only: bool,
    100 }
    101 
    102 impl<V> PassChannel<V> {
    103    pub(crate) fn to_wgpu(self) -> wgc::command::PassChannel<V> {
    104        let Self {
    105            load_op,
    106            store_op,
    107            read_only,
    108        } = self;
    109 
    110        wgc::command::PassChannel {
    111            load_op: load_op.to_std(),
    112            store_op: store_op.to_std(),
    113            read_only,
    114        }
    115    }
    116 }
    117 
    118 trait MapClearValue<V1, V2> {
    119    type Converted;
    120 
    121    fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted;
    122 }
    123 
    124 impl<V1, V2> MapClearValue<V1, V2> for wgc::command::PassChannel<V1> {
    125    type Converted = wgc::command::PassChannel<V2>;
    126 
    127    fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted {
    128        let Self {
    129            load_op,
    130            store_op,
    131            read_only,
    132        } = self;
    133        wgc::command::PassChannel {
    134            load_op: load_op.map(|o| o.map_clear_value(f)),
    135            store_op,
    136            read_only,
    137        }
    138    }
    139 }
    140 
    141 impl<V1, V2> MapClearValue<V1, V2> for wgc::command::LoadOp<V1> {
    142    type Converted = wgc::command::LoadOp<V2>;
    143 
    144    fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted {
    145        match self {
    146            Self::Clear(value) => wgc::command::LoadOp::Clear(f(value)),
    147            Self::Load => wgc::command::LoadOp::Load,
    148            Self::DontCare(token) => wgc::command::LoadOp::DontCare(token),
    149        }
    150    }
    151 }