tracy_full 1.2.1

Fully featured bindings for the Tracy profiler
Documentation
Complete Rust bindings for the [Tracy](https://github.com/wolfpld/tracy) profiler.

## Getting Started


Just add the following to your `Cargo.toml`:
```toml
[dependencies.tracy]
package = "tracy_full"
version = "1.0.0"
```

To enable profiling for a build, add the `enable` feature:
```toml
[dependencies.tracy]
...
features = ["enable"]
```

## Features


### Allocation Tracking

```rust
#[global_allocator]

static ALLOC: tracy::GlobalAllocator = tracy::GlobalAllocator::new();
```
This tracks all allocations, using the default `System` allocator for allocations.

For a custom allocator:
```rust
#[global_allocator]

static ALLOC: tracy::GlobalAllocator<MyAlloc> = tracy::GlobalAllocator::new_with(MyAlloc::new());
```

Tracy also supports tracking custom allocators using the `allocator_api` feature:
```toml
[dependencies.tracy]
...
features = ["allocator_api"]
```
```rust
let alloc = TrackedAllocator::new(alloc, tracy::c_str!("TrackedAllocator"));
```
This creates a memory pool named `TrackedAllocator` in Tracy.

All the allocators have a `*Sampled` variant that samples the callstack on each allocation.

### Frame Marks

Mark the end of the main frame using:
```rust
use tracy::frame;

frame!();
```

Mark the end of a sub-frame using:
```rust
frame!("Name");
```

Mark the scope of a discontinuous frame using:
```rust
frame!(discontinuous "Name");
```

#### The difference between frame types

The main frame what is usually thought of as a 'frame'. 
It is usually placed after the swapchain present call on the main thread.

Sub-frames are parts of the main frame, for example, input gathering, physics, and rendering:
```rust
loop {
    // Gather input
    frame!("Input");
    // Process input
    frame!("Processing");
    // Render
    frame!("Render");

    swapchain.present();
    frame!();
}
```

Discontinuous frames are frames that are not in sync with the frame on the main thread.
This can be things like async asset loading on different threads.

### Plotting

You can plot graphs in Tracy:
```rust
use tracy::plotter;

let plotter = plotter!("MyGraph");
plotter.value(1.0);
plotter.value(2.0);
```

### Zones

```rust
use tracy::zone;

zone!(); // Zone with no name
zone!("MyZone"); // Zone with name "MyZone"
zone!(tracy::color::RED); // Zone with color red
zone!("MyZone", true); // Zone with name "MyZone", and enabled with a runtime expression.
zone!(tracy::color::RED, true); // Zone with color red, and enabled with a runtime expression.
zone!("MyZone", tracy::color::RED, true); // Zone with name "MyZone", color red, and enabled with a runtime expression.
```
All zones profile from creation to the end of the enclosed scope.

## Extra features


### Future support

Futures can be represented as fibers in Tracy. The `futures` feature must be enabled.

```toml
[dependencies.tracy]
...
features = ["enable", "futures"]
```
```rust
use tracy::future;

trace_future!(async_function(), "Async Function").await;
```

### Unstable

The `unstable` feature allows for optimizations that require a nightly compiler.

```toml
[dependencies.tracy]
...
features = ["enable", "unstable"]
```

## External Library Integration


### `bevy`

Enable the `bevy` feature to be able to profile Bevy systems.
```toml
[dependencies.tracy]
...
features = ["enable", "bevy"]
```

```rust
use tracy::bevy::timeline;

App::new().add_system(timeline(my_system)).run();
```

This creates a separate fiber for the system in the tracy timeline.

### `tracing`

Enable the `tracing` feature to be able to profile tracing spans.
```toml
[dependencies.tracy]
...
features = ["enable", "tracing"]
```

```rust
use tracy::tracing::TracyLayer;

tracing::subscriber::set_global_default(
    tracing_subscriber::registry().with(TracyLayer)
);
```
Extra data on spans are currently unsupported.

### `wgpu`

Enable the `wgpu` feature to be able to profile wgpu command encoders and render/compute passes.
```toml
[dependencies.tracy]
...
features = ["enable", "wgpu"]
```

```rust
use tracy::wgpu::ProfileContext;

let mut profile_context = ProfileContext::with_name("Name", &adapter, &device, &queue, buffered_frames);
```
`buffered_frames`: the number of frames of profiling data you want the profiler to buffer. 
Note that you must synchronize the host and device accordingly, or else the call to `end_frame` will panic.

You also need to have one `ProfileContext` per host thread.

You can create a profiled command encoder:
```rust
use tracy::{wgpu_command_encoder, wgpu_render_pass, wgpu_compute_pass};

let mut command_encoder = wgpu_command_encoder!(device, profile_context, desc);
{
    let render_pass = wgpu_render_pass!(command_encoder, desc)
}

{
    let compute_pass = wgpu_compute_pass!(command_encoder, desc)
}
```

At the end of each frame, you must call `end_frame`:
```rust
profile_context.end_frame(&device, &queue);
```
This uploads the profiling data to the Tracy.