Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::render Namespace Reference

Namespaces

namespace  bench
namespace  detail

Classes

struct  AtlasInfo
 A value-snapshot of one texture atlas's state, taken at a known point. More...
class  AtlasInventory
 A read-only collection of atlas snapshots for the inspector. More...
class  DirtyTracker
 Tracks rectangular regions that need repainting. More...
struct  DecodedMesh
 Decoded mesh geometry from DRACO-compressed data. More...
struct  DracoAttributeIds
 Draco attribute unique IDs from a glTF KHR_draco_mesh_compression attributes map. More...
struct  GpuDeviceFeatures
 Optional device features that change what a format can do. More...
struct  GpuFormatSupport
 What one format supports on a device. More...
struct  GpuDeviceFacts
 The facts pick_tier() reads. A test can build one by hand. More...
struct  GpuDeviceCapabilities
 Rendering capabilities of the shared device. More...
class  GpuCompute
 GPU compute pipeline for non-rendering workloads (e.g. More...
struct  GpuDiagnosticsStats
 Counters that separate "the sink was never called" from "the sink was called but this build compiles the trace macros out". More...
struct  SkiaLogBridgeState
class  LogTextBudget
 A thread-safe "first N" budget: admit() returns true for the first limit calls and false afterwards, counting both. More...
struct  GpuError
struct  GpuTextureDesc
class  GpuTexture
struct  GpuBufferDesc
class  GpuBuffer
struct  GpuSamplerDesc
class  GpuSampler
class  GpuShaderModule
 A compiled WGSL module. More...
struct  GpuVertexAttribute
struct  GpuVertexBufferLayout
struct  GpuColorTargetDesc
struct  GpuDepthStateDesc
struct  GpuRenderPipelineDesc
class  GpuRenderPipeline
struct  GpuComputePipelineDesc
class  GpuComputePipeline
struct  GpuBinding
 One entry of a bind group: a buffer range, a texture or a sampler. More...
class  GpuBindGroup
struct  GpuTargetDesc
struct  GpuPixels
 Tightly packed pixels read back from a target, rows top to bottom. More...
class  GpuTarget
 Offscreen color target (and optional depth) with CPU readback. More...
class  GpuDevice
 Typed handle to the device a GpuSurface owns. Copies share it. More...
struct  GpuColorAttachment
struct  GpuRenderPassDesc
class  GpuRenderPass
 An open render pass. More...
class  GpuComputePass
 An open compute pass. Same rules as GpuRenderPass. More...
class  GpuSubmission
 Completion of one submitted frame. More...
class  GpuFrame
 One command encoder's worth of passes, submitted once. More...
struct  DawnProcInstaller
 A host-supplied installer for Dawn's process-global proc table. More...
class  GpuRenderTimeTracker
 Thread-safe holder for the latest GPU render-time sample. More...
class  GpuFramesInFlight
 Frames whose GPU work has been submitted but has not finished executing. More...
struct  GpuStartupReport
 Bring-up stage timings from GpuSurface::initialize() plus the two stages the owning host measures around it. More...
class  SwapchainResizeState
 Decides when a presentable swapchain has to be (re)configured. More...
class  GpuSurface
 Abstract GPU surface — a presentable rendering target backed by a native window/view. More...
class  HeadlessSurface
 One-call wrapper for the existing offscreen Dawn + Skia path (GpuSurface::create_dawn() + native_surface_handle=nullptr + SkiaSurface::create). More...
struct  DecodedTexture
 Parsed texture data from a KTX2 container. More...
class  DisplayRateBoost
class  RenderLoop
struct  PassStats
 Statistics for a single render pass. More...
class  RenderPassManager
 Frame-level render pass manager. More...
struct  HardcodedCubeRenderConfig
struct  Scene3DRenderResult
struct  SceneDataRenderConfig
class  Renderer3D
struct  Sdl3SurfaceInfo
struct  GpuCacheBytes
 GPU bytes held by a surface's Skia resource caches. More...
class  GpuIdleTrimSchedule
 When a surface's idle trim runs. More...
class  SkiaSurface
 Skia Graphite rendering surface. More...
struct  SkpCaptureResult
 Outcome of a .skp capture attempt. More...
class  SkpFrameCapture
 Records a single frame's draw ops into an SkPicture and serializes it to a .skp artifact. More...
class  AtlasPacker
 Simple rectangle packer for atlas allocation. More...
class  ImageAtlas
 Image atlas — packs small images into a shared GPU texture. More...
class  GradientAtlas
 Gradient atlas — caches evaluated gradient ramps as GPU textures. More...
class  GlyphAtlas
 Glyph atlas — per-font-size glyph cache as GPU texture. More...
class  PathAtlas
 Path atlas — caches rasterized vector paths (e.g., complex SVG icons). More...
class  BufferPool
 Buffer pool — reuses std::vector allocations in hot rendering paths. More...
struct  WgslDiagnostic

Typedefs

template<typename T>
using GpuResult = runtime::Result<T, GpuError>
using GpuStatus = runtime::Result<void, GpuError>
 Success is a default-constructed value.
using FrameCallback = std::function<void()>
using HardcodedCubeRenderResult = Scene3DRenderResult
using SceneDataRenderResult = Scene3DRenderResult

Enumerations

enum class  AtlasKind { glyph , image , gradient , path }
 Which kind of atlas an AtlasInfo describes. More...
enum class  GpuFormat : std::uint8_t {
  undefined , r8_unorm , rg8_unorm , rgba8_unorm ,
  rgba8_unorm_srgb , bgra8_unorm , bgra8_unorm_srgb , rgb10a2_unorm ,
  rg11b10_ufloat , r16_float , rg16_float , rgba16_float ,
  r32_float , rg32_float , rgba32_float , r32_uint ,
  rgba8_uint , depth16_unorm , depth24_plus , depth24_plus_stencil8 ,
  depth32_float
}
 Texture formats the typed GPU API accepts. More...
enum class  GpuAdapterKind : std::uint8_t { unknown , integrated , discrete , cpu }
 Adapter class as Dawn reports it. More...
enum class  GpuRenderTier : std::uint8_t { none , basic , standard , high }
 Coarse rendering tier for choosing a visual path. More...
enum class  GpuDiagnosticSeverity { info , warning , error , fatal }
 Severity of one GPU diagnostic record. More...
enum class  SkiaLogBridgeStatus {
  not_attempted , installed , declined_handler_present , declined_not_enabled ,
  unavailable_no_skia
}
 Outcome of trying to route Skia's process-global log handler into the sink. More...
enum class  GpuTextureUsage : std::uint32_t {
  none = 0 , copy_src = 1u << 0 , copy_dst = 1u << 1 , sampled = 1u << 2 ,
  storage = 1u << 3 , render_target = 1u << 4
}
 Texture usage bits. Values match WebGPU's GPUTextureUsage. More...
enum class  GpuBufferUsage : std::uint32_t {
  none = 0 , map_read = 1u << 0 , map_write = 1u << 1 , copy_src = 1u << 2 ,
  copy_dst = 1u << 3 , index = 1u << 4 , vertex = 1u << 5 , uniform = 1u << 6 ,
  storage = 1u << 7
}
 Buffer usage bits. Values match WebGPU's GPUBufferUsage. More...
enum class  GpuVertexFormat : std::uint8_t {
  float32 , float32x2 , float32x3 , float32x4 ,
  uint32 , sint32 , unorm8x4
}
enum class  GpuBlend : std::uint8_t { replace , alpha , premultiplied , additive }
enum class  GpuPrimitiveTopology : std::uint8_t {
  triangle_list , triangle_strip , line_list , line_strip ,
  point_list
}
enum class  GpuCullMode : std::uint8_t { none , front , back }
enum class  GpuCompare : std::uint8_t {
  never , less , less_equal , greater ,
  greater_equal , equal , not_equal , always
}
enum class  GpuSubmissionStatus : std::uint8_t { pending , succeeded , failed }
enum class  RenderLoopBackend {
  cv_display_link , ca_display_link , choreographer , dwm_flush ,
  raf , timer
}
 Which concrete backend RenderLoop::create() selected. More...
enum class  RenderPassType {
  background , content , effects , overlay ,
  post_effects
}
 Defines the ordering of render passes in a frame. More...
enum class  Renderer3DAdapterBackendPreference { default_backend , null_backend , vulkan , d3d12 }
enum class  FrameOutcome { presented , offscreen , recreate , failed }
 Where a frame actually ended up. More...

Functions

const char * atlas_kind_name (AtlasKind kind)
 Human-readable name for an AtlasKind — used by the inspector panel and by tests.
DecodedMesh decode_draco (const uint8_t *data, size_t size)
 Decode a DRACO-compressed mesh buffer.
DecodedMesh decode_draco (const uint8_t *data, size_t size, const DracoAttributeIds &attribute_ids)
 Decode a DRACO-compressed mesh buffer using glTF semantic -> Draco unique-id mappings.
bool draco_decoder_available ()
 True when this build was compiled with the native DRACO decoder enabled.
const std::vector< GpuFormat > & all_gpu_formats ()
 Every format above except undefined, in declaration order.
std::string_view gpu_format_name (GpuFormat format)
 WebGPU spelling of a format ("rgba8unorm"), or "undefined".
std::uint32_t gpu_format_bytes_per_pixel (GpuFormat format)
 Bytes per texel for color formats, 0 for depth/stencil and undefined (depth texels have no defined CPU layout and cannot be read back).
bool gpu_format_is_depth (GpuFormat format)
 True for depth and depth/stencil formats.
GpuFormatSupport gpu_format_support (GpuFormat format, const GpuDeviceFeatures &features)
 The WebGPU format table for format, adjusted for features. Pure.
void fill_format_table (GpuDeviceCapabilities &caps)
 Fill the format table of caps from caps.facts.features. Pure.
std::string_view gpu_render_tier_name (GpuRenderTier tier)
GpuRenderTier pick_tier (const GpuDeviceFacts &facts)
 Pure: the same facts always give the same tier.
const char * to_string (GpuDiagnosticSeverity severity) noexcept
 Stable lowercase label for a severity, suitable as a trace annotation value.
void emit_gpu_diagnostic (GpuDiagnosticSeverity severity, const char *source, std::string_view message) noexcept
 Publish one GPU diagnostic as a gpu-category instant event.
GpuDiagnosticsStats gpu_diagnostics_stats () noexcept
const char * to_string (SkiaLogBridgeStatus status) noexcept
 Stable lowercase label for a bridge status, suitable for status output.
SkiaLogBridgeState skia_log_bridge_state () noexcept
bool skia_log_bridge_available () noexcept
 True when this build contains the Skia log-handler subclass at all.
bool skia_log_bridge_enabled () noexcept
 True when the opt-in is satisfied: a PULP_TRACING=ON build, or PULP_GPU_LOG_BRIDGE set to 1/true/yes/on.
SkiaLogBridgeStatus install_skia_log_bridge_if_enabled () noexcept
 Install the bridge, honouring the opt-in.
SkiaLogBridgeStatus install_skia_log_bridge () noexcept
 Install the bridge regardless of the opt-in — calling this IS the explicit opt-in.
std::string_view gpu_error_kind_name (GpuError::Kind kind)
constexpr GpuTextureUsage operator| (GpuTextureUsage a, GpuTextureUsage b)
constexpr bool has_usage (GpuTextureUsage set, GpuTextureUsage bit)
constexpr GpuBufferUsage operator| (GpuBufferUsage a, GpuBufferUsage b)
constexpr bool has_usage (GpuBufferUsage set, GpuBufferUsage bit)
GpuStatus draw_gpu_texture (canvas::Canvas &canvas, const GpuTexture &texture, float x, float y, float w, float h)
 Draw texture into the canvas rectangle (x, y, w, h).
bool set_dawn_proc_installer (const DawnProcInstaller &installer, std::string *error=nullptr)
 Register the process's Dawn proc-table installer in place of Pulp's native default.
bool ensure_dawn_procs (std::string *error=nullptr)
 Make Dawn's proc table usable before creating a Dawn object.
std::vector< const char * > gpu_surface_disabled_toggles (bool timestamp_query_requested)
 Dawn toggles that must be DISABLED for the requested device features.
std::optional< double > gpu_render_ns_to_ms (std::uint64_t elapsed_ns, bool callback_ok)
 Convert a Graphite GpuStats::elapsedTime sample into a millisecond duration.
const char * adapter_type_label (GpuSurface::AdapterType type) noexcept
 Stable lowercase label for an adapter type: "integrated", "discrete", "cpu", or "unknown".
std::string format_gpu_adapter_line (const GpuSurface::AdapterInfo &info)
 One line naming the adapter a surface came up on, e.g.
std::string format_gpu_startup_line (const GpuStartupReport &report)
 One line of stage timings in milliseconds with one decimal, e.g.
std::string format_gpu_diagnostics_line (const SkiaLogBridgeState &bridge, const GpuDiagnosticsStats &stats)
 One line saying whether the Skia log bridge is wired and what reached it, e.g.
void log_gpu_diagnostics_summary ()
 Log the GpuDiagnostics line for this process at info level, preceded by skia: N more records suppressed when the bridge's text budget ran out.
std::string optimal_gpu_format ()
 Detect the optimal GPU texture compression format for the current platform.
DecodedTexture decode_ktx2 (const uint8_t *data, size_t size)
 Validate and parse KTX2 header metadata.
bool ktx2_available ()
 Check if a KTX2 transcoding backend was compiled in.
const char * render_loop_backend_name (RenderLoopBackend backend)
 Human-readable name for a backend (for logs / diagnostics).
constexpr bool render_loop_backend_is_vsync (RenderLoopBackend backend)
 True if the backend is locked to a real hardware/compositor vblank signal (as opposed to the conscious timer fallback).
void apply_display_rate_change (void *ca_display_link, DisplayRateBoost::Change change)
 iOS only: applies change to a CADisplayLink (passed as void* so C++ callers need no Objective-C).
Sdl3SurfaceInfo extract_sdl3_surface (SDL_Window *window)
constexpr bool frame_reached_output (FrameOutcome outcome)
 True when outcome means the frame's pixels reached their intended output, i.e.
SkpCaptureResult capture_skp_to_file (int width, int height, const std::string &path, const std::function< void(canvas::Canvas &)> &paint, skgpu::graphite::Context *graphite_context=nullptr)
 One-shot helper: capture a frame by handing a paint callback the capture canvas, then writing the .skp to path.
bool skp_capture_supported ()
 true when this build can produce .skp captures (Skia compiled in).
SkpCaptureResult maybe_capture_skp_from_env (int width, int height, const std::function< void(canvas::Canvas &)> &paint, skgpu::graphite::Context *graphite_context=nullptr)
 Env-var-triggered one-shot .skp capture.
std::string_view wgsl_severity_name (WgslDiagnostic::Severity severity)
std::string format_wgsl_diagnostic (std::string_view source_name, const WgslDiagnostic &diagnostic)
 name:line:column: severity: message, or name: severity: message without a position.
std::string format_wgsl_diagnostics (std::string_view source_name, const std::vector< WgslDiagnostic > &diagnostics)
 One formatted diagnostic per line.
bool has_wgsl_errors (const std::vector< WgslDiagnostic > &diagnostics)

Variables

constexpr std::size_t kGpuDiagnosticMessageLimit = 512
 Longest message text carried into a trace annotation.
constexpr std::uint64_t kSkiaLogTextLimit = 50
 How many Skia log records the bridge copies into the text log before it stops, so a chatty Skia cannot flood a user's log.
constexpr double kGpuRenderNanosecondsPerMillisecond = 1.0e6
 Whole-recording GPU render time.
constexpr const char * kDawnTimestampQuantizationToggle = "timestamp_quantization"
 Dawn's timestamp_quantization toggle, which defaults to ON in native Dawn (not only in Chrome) and ANDs every resolved timestamp with 0xFFFF0000 — truncating each endpoint to a multiple of 65536 ns.

Typedef Documentation

◆ FrameCallback

using pulp::render::FrameCallback = std::function<void()>

◆ GpuResult

template<typename T>
using pulp::render::GpuResult = runtime::Result<T, GpuError>

◆ GpuStatus

Success is a default-constructed value.

◆ HardcodedCubeRenderResult

◆ SceneDataRenderResult

Enumeration Type Documentation

◆ AtlasKind

enum class pulp::render::AtlasKind
strong

Which kind of atlas an AtlasInfo describes.

Mirrors the atlas classes in texture_atlas.hpp so the inspector can label rows and (later) pick per-kind colors.

Enumerator
glyph 

GlyphAtlas — SDF / custom-text glyph cache.

image 

ImageAtlas — packed small images.

gradient 

GradientAtlas — evaluated gradient ramps (row-packed).

path 

PathAtlas — rasterized vector paths.

◆ FrameOutcome

enum class pulp::render::FrameOutcome
strong

Where a frame actually ended up.

A frame that renders perfectly and reaches nothing is the failure mode this enum exists to stop being silent. Before it, begin_frame() answered a failed native-drawable wrap by handing back the OFFSCREEN canvas: the host painted, submitted, presented, reported success, and cleared its damage, while the texture being presented had never been drawn into. The editor was black and every observable signal — including screenshot readback, which reads the offscreen target — said the frame was fine.

offscreen is therefore a first-class SUCCESS (headless capture and the browser path have no presentable surface by design), and the offscreen canvas is never a fallback for a presentable surface that failed.

Enumerator
presented 

Drew into, and submitted to, the intended presentable drawable.

offscreen 

No native surface exists by design; the offscreen target IS the output.

recreate 

The native drawable could not be wrapped or blitted.

Its contents are undefined; the surface should be recreated before the next attempt.

failed 

Submission failed. The surface is still usable — retry the frame.

◆ GpuAdapterKind

enum class pulp::render::GpuAdapterKind : std::uint8_t
strong

Adapter class as Dawn reports it.

Enumerator
unknown 
integrated 
discrete 
cpu 

◆ GpuBlend

enum class pulp::render::GpuBlend : std::uint8_t
strong
Enumerator
replace 

Write the fragment color as is.

alpha 

Straight alpha: src * a + dst * (1 - a).

premultiplied 

Premultiplied alpha: src + dst * (1 - a). Skia composites premultiplied.

additive 

src + dst.

◆ GpuBufferUsage

enum class pulp::render::GpuBufferUsage : std::uint32_t
strong

Buffer usage bits. Values match WebGPU's GPUBufferUsage.

Enumerator
none 
map_read 
map_write 
copy_src 
copy_dst 
index 
vertex 
uniform 
storage 

◆ GpuCompare

enum class pulp::render::GpuCompare : std::uint8_t
strong
Enumerator
never 
less 
less_equal 
greater 
greater_equal 
equal 
not_equal 
always 

◆ GpuCullMode

enum class pulp::render::GpuCullMode : std::uint8_t
strong
Enumerator
none 
front 
back 

◆ GpuDiagnosticSeverity

Severity of one GPU diagnostic record.

Enumerator
info 
warning 
error 
fatal 

◆ GpuFormat

enum class pulp::render::GpuFormat : std::uint8_t
strong

Texture formats the typed GPU API accepts.

Names follow WebGPU (gpu_format_name(GpuFormat::rgba8_unorm) == "rgba8unorm").

Enumerator
undefined 
r8_unorm 
rg8_unorm 
rgba8_unorm 
rgba8_unorm_srgb 
bgra8_unorm 
bgra8_unorm_srgb 
rgb10a2_unorm 
rg11b10_ufloat 
r16_float 
rg16_float 
rgba16_float 
r32_float 
rg32_float 
rgba32_float 
r32_uint 
rgba8_uint 
depth16_unorm 
depth24_plus 
depth24_plus_stencil8 
depth32_float 

◆ GpuPrimitiveTopology

enum class pulp::render::GpuPrimitiveTopology : std::uint8_t
strong
Enumerator
triangle_list 
triangle_strip 
line_list 
line_strip 
point_list 

◆ GpuRenderTier

enum class pulp::render::GpuRenderTier : std::uint8_t
strong

Coarse rendering tier for choosing a visual path.

none no device, or the Null backend: render nothing on the GPU. basic a CPU (software) adapter, or a device below the standard limits: keep passes small, avoid MSAA and float targets. standard a hardware adapter with at least 4 color attachments, 4 storage textures per stage, 256 compute invocations per workgroup and 8192-texel 2D textures (the WebGPU defaults). high standard on a discrete adapter, or with 16384-texel textures, 8 color attachments and float32 blending.

Enumerator
none 
basic 
standard 
high 

◆ GpuSubmissionStatus

enum class pulp::render::GpuSubmissionStatus : std::uint8_t
strong
Enumerator
pending 
succeeded 
failed 

◆ GpuTextureUsage

enum class pulp::render::GpuTextureUsage : std::uint32_t
strong

Texture usage bits. Values match WebGPU's GPUTextureUsage.

Enumerator
none 
copy_src 
copy_dst 
sampled 
storage 
render_target 

◆ GpuVertexFormat

enum class pulp::render::GpuVertexFormat : std::uint8_t
strong
Enumerator
float32 
float32x2 
float32x3 
float32x4 
uint32 
sint32 
unorm8x4 

◆ Renderer3DAdapterBackendPreference

Enumerator
default_backend 
null_backend 
vulkan 
d3d12 

◆ RenderLoopBackend

Which concrete backend RenderLoop::create() selected.

Exposed so callers (and tests) can introspect whether a real vblank source or the timer fallback is in use without depending on platform defines.

Enumerator
cv_display_link 

macOS — real vblank.

ca_display_link 

iOS — real vblank.

choreographer 

Android — real vblank.

dwm_flush 

Windows — DWM-composed vblank wait.

raf 

Browser — requestAnimationFrame (compositor vblank).

timer 

Conscious ~60 Hz timer fallback (Linux/other).

◆ RenderPassType

enum class pulp::render::RenderPassType
strong

Defines the ordering of render passes in a frame.

Audio plugin UIs benefit from ordered compositing: background → content → effects → overlays → post-effects.

Enumerator
background 

Static backgrounds, panel fills.

content 

Main widget content (knobs, faders, meters).

effects 

Per-layer effects (blur, bloom).

overlay 

Tooltips, dropdowns, modals (always on top).

post_effects 

Full-frame post-processing (vignette, color grading).

◆ SkiaLogBridgeStatus

Outcome of trying to route Skia's process-global log handler into the sink.

SkLogHandler::SetInstance is first-install-wins and process-global, and Pulp loads into hosts that may use Skia themselves, so every outcome other than installed is a normal, reportable state rather than an error.

Enumerator
not_attempted 

install_skia_log_bridge*() has not run yet.

installed 

This process owns Skia's log handler and records are flowing.

declined_handler_present 

Somebody else installed a handler first; theirs is left untouched.

declined_not_enabled 

The opt-in was absent, so no install was attempted.

unavailable_no_skia 

This build has no Skia, so there is no handler to install.

Function Documentation

◆ adapter_type_label()

const char * pulp::render::adapter_type_label ( GpuSurface::AdapterType type)
noexcept

Stable lowercase label for an adapter type: "integrated", "discrete", "cpu", or "unknown".

◆ all_gpu_formats()

const std::vector< GpuFormat > & pulp::render::all_gpu_formats ( )

Every format above except undefined, in declaration order.

◆ apply_display_rate_change()

void pulp::render::apply_display_rate_change ( void * ca_display_link,
DisplayRateBoost::Change change )

iOS only: applies change to a CADisplayLink (passed as void* so C++ callers need no Objective-C).

raise requests the main screen's maximum frame rate when it exceeds 60 Hz; lower restores the default range; none and a null link do nothing. Defined only in iOS builds.

◆ atlas_kind_name()

const char * pulp::render::atlas_kind_name ( AtlasKind kind)
inline

Human-readable name for an AtlasKind — used by the inspector panel and by tests.

◆ capture_skp_to_file()

SkpCaptureResult pulp::render::capture_skp_to_file ( int width,
int height,
const std::string & path,
const std::function< void(canvas::Canvas &)> & paint,
skgpu::graphite::Context * graphite_context = nullptr )

One-shot helper: capture a frame by handing a paint callback the capture canvas, then writing the .skp to path.

The callback paints whatever should appear in the frame. When Skia is unavailable, or width/height are non-positive, this returns a failed SkpCaptureResult with a reason and writes nothing.

graphite_context is forwarded to SkpFrameCapture — supply it when the painted frame may embed GPU-texture-backed images so they survive serialization (see the SkpFrameCapture constructor).

◆ decode_draco() [1/2]

DecodedMesh pulp::render::decode_draco ( const uint8_t * data,
size_t size )

Decode a DRACO-compressed mesh buffer.

Returns decoded geometry with positions, normals, UVs, and indices.

◆ decode_draco() [2/2]

DecodedMesh pulp::render::decode_draco ( const uint8_t * data,
size_t size,
const DracoAttributeIds & attribute_ids )

Decode a DRACO-compressed mesh buffer using glTF semantic -> Draco unique-id mappings.

This is the path required by KHR_draco_mesh_compression.

◆ decode_ktx2()

DecodedTexture pulp::render::decode_ktx2 ( const uint8_t * data,
size_t size )

Validate and parse KTX2 header metadata.

The current built-in path does not transcode Basis Universal payloads, so pixels can be empty even when success is true.

◆ draco_decoder_available()

bool pulp::render::draco_decoder_available ( )

True when this build was compiled with the native DRACO decoder enabled.

◆ draw_gpu_texture()

GpuStatus pulp::render::draw_gpu_texture ( canvas::Canvas & canvas,
const GpuTexture & texture,
float x,
float y,
float w,
float h )

Draw texture into the canvas rectangle (x, y, w, h).

Requirements:

  • the canvas is a GPU (Skia Graphite) canvas; any other canvas, such as a recording or CPU canvas, fails with unavailable. It must draw on the device the texture was created on, the one the GpuSurface behind GpuDevice::from_surface() owns;
  • the texture is single-sample, has sampled usage and is rgba8_unorm, bgra8_unorm or rgba16_float (checked);
  • no unsubmitted GpuFrame writes it (checked): submit first, so the queue runs the pass before Graphite samples the result.

The texture's contents are treated as premultiplied alpha. Graphite's wrapped image retains the Dawn texture until it is done with it, so the caller may drop its own handle after this returns.

◆ emit_gpu_diagnostic()

void pulp::render::emit_gpu_diagnostic ( GpuDiagnosticSeverity severity,
const char * source,
std::string_view message )
noexcept

Publish one GPU diagnostic as a gpu-category instant event.

source is a stable, low-cardinality tag naming the producer ("dawn.uncaptured_error", "dawn.device_lost", "skia.log"). message is the variable text; it is truncated to kGpuDiagnosticMessageLimit bytes rather than allocated. Callers may pass a non-null-terminated view.

Counted unconditionally, including in a PULP_TRACING=OFF build, so the counter proves the call site ran even where no Perfetto event exists.

◆ ensure_dawn_procs()

bool pulp::render::ensure_dawn_procs ( std::string * error = nullptr)
nodiscard

Make Dawn's proc table usable before creating a Dawn object.

The first call fixes the policy (later set_dawn_proc_installer() calls are rejected) and runs the registered installer, or the native default. Once an installer reports success, every later call returns true without running it again. A failed attempt is not latched: the next call retries, so a verify-only host can finish its own installation first. Thread-safe.

◆ extract_sdl3_surface()

Sdl3SurfaceInfo pulp::render::extract_sdl3_surface ( SDL_Window * window)

◆ fill_format_table()

void pulp::render::fill_format_table ( GpuDeviceCapabilities & caps)

Fill the format table of caps from caps.facts.features. Pure.

◆ format_gpu_adapter_line()

std::string pulp::render::format_gpu_adapter_line ( const GpuSurface::AdapterInfo & info)

One line naming the adapter a surface came up on, e.g.

GpuSurface: adapter name="Apple M3 Max" vendor="apple" architecture="metal-3" description="..." type=integrated backend=Metal null=false (a single line; wrapped here for width). String fields are quoted with " and \\endiskip escaped and control characters replaced by spaces, so one field can never break the line or impersonate another.

◆ format_gpu_diagnostics_line()

std::string pulp::render::format_gpu_diagnostics_line ( const SkiaLogBridgeState & bridge,
const GpuDiagnosticsStats & stats )

One line saying whether the Skia log bridge is wired and what reached it, e.g.

GpuDiagnostics: skia_bridge=installed skia_records=3 gpu_diagnostics_emitted=5 truncated=0 skia_text_suppressed=0 (a single line), so "nothing was logged" is distinguishable from "nothing was wired".

◆ format_gpu_startup_line()

std::string pulp::render::format_gpu_startup_line ( const GpuStartupReport & report)

One line of stage timings in milliseconds with one decimal, e.g.

GpuSurface: startup_ms instance=0.4 adapter=12.1 device=8.3 surface=1.0 graphite=20.5 first_frame=95.2 (a single line). A stage that was not measured prints n/a.

◆ format_wgsl_diagnostic()

std::string pulp::render::format_wgsl_diagnostic ( std::string_view source_name,
const WgslDiagnostic & diagnostic )

name:line:column: severity: message, or name: severity: message without a position.

◆ format_wgsl_diagnostics()

std::string pulp::render::format_wgsl_diagnostics ( std::string_view source_name,
const std::vector< WgslDiagnostic > & diagnostics )

One formatted diagnostic per line.

◆ frame_reached_output()

bool pulp::render::frame_reached_output ( FrameOutcome outcome)
constexpr

True when outcome means the frame's pixels reached their intended output, i.e.

the caller may retire this frame's damage. The one predicate hosts should use, so "did it reach the screen?" cannot drift between platforms.

◆ gpu_diagnostics_stats()

GpuDiagnosticsStats pulp::render::gpu_diagnostics_stats ( )
noexcept

◆ gpu_error_kind_name()

std::string_view pulp::render::gpu_error_kind_name ( GpuError::Kind kind)

◆ gpu_format_bytes_per_pixel()

std::uint32_t pulp::render::gpu_format_bytes_per_pixel ( GpuFormat format)

Bytes per texel for color formats, 0 for depth/stencil and undefined (depth texels have no defined CPU layout and cannot be read back).

◆ gpu_format_is_depth()

bool pulp::render::gpu_format_is_depth ( GpuFormat format)

True for depth and depth/stencil formats.

◆ gpu_format_name()

std::string_view pulp::render::gpu_format_name ( GpuFormat format)

WebGPU spelling of a format ("rgba8unorm"), or "undefined".

◆ gpu_format_support()

GpuFormatSupport pulp::render::gpu_format_support ( GpuFormat format,
const GpuDeviceFeatures & features )

The WebGPU format table for format, adjusted for features. Pure.

◆ gpu_render_ns_to_ms()

std::optional< double > pulp::render::gpu_render_ns_to_ms ( std::uint64_t elapsed_ns,
bool callback_ok )
inlinenodiscard

Convert a Graphite GpuStats::elapsedTime sample into a millisecond duration.

Returns std::nullopt — meaning "no usable sample this frame" — when the finished-with-stats callback did not succeed, or when the elapsed time is zero (Skia surfaces 0 when no pass was timestamped or the timer setup failed — never a real sample). This guard is only correct while quantization is disabled; with it on, a genuinely fast frame also reports 0 and is wrongly discarded.

◆ gpu_render_tier_name()

std::string_view pulp::render::gpu_render_tier_name ( GpuRenderTier tier)

◆ gpu_surface_disabled_toggles()

std::vector< const char * > pulp::render::gpu_surface_disabled_toggles ( bool timestamp_query_requested)
inlinenodiscard

Dawn toggles that must be DISABLED for the requested device features.

Requesting timestamp queries without disabling quantization yields samples that are technically present and numerically useless.

◆ has_usage() [1/2]

bool pulp::render::has_usage ( GpuBufferUsage set,
GpuBufferUsage bit )
constexpr

◆ has_usage() [2/2]

bool pulp::render::has_usage ( GpuTextureUsage set,
GpuTextureUsage bit )
constexpr

◆ has_wgsl_errors()

bool pulp::render::has_wgsl_errors ( const std::vector< WgslDiagnostic > & diagnostics)

◆ install_skia_log_bridge()

SkiaLogBridgeStatus pulp::render::install_skia_log_bridge ( )
noexcept

Install the bridge regardless of the opt-in — calling this IS the explicit opt-in.

Installs only when SkLogHandler::GetInstance() is null; an existing handler is never displaced. Idempotent: repeat calls report the first outcome.

◆ install_skia_log_bridge_if_enabled()

SkiaLogBridgeStatus pulp::render::install_skia_log_bridge_if_enabled ( )
noexcept

Install the bridge, honouring the opt-in.

Without it the status becomes declined_not_enabled and Skia is not touched. This is the entry point a host or app calls; a plugin build ships with the opt-in off.

◆ ktx2_available()

bool pulp::render::ktx2_available ( )

Check if a KTX2 transcoding backend was compiled in.

◆ log_gpu_diagnostics_summary()

void pulp::render::log_gpu_diagnostics_summary ( )

Log the GpuDiagnostics line for this process at info level, preceded by skia: N more records suppressed when the bridge's text budget ran out.

Intended for the end of a bounded run (a headless screenshot), not per frame.

◆ maybe_capture_skp_from_env()

SkpCaptureResult pulp::render::maybe_capture_skp_from_env ( int width,
int height,
const std::function< void(canvas::Canvas &)> & paint,
skgpu::graphite::Context * graphite_context = nullptr )

Env-var-triggered one-shot .skp capture.

This is the concrete trigger the capture machinery was missing — SkpFrameCapture / capture_skp_to_file had no production caller. The macOS GPU host calls this once per painted frame; when PULP_SKP_CAPTURE_DIR names a directory it captures the frame into <dir>/pulp-frame-<n>.skp, logs the path, and disarms — so setting the variable dumps exactly ONE .skp per arming, not one per frame. Re-arms only when the variable's value changes (point it at a new directory to capture again). Returns a failed result (with a reason) when the variable is unset, already fired for this value, or Skia is unavailable.

◆ operator|() [1/2]

GpuBufferUsage pulp::render::operator| ( GpuBufferUsage a,
GpuBufferUsage b )
constexpr

◆ operator|() [2/2]

GpuTextureUsage pulp::render::operator| ( GpuTextureUsage a,
GpuTextureUsage b )
constexpr

◆ optimal_gpu_format()

std::string pulp::render::optimal_gpu_format ( )

Detect the optimal GPU texture compression format for the current platform.

Returns "astc" on Apple targets, "bc7" on Windows/Linux-family targets, and "rgba8" for the fallback path.

◆ pick_tier()

GpuRenderTier pulp::render::pick_tier ( const GpuDeviceFacts & facts)

Pure: the same facts always give the same tier.

◆ render_loop_backend_is_vsync()

bool pulp::render::render_loop_backend_is_vsync ( RenderLoopBackend backend)
constexpr

True if the backend is locked to a real hardware/compositor vblank signal (as opposed to the conscious timer fallback).

◆ render_loop_backend_name()

const char * pulp::render::render_loop_backend_name ( RenderLoopBackend backend)

Human-readable name for a backend (for logs / diagnostics).

◆ set_dawn_proc_installer()

bool pulp::render::set_dawn_proc_installer ( const DawnProcInstaller & installer,
std::string * error = nullptr )
nodiscard

Register the process's Dawn proc-table installer in place of Pulp's native default.

Call it before the first GpuSurface or GpuCompute is created. Registering the same installer and context again is a no-op that returns true. Returns false, logs an error, and leaves the current policy in place when installer.install is null, when a different installer is already registered, or when a Dawn object creation has already consulted the policy: a late registration is a host ordering bug, never silently ignored.

◆ skia_log_bridge_available()

bool pulp::render::skia_log_bridge_available ( )
noexcept

True when this build contains the Skia log-handler subclass at all.

False means unavailable_no_skia is the only outcome an install can ever report, which is the difference between "nothing to install" and "declined to".

◆ skia_log_bridge_enabled()

bool pulp::render::skia_log_bridge_enabled ( )
noexcept

True when the opt-in is satisfied: a PULP_TRACING=ON build, or PULP_GPU_LOG_BRIDGE set to 1/true/yes/on.

Setting PULP_GPU_LOG_BRIDGE to 0/false/no/off wins over the tracing build, so a tracing build can still leave the host's Skia logging alone.

◆ skia_log_bridge_state()

SkiaLogBridgeState pulp::render::skia_log_bridge_state ( )
noexcept

◆ skp_capture_supported()

bool pulp::render::skp_capture_supported ( )

true when this build can produce .skp captures (Skia compiled in).

Lets a caller report an honest "unavailable" (e.g. the maybe_capture_skp_from_env trigger, which no-ops on a non-Skia build) instead of attempting a doomed capture.

◆ to_string() [1/2]

const char * pulp::render::to_string ( GpuDiagnosticSeverity severity)
noexcept

Stable lowercase label for a severity, suitable as a trace annotation value.

◆ to_string() [2/2]

const char * pulp::render::to_string ( SkiaLogBridgeStatus status)
noexcept

Stable lowercase label for a bridge status, suitable for status output.

◆ wgsl_severity_name()

std::string_view pulp::render::wgsl_severity_name ( WgslDiagnostic::Severity severity)

Variable Documentation

◆ kDawnTimestampQuantizationToggle

const char* pulp::render::kDawnTimestampQuantizationToggle = "timestamp_quantization"
inlineconstexpr

Dawn's timestamp_quantization toggle, which defaults to ON in native Dawn (not only in Chrome) and ANDs every resolved timestamp with 0xFFFF0000 — truncating each endpoint to a multiple of 65536 ns.

It exists to stop untrusted web content building a high-resolution timer; Pulp runs its own shaders in its own process, so the mitigation buys nothing here and costs the metric roughly three orders of magnitude of resolution.

Two consequences worth knowing if you ever read a sample taken with it on:

  • Both endpoints truncate independently, so the error has zero mean. The MEAN of many frames converges on the true duration; a min or a median does not, at any sample count.
  • A frame faster than 65536 ns reports exactly 0 and is discarded below as "no sample", which preferentially drops the FAST frames and biases even the mean upward.

Apple contributes no coarsening of its own: Apple Silicon GPU timestamps are already nanoseconds, with a 41.67 ns (24 MHz) hardware granularity.

◆ kGpuDiagnosticMessageLimit

std::size_t pulp::render::kGpuDiagnosticMessageLimit = 512
inlineconstexpr

Longest message text carried into a trace annotation.

Longer messages are truncated; the full text still reaches the log.

◆ kGpuRenderNanosecondsPerMillisecond

double pulp::render::kGpuRenderNanosecondsPerMillisecond = 1.0e6
inlineconstexpr

Whole-recording GPU render time.

True per-pass GPU timing tied to Pulp's logical render passes is architecturally blocked: Skia Graphite owns the Dawn command encoder and every render-pass descriptor, so Pulp cannot inject per-pass timestampWrites, and the encoder-level WriteTimestamp is gated behind Dawn's allow_unsafe_apis toggle and disabled by Skia's DawnCaps on Metal/Apple-silicon (Pulp's primary platform).

What IS available — and correct on every backend — is Skia Graphite's own GPU-stats API: InsertRecordingInfo::fGpuStatsFlags = kElapsedTime plus a finished-with-stats callback that hands back a GpuStats{elapsedTime} in nanoseconds once the GPU finishes the recording. SkiaSurface wires that callback; this header carries the pure, Dawn-free seam — the ns→ms conversion + the cross-thread latest-sample holder — so it can be unit tested without a live GPU device.

Naming note: it is "GPU render time", not total frame time. On the Metal fallback Skia measures first-pass-begin → last-pass-end of the recording and excludes non-pass work (texture uploads/copies) and present. Nanoseconds per millisecond. Skia reports results[1] - results[0] verbatim, but Dawn is not a passthrough: it scales raw ticks by a per-device period and then, unless the toggle below is disabled, masks the low 16 bits of every endpoint.

◆ kSkiaLogTextLimit

std::uint64_t pulp::render::kSkiaLogTextLimit = 50
inlineconstexpr

How many Skia log records the bridge copies into the text log before it stops, so a chatty Skia cannot flood a user's log.

The remainder is counted and reported once by log_gpu_diagnostics_summary().