tor-browser

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

filterdata.rs (7808B)


      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 use std::hash;
      6 use crate::intern;
      7 use crate::renderer::{GpuBufferAddress, GpuBufferBuilderF, GpuBufferWriterF};
      8 use api::ComponentTransferFuncType;
      9 
     10 
     11 pub type FilterDataHandle = intern::Handle<FilterDataIntern>;
     12 
     13 #[derive(Debug, Clone, MallocSizeOf, PartialEq)]
     14 #[cfg_attr(feature = "capture", derive(Serialize))]
     15 #[cfg_attr(feature = "replay", derive(Deserialize))]
     16 pub enum SFilterDataComponent {
     17    Identity,
     18    Table(Vec<f32>),
     19    Discrete(Vec<f32>),
     20    Linear(f32, f32),
     21    Gamma(f32, f32, f32),
     22 }
     23 
     24 impl Eq for SFilterDataComponent {}
     25 
     26 impl hash::Hash for SFilterDataComponent {
     27    fn hash<H: hash::Hasher>(&self, state: &mut H) {
     28        match self {
     29            SFilterDataComponent::Identity => {
     30                0.hash(state);
     31            }
     32            SFilterDataComponent::Table(values) => {
     33                1.hash(state);
     34                values.len().hash(state);
     35                for val in values {
     36                    val.to_bits().hash(state);
     37                }
     38            }
     39            SFilterDataComponent::Discrete(values) => {
     40                2.hash(state);
     41                values.len().hash(state);
     42                for val in values {
     43                    val.to_bits().hash(state);
     44                }
     45            }
     46            SFilterDataComponent::Linear(a, b) => {
     47                3.hash(state);
     48                a.to_bits().hash(state);
     49                b.to_bits().hash(state);
     50            }
     51            SFilterDataComponent::Gamma(a, b, c) => {
     52                4.hash(state);
     53                a.to_bits().hash(state);
     54                b.to_bits().hash(state);
     55                c.to_bits().hash(state);
     56            }
     57        }
     58    }
     59 }
     60 
     61 impl SFilterDataComponent {
     62    pub fn to_int(&self) -> u32 {
     63        match self {
     64            SFilterDataComponent::Identity => 0,
     65            SFilterDataComponent::Table(_) => 1,
     66            SFilterDataComponent::Discrete(_) => 2,
     67            SFilterDataComponent::Linear(_, _) => 3,
     68            SFilterDataComponent::Gamma(_, _, _) => 4,
     69        }
     70    }
     71 
     72    pub fn from_functype_values(
     73        func_type: ComponentTransferFuncType,
     74        values: &[f32],
     75    ) -> SFilterDataComponent {
     76        match func_type {
     77            ComponentTransferFuncType::Identity => SFilterDataComponent::Identity,
     78            ComponentTransferFuncType::Table => SFilterDataComponent::Table(values.to_vec()),
     79            ComponentTransferFuncType::Discrete => SFilterDataComponent::Discrete(values.to_vec()),
     80            ComponentTransferFuncType::Linear => SFilterDataComponent::Linear(values[0], values[1]),
     81            ComponentTransferFuncType::Gamma => SFilterDataComponent::Gamma(values[0], values[1], values[2]),
     82        }
     83    }
     84 }
     85 
     86 #[derive(Debug, Clone, MallocSizeOf, PartialEq, Eq, Hash)]
     87 #[cfg_attr(feature = "capture", derive(Serialize))]
     88 #[cfg_attr(feature = "replay", derive(Deserialize))]
     89 pub struct SFilterData {
     90    pub r_func: SFilterDataComponent,
     91    pub g_func: SFilterDataComponent,
     92    pub b_func: SFilterDataComponent,
     93    pub a_func: SFilterDataComponent,
     94 }
     95 
     96 #[derive(Debug, Clone, MallocSizeOf, PartialEq, Eq, Hash)]
     97 #[cfg_attr(feature = "capture", derive(Serialize))]
     98 #[cfg_attr(feature = "replay", derive(Deserialize))]
     99 pub struct SFilterDataKey {
    100    pub data: SFilterData,
    101 }
    102 
    103 impl intern::InternDebug for SFilterDataKey {}
    104 
    105 #[derive(Debug)]
    106 #[cfg_attr(feature = "capture", derive(Serialize))]
    107 #[cfg_attr(feature = "replay", derive(Deserialize))]
    108 #[derive(MallocSizeOf)]
    109 pub struct SFilterDataTemplate {
    110    pub data: SFilterData,
    111    pub gpu_buffer_address: GpuBufferAddress,
    112 }
    113 
    114 impl From<SFilterDataKey> for SFilterDataTemplate {
    115    fn from(item: SFilterDataKey) -> Self {
    116        SFilterDataTemplate {
    117            data: item.data,
    118            gpu_buffer_address: GpuBufferAddress::INVALID,
    119        }
    120    }
    121 }
    122 
    123 impl SFilterData {
    124    pub fn is_identity(&self) -> bool {
    125        self.r_func == SFilterDataComponent::Identity
    126            && self.g_func == SFilterDataComponent::Identity
    127            && self.b_func == SFilterDataComponent::Identity
    128            && self.a_func == SFilterDataComponent::Identity
    129    }
    130 
    131    pub fn write_gpu_blocks(&self, gpu_buffer: &mut GpuBufferBuilderF) -> GpuBufferAddress {
    132        assert!(!self.is_identity());
    133        let mut writer = gpu_buffer.write_blocks(1024);
    134        push_component_transfer_data(&self.r_func, &mut writer);
    135        push_component_transfer_data(&self.g_func, &mut writer);
    136        push_component_transfer_data(&self.b_func, &mut writer);
    137        push_component_transfer_data(&self.a_func, &mut writer);
    138        writer.finish()
    139    }
    140 }
    141 
    142 impl SFilterDataTemplate {
    143    /// Update the GPU cache for a given filter data template. This may be called multiple
    144    /// times per frame, by each primitive reference that refers to this interned
    145    /// template. The initial request call to the GPU cache ensures that work is only
    146    /// done if the cache entry is invalid (due to first use or eviction).
    147    pub fn write_gpu_blocks(
    148        &mut self,
    149        gpu_buffer: &mut GpuBufferBuilderF,
    150    ) {
    151        self.gpu_buffer_address = self.data.write_gpu_blocks(gpu_buffer);
    152    }
    153 }
    154 
    155 #[derive(Copy, Clone, Debug, MallocSizeOf)]
    156 #[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
    157 pub enum FilterDataIntern {}
    158 
    159 impl intern::Internable for FilterDataIntern {
    160    type Key = SFilterDataKey;
    161    type StoreData = SFilterDataTemplate;
    162    type InternData = ();
    163    const PROFILE_COUNTER: usize = crate::profiler::INTERNED_FILTER_DATA;
    164 }
    165 
    166 fn push_component_transfer_data(
    167    func_comp: &SFilterDataComponent,
    168    writer: &mut GpuBufferWriterF,
    169 ) {
    170    match func_comp {
    171        SFilterDataComponent::Identity => {}
    172        SFilterDataComponent::Table(values) |
    173        SFilterDataComponent::Discrete(values) => {
    174            // Push a 256 entry lookup table.
    175            assert!(values.len() > 0);
    176            for i in 0 .. 64 {
    177                let mut arr = [0.0 ; 4];
    178                for j in 0 .. 4 {
    179                    if (values.len() == 1) || (i == 63 && j == 3) {
    180                        arr[j] = values[values.len()-1];
    181                    } else {
    182                        let c = ((4*i + j) as f32)/255.0;
    183                        match func_comp {
    184                            SFilterDataComponent::Table(_) => {
    185                                let n = (values.len()-1) as f32;
    186                                let k = (n * c).floor() as u32;
    187                                let ku = k as usize;
    188                                assert!(ku < values.len()-1);
    189                                arr[j] = values[ku] + (c*n - (k as f32)) * (values[ku+1] - values[ku]);
    190                            }
    191                            SFilterDataComponent::Discrete(_) => {
    192                                let n = values.len() as f32;
    193                                let k = (n * c).floor() as usize;
    194                                assert!(k < values.len());
    195                                arr[j] = values[k];
    196                            }
    197                            SFilterDataComponent::Identity |
    198                            SFilterDataComponent::Linear(_,_) |
    199                            SFilterDataComponent::Gamma(_,_,_) => {
    200                                unreachable!();
    201                            }
    202                        }
    203 
    204                    }
    205                }
    206 
    207                writer.push_one(arr);
    208            }
    209        }
    210        SFilterDataComponent::Linear(a, b) => {
    211            writer.push_one([*a, *b, 0.0, 0.0]);
    212        }
    213        SFilterDataComponent::Gamma(a, b, c) => {
    214            writer.push_one([*a, *b, *c, 0.0]);
    215        }
    216    }
    217 }