Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  capture.rs   Sprache: unbekannt

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::fs::File;
use std::path::{Path, PathBuf};

use api::{ExternalImageData, ImageDescriptor};
#[cfg(feature = "png")]
use api::ImageFormat;
use api::units::TexelRect;
#[cfg(feature = "png")]
use api::units::DeviceIntSize;
#[cfg(feature = "capture")]
use crate::print_tree::{PrintableTree, PrintTree};
use crate::render_api::CaptureBits;


#[derive(Clone)]
pub struct CaptureConfig {
    pub root: PathBuf,
    pub bits: CaptureBits,
    /// Scene sequence ID when capturing multiple frames. Zero for a single frame capture.
    pub scene_id: u32,
    /// Frame sequence ID when capturing multiple frames. Zero for a single frame capture.
    pub frame_id: u32,
    /// Resource sequence ID when capturing multiple frames. Zero for a single frame capture.
    pub resource_id: u32,
    #[cfg(feature = "capture")]
    pretty: ron::ser::PrettyConfig,
}

impl CaptureConfig {
    #[cfg(any(feature = "capture", feature = "replay"))]
    pub fn new(root: PathBuf, bits: CaptureBits) -> Self {
        CaptureConfig {
            root,
            bits,
            scene_id: 0,
            frame_id: 0,
            resource_id: 0,
            #[cfg(feature = "capture")]
            pretty: ron::ser::PrettyConfig::new()
                .enumerate_arrays(true)
                .indentor(" ".to_string()),
        }
    }

    #[cfg(feature = "capture")]
    pub fn prepare_scene(&mut self) {
        use std::fs::create_dir_all;
        self.scene_id += 1;
        let _ = create_dir_all(&self.scene_root());
    }

    #[cfg(feature = "capture")]
    pub fn prepare_frame(&mut self) {
        use std::fs::create_dir_all;
        self.frame_id += 1;
        let _ = create_dir_all(&self.frame_root());
    }

    #[cfg(feature = "capture")]
    pub fn prepare_resource(&mut self) {
        use std::fs::create_dir_all;
        self.resource_id += 1;
        let _ = create_dir_all(&self.resource_root());
    }

    #[cfg(any(feature = "capture", feature = "replay"))]
    pub fn scene_root(&self) -> PathBuf {
        if self.scene_id > 0 {
            let path = format!("scenes/{:05}", self.scene_id);
            self.root.join(path)
        } else {
            self.root.clone()
        }
    }

    #[cfg(any(feature = "capture", feature = "replay"))]
    pub fn frame_root(&self) -> PathBuf {
        if self.frame_id > 0 {
            let path = format!("frames/{:05}", self.frame_id);
            self.scene_root().join(path)
        } else {
            self.root.clone()
        }
    }

    #[cfg(any(feature = "capture", feature = "replay"))]
    pub fn resource_root(&self) -> PathBuf {
        if self.resource_id > 0 {
            let path = format!("resources/{:05}", self.resource_id);
            self.root.join(path)
        } else {
            self.root.clone()
        }
    }

    #[cfg(feature = "capture")]
    pub fn serialize_for_scene<T, P>(&self, data: &T, name: P)
    where
        T: serde::Serialize,
        P: AsRef<Path>,
    {
        self.serialize(data, self.scene_root(), name)
    }

    #[cfg(feature = "capture")]
    pub fn serialize_for_frame<T, P>(&self, data: &T, name: P)
    where
        T: serde::Serialize,
        P: AsRef<Path>,
    {
        self.serialize(data, self.frame_root(), name)
    }

    #[cfg(feature = "capture")]
    pub fn serialize_for_resource<T, P>(&self, data: &T, name: P)
    where
        T: serde::Serialize,
        P: AsRef<Path>,
    {
        self.serialize(data, self.resource_root(), name)
    }

    #[cfg(feature = "capture")]
    pub fn file_path_for_frame<P>(&self, name: P, ext: &str) -> PathBuf
    where P: AsRef<Path> {
        self.frame_root().join(name).with_extension(ext)
    }

    #[cfg(feature = "capture")]
    fn serialize<T, P>(&self, data: &T, path: PathBuf, name: P)
    where
        T: serde::Serialize,
        P: AsRef<Path>,
    {
        use std::io::Write;
        let ron = ron::ser::to_string_pretty(data, self.pretty.clone())
            .unwrap();
        let mut file = File::create(path.join(name).with_extension("ron"))
            .unwrap();
        write!(file, "{}\n", ron)
            .unwrap();
    }

    #[cfg(feature = "capture")]
    fn serialize_tree<T, P>(data: &T, root: PathBuf, name: P)
    where
        T: PrintableTree,
        P: AsRef<Path>
    {
        let path = root
            .join(name)
            .with_extension("tree");
        let file = File::create(path)
            .unwrap();
        let mut pt = PrintTree::new_with_sink("", file);
        data.print_with(&mut pt);
    }

    #[cfg(feature = "capture")]
    pub fn serialize_tree_for_frame<T, P>(&self, data: &T, name: P)
    where
        T: PrintableTree,
        P: AsRef<Path>
    {
        Self::serialize_tree(data, self.frame_root(), name)
    }

    #[cfg(feature = "replay")]
    fn deserialize<T, P>(root: &PathBuf, name: P) -> Option<T>
    where
        T: for<'a> serde::Deserialize<'a>,
        P: AsRef<Path>,
    {
        use std::io::Read;

        let mut string = String::new();
        let path = root
            .join(name.as_ref())
            .with_extension("ron");
        File::open(path)
            .ok()?
            .read_to_string(&mut string)
            .unwrap();
        match ron::de::from_str(&string) {
            Ok(out) => Some(out),
            Err(e) => panic!("File {:?} deserialization failed: {:?}", name.as_ref(), e),
        }
    }

    #[cfg(feature = "replay")]
    pub fn deserialize_for_scene<T, P>(&self, name: P) -> Option<T>
    where
        T: for<'a> serde::Deserialize<'a>,
        P: AsRef<Path>,
    {
        Self::deserialize(&self.scene_root(), name)
    }

    #[cfg(feature = "replay")]
    pub fn deserialize_for_frame<T, P>(&self, name: P) -> Option<T>
    where
        T: for<'a> serde::Deserialize<'a>,
        P: AsRef<Path>,
    {
        Self::deserialize(&self.frame_root(), name)
    }

    #[cfg(feature = "replay")]
    pub fn deserialize_for_resource<T, P>(&self, name: P) -> Option<T>
    where
        T: for<'a> serde::Deserialize<'a>,
        P: AsRef<Path>,
    {
        Self::deserialize(&self.resource_root(), name)
    }

    #[cfg(feature = "png")]
    pub fn save_png(
        path: PathBuf, size: DeviceIntSize, format: ImageFormat, stride: Option<i32>, data: &[u8],
    ) {
        use png::{BitDepth, ColorType, Encoder};
        use std::io::BufWriter;
        use std::borrow::Cow;

        // `png` expects
        let data = match stride {
            Some(stride) if stride != format.bytes_per_pixel() * size.width => {
                let mut unstrided = Vec::new();
                for y in 0..size.height {
                    let start = (y * stride) as usize;
                    unstrided.extend_from_slice(&data[start..start+(size.width * format.bytes_per_pixel()) as usize]);
                }
                Cow::from(unstrided)
            }
            _ => Cow::from(data),
        };

        let color_type = match format {
            ImageFormat::RGBA8 => ColorType::RGBA,
            ImageFormat::BGRA8 => {
                warn!("Unable to swizzle PNG of BGRA8 type");
                ColorType::RGBA
            },
            ImageFormat::R8 => ColorType::Grayscale,
            ImageFormat::RG8 => ColorType::GrayscaleAlpha,
            _ => {
                error!("Unable to save PNG of {:?}", format);
                return;
            }
        };
        let w = BufWriter::new(File::create(path).unwrap());
        let mut enc = Encoder::new(w, size.width as u32, size.height as u32);
        enc.set_color(color_type);
        enc.set_depth(BitDepth::Eight);
        enc
            .write_header()
            .unwrap()
            .write_image_data(&*data)
            .unwrap();
    }
}

/// An image that `ResourceCache` is unable to resolve during a capture.
/// The image has to be transferred to `Renderer` and locked with the
/// external image handler to get the actual contents and serialize them.
#[derive(Deserialize, Serialize)]
pub struct ExternalCaptureImage {
    pub short_path: String,
    pub descriptor: ImageDescriptor,
    pub external: ExternalImageData,
}

/// A short description of an external image to be saved separately as
/// "externals/XX.ron", redirecting into a specific texture/blob with
/// the corresponding UV rectangle.
#[derive(Deserialize, Serialize)]
pub struct PlainExternalImage {
    /// Path to the RON file describing the texel data.
    pub data: String,
    /// External image data source.
    pub external: ExternalImageData,
    /// UV sub-rectangle of the image.
    pub uv: TexelRect,
}

[ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge