Removed `webrender_api` from `zero_ui_view_api` API.

This commit is contained in:
Samuel Guerra 2024-02-21 19:09:44 -03:00
parent 30b599515b
commit 9f00c221f1
23 changed files with 343 additions and 296 deletions

View File

@ -73,6 +73,7 @@ members = [
"zero-ui-wgt-tooltip",
"zero-ui-wgt-markdown",
"zero-ui-wgt-material-icons",
"zero-ui-wgt-webrender-debug",
# main
"zero-ui",

View File

@ -1,3 +1,9 @@
* Implement `zero-ui-wgt-webrender-debug`
- Review view extension API.
- Access point to call `render_extension` from `WINDOW` or `WINDOWS`?
- Need to register extension with window in window request?
- `WindowRequest::extensions`
* Continue removing webrender from view API.
# Documentation

View File

@ -26,6 +26,7 @@ zero-ui = { path = "../zero-ui", features = [
zero-ui-app = { path = "../zero-ui-app" } # for respawn and extend_view examples
zero-ui-view-api = { path = "../zero-ui-view-api" } # for the extend_view example
zero-ui-view = { path = "../zero-ui-view" } # for the extend_view example
zero-ui-wgt-webrender-debug = { path = "../zero-ui-wgt-webrender-debug" } # for the extend_view example
examples-util = { path = "util" }
# backtrace-on-stack-overflow = "0.2"

View File

@ -1,5 +1,6 @@
use zero_ui::{color::filter::hue_rotate, layout::size, prelude::*};
use zero_ui_view::extensions::ViewExtensions;
// use zero_ui_wgt_webrender_debug as wr;
// Examples of how to extend the view-process with custom renderers.
//
@ -18,9 +19,8 @@ fn main() {
fn app_main() {
APP.defaults().run_window(async {
Window! {
// renderer_debug = {
// use zero_ui::core::render::webrender_api::DebugFlags;
// DebugFlags::TEXTURE_CACHE_DBG | DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED
// wr::renderer_debug = {
// wr::DebugFlags::TEXTURE_CACHE_DBG | wr::DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED
// };
title = "Extend-View Example";
@ -432,7 +432,7 @@ pub mod using_blob {
euclid,
},
};
use zero_ui_view_api::{api_extension::ApiExtensionId, unit::PxToWr as _, webrender_api};
use zero_ui_view_api::{api_extension::ApiExtensionId, unit::PxToWr as _};
pub fn extend(exts: &mut ViewExtensions) {
exts.renderer(super::api::extension_name(), CustomExtension::new);
@ -690,7 +690,7 @@ pub mod using_blob {
// Webrender received the update request
}
fn delete(&mut self, key: webrender_api::BlobImageKey) {
fn delete(&mut self, key: BlobImageKey) {
// Webrender requested cleanup.
let mut renderer = self.renderer.lock();

View File

@ -2,7 +2,7 @@
use std::path::PathBuf;
use zero_ui::view_process::prebuilt as view_process;
use zero_ui::view_process::default as view_process;
use zero_ui::{
app, button,
checkerboard::Checkerboard,
@ -21,6 +21,8 @@ use zero_ui::{
window::{RenderMode, WindowState},
};
use zero_ui_wgt_webrender_debug as wr;
fn main() {
examples_util::print_info();
// view_process::init();
@ -584,10 +586,9 @@ impl ImgWindow {
fn widget_intrinsic(&mut self) {
zero_ui::prelude_wgt::widget_set! {
self;
// renderer_debug = {
// use zero_ui::core::render::webrender_api::DebugFlags;
// DebugFlags::TEXTURE_CACHE_DBG | DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED
// };
wr::renderer_debug = {
wr::DebugFlags::TEXTURE_CACHE_DBG | wr::DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED
};
// render_mode = RenderMode::Software;

View File

@ -11,6 +11,7 @@ ipc = ["zero-ui/ipc"]
[dev-dependencies]
zero-ui = { path = "../zero-ui", features = ["test_util", "toml", "ron", "yaml"] }
zero-ui-view = { path = "../zero-ui-view" }
zero-ui-wgt-webrender-debug = { path = "../zero-ui-wgt-webrender-debug" }
zero-ui-app = { path = "../zero-ui-app" }
pretty_assertions = "1"

View File

@ -10,7 +10,7 @@ use zero_ui::{
render::FrameId,
touch::{TouchForce, TouchPhase},
widget::{BorderSides, BorderStyle, LineStyle},
window::{DebugFlags, RendererDebug, WindowState},
window::WindowState,
};
#[test]
@ -166,8 +166,8 @@ fn test_view_api_types() {
test_config!(CursorIcon::Alias);
test_config!(WindowState::Normal);
test_config!(RendererDebug {
flags: DebugFlags::DISABLE_ALPHA_PASS | DebugFlags::DISABLE_BATCHING,
test_config!(zero_ui_wgt_webrender_debug::RendererDebug {
flags: zero_ui_wgt_webrender_debug::DebugFlags::DISABLE_ALPHA_PASS | zero_ui_wgt_webrender_debug::DebugFlags::DISABLE_BATCHING,
profiler_ui: "default".to_owned()
});
}

View File

@ -23,8 +23,6 @@ use zero_ui_view_api::{
config::FontAntiAliasing,
display_list::{DisplayList, DisplayListBuilder, FilterOp, NinePatchSource, ReuseRange, ReuseStart},
font::{GlyphInstance, GlyphOptions},
unit::PxToWr,
webrender_api,
window::FrameId,
ReferenceFrameId as RenderReferenceFrameId,
};
@ -1356,13 +1354,11 @@ impl FrameBuilder {
self.display_list.push_nine_patch_border(
bounds,
NinePatchSource::RadialGradient {
gradient: webrender_api::RadialGradient {
center: center.to_wr(),
radius: radius.to_wr(),
start_offset: 0.0,
end_offset: 1.0,
extend_mode: extend_mode.into(),
},
center: center.cast(),
radius: radius.cast(),
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
stops: stops.to_vec().into_boxed_slice(),
},
widths,
@ -1401,13 +1397,11 @@ impl FrameBuilder {
self.display_list.push_nine_patch_border(
bounds,
NinePatchSource::ConicGradient {
gradient: webrender_api::ConicGradient {
center: center.to_wr(),
angle: angle.0,
start_offset: 0.0,
end_offset: 1.0,
extend_mode: extend_mode.into(),
},
center: center.cast(),
angle,
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
stops: stops.to_vec().into_boxed_slice(),
},
widths,

View File

@ -8,7 +8,7 @@ use byteorder::{BigEndian, ReadBytesExt};
use icu_properties::sets;
use zero_ui_color::{rgba, ColorScheme, Rgba};
use zero_ui_var::impl_from_and_into_var;
use zero_ui_view_api::webrender_api::GlyphIndex;
use zero_ui_view_api::font::GlyphIndex;
pub(super) fn maybe_emoji(c: char) -> bool {
sets::emoji().contains(c)

View File

@ -64,7 +64,6 @@ use zero_ui_var::{
animation::Transitionable, impl_from_and_into_var, response_done_var, response_var, var, AnyVar, ArcVar, IntoVar, LocalVar,
ResponderVar, ResponseVar, Var,
};
use zero_ui_view_api::webrender_api as wr;
use zero_ui_view_api::{config::FontAntiAliasing, ViewProcessOffline};
/// Font family name.
@ -1439,7 +1438,10 @@ impl Font {
///
/// The caret offset for the first cluster is the glyph offset and is not yielded in the iterator. The
/// yielded offsets are relative to the glyph position.
pub fn ligature_caret_offsets(&self, lig: wr::GlyphIndex) -> impl ExactSizeIterator<Item = f32> + DoubleEndedIterator + '_ {
pub fn ligature_caret_offsets(
&self,
lig: zero_ui_view_api::font::GlyphIndex,
) -> impl ExactSizeIterator<Item = f32> + DoubleEndedIterator + '_ {
let face = &self.0.face.0;
face.lig_carets.carets(lig).iter().map(move |&o| match o {
ligature_util::LigatureCaret::Coordinate(o) => {

View File

@ -10,7 +10,7 @@ NULL = 0
use core::cmp;
use byteorder::{BigEndian, ReadBytesExt};
use zero_ui_view_api::webrender_api::GlyphIndex;
use zero_ui_view_api::font::GlyphIndex;
const GDEF: u32 = u32::from_be_bytes(*b"GDEF");

View File

@ -767,7 +767,7 @@ impl ShapedText {
if self.lines.0.len() > 2 {
// has mid-lines
let mid_offset = euclid::vec2::<f32, zero_ui_view_api::webrender_api::units::LayoutPixel>(
let mid_offset = euclid::vec2::<f32, Px>(
0.0,
match block_size.height.cmp(&align_size.height) {
cmp::Ordering::Less => (align_size.height - block_size.height).0 as f32 * align_y + mid.0 as f32,

View File

@ -515,14 +515,6 @@ impl HeadedCtrl {
self.vars.0.actual_color_scheme.set(scheme);
}
self.vars.renderer_debug().with_new(|dbg| {
if let Some(view) = &self.window {
if let Some(key) = dbg.extension_id() {
let _ = view.renderer().render_extension::<_, ()>(key, dbg);
}
}
});
if let Some(e) = self.vars.0.access_enabled.get_new() {
debug_assert!(e.is_enabled());
UPDATES.update_info_window(WINDOW.id());
@ -1082,11 +1074,7 @@ impl HeadedCtrl {
Some(area)
}),
extensions: {
let mut exts = vec![];
self.vars.renderer_debug().with(|d| d.push_extension(&mut exts));
exts
},
extensions: vec![],
};
match VIEW_PROCESS.open_window(request) {
@ -1213,11 +1201,7 @@ impl HeadedCtrl {
Some(area)
}),
extensions: {
let mut exts = vec![];
self.vars.renderer_debug().with(|d| d.push_extension(&mut exts));
exts
},
extensions: vec![],
};
match VIEW_PROCESS.open_window(request) {
@ -1449,14 +1433,6 @@ impl HeadlessWithRendererCtrl {
self.var_bindings = update_headless_vars(self.headless_monitor.scale_factor, &self.vars);
}
self.vars.renderer_debug().with_new(|dbg| {
if let Some(view) = &self.surface {
if let Some(key) = dbg.extension_id() {
let _ = view.renderer().render_extension::<_, ()>(key, dbg);
}
}
});
self.content.update(update_widgets);
}
@ -1564,11 +1540,7 @@ impl HeadlessWithRendererCtrl {
scale_factor,
size,
render_mode,
extensions: {
let mut exts = vec![];
self.vars.renderer_debug().with(|d| d.push_extension(&mut exts));
exts
},
extensions: vec![],
});
match r {

View File

@ -18,9 +18,7 @@ use zero_ui_txt::Txt;
use zero_ui_unique_id::IdSet;
use zero_ui_var::impl_from_and_into_var;
use zero_ui_view_api::{
api_extension::{ApiExtensionId, ApiExtensionPayload},
image::{ImageDataFormat, ImageMaskMode},
webrender_api::DebugFlags,
window::{EventCause, FrameId},
};
@ -680,167 +678,3 @@ impl fmt::Display for WindowNotFound {
}
}
impl std::error::Error for WindowNotFound {}
/// Webrender renderer debug flags and profiler UI.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct RendererDebug {
/// Debug flags.
#[serde(with = "serde_debug_flags")]
pub flags: DebugFlags,
/// Profiler UI rendered when [`DebugFlags::PROFILER_DBG`] is set.
///
/// # Syntax
///
/// Comma-separated list of of tokens with trailing and leading spaces trimmed.
/// Each tokens can be:
/// - A counter name with an optional prefix. The name corresponds to the displayed name.
/// - By default (no prefix) the counter is shown as average + max over half a second.
/// - With a '#' prefix the counter is shown as a graph.
/// - With a '*' prefix the counter is shown as a change indicator.
/// - Some special counters such as GPU time queries have specific visualizations ignoring prefixes.
/// - A preset name to append the preset to the UI.
/// - An empty token to insert a bit of vertical space.
/// - A '|' token to start a new column.
/// - A '_' token to start a new row.
///
/// # Preset & Counter Names
///
/// * `"Default"`: `"FPS,|,Slow indicators,_,Time graphs,|,Frame times, ,Transaction times, ,Frame stats, ,Memory, ,Interners,_,GPU time queries,_,Paint phase graph"`
/// * `"Compact"`: `"FPS, ,Frame times, ,Frame stats"`
///
/// See the `webrender/src/profiler.rs` file for more details and more counter names.
pub profiler_ui: String,
}
impl Default for RendererDebug {
/// Disabled
fn default() -> Self {
Self::disabled()
}
}
impl RendererDebug {
/// Default mode, no debugging enabled.
pub fn disabled() -> Self {
Self {
flags: DebugFlags::empty(),
profiler_ui: String::new(),
}
}
/// Enable profiler UI rendering.
pub fn profiler(ui: impl Into<String>) -> Self {
Self {
flags: DebugFlags::PROFILER_DBG,
profiler_ui: ui.into(),
}
}
/// Custom flags with no UI string.
pub fn flags(flags: DebugFlags) -> Self {
Self {
flags,
profiler_ui: String::new(),
}
}
/// If no flag nor profiler UI are set.
pub fn is_empty(&self) -> bool {
self.flags.is_empty() && self.profiler_ui.is_empty()
}
pub(super) fn extension_id(&self) -> Option<ApiExtensionId> {
zero_ui_app::view_process::VIEW_PROCESS
.extension_id("zero-ui-view.webrender_debug")
.ok()
.flatten()
}
pub(super) fn push_extension(&self, exts: &mut Vec<(ApiExtensionId, ApiExtensionPayload)>) {
if !self.is_empty() {
if let Some(id) = self.extension_id() {
exts.push((id, ApiExtensionPayload::serialize(self).unwrap()));
}
}
}
}
impl_from_and_into_var! {
fn from(profiler_default: bool) -> RendererDebug {
if profiler_default {
Self::profiler("Default")
} else {
Self::disabled()
}
}
fn from(profiler: &str) -> RendererDebug {
Self::profiler(profiler)
}
fn from(profiler: Txt) -> RendererDebug {
Self::profiler(profiler)
}
fn from(flags: DebugFlags) -> RendererDebug {
Self::flags(flags)
}
}
/// Named DebugFlags in JSON serialization.
mod serde_debug_flags {
use super::*;
use serde::*;
bitflags::bitflags! {
#[repr(C)]
#[derive(Default, Deserialize, Serialize)]
#[serde(transparent)]
struct DebugFlagsRef: u32 {
const PROFILER_DBG = DebugFlags::PROFILER_DBG.bits();
const RENDER_TARGET_DBG = DebugFlags::RENDER_TARGET_DBG.bits();
const TEXTURE_CACHE_DBG = DebugFlags::TEXTURE_CACHE_DBG.bits();
const GPU_TIME_QUERIES = DebugFlags::GPU_TIME_QUERIES.bits();
const GPU_SAMPLE_QUERIES = DebugFlags::GPU_SAMPLE_QUERIES.bits();
const DISABLE_BATCHING = DebugFlags::DISABLE_BATCHING.bits();
const EPOCHS = DebugFlags::EPOCHS.bits();
const ECHO_DRIVER_MESSAGES = DebugFlags::ECHO_DRIVER_MESSAGES.bits();
const SHOW_OVERDRAW = DebugFlags::SHOW_OVERDRAW.bits();
const GPU_CACHE_DBG = DebugFlags::GPU_CACHE_DBG.bits();
const TEXTURE_CACHE_DBG_CLEAR_EVICTED = DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED.bits();
const PICTURE_CACHING_DBG = DebugFlags::PICTURE_CACHING_DBG.bits();
const PRIMITIVE_DBG = DebugFlags::PRIMITIVE_DBG.bits();
const ZOOM_DBG = DebugFlags::ZOOM_DBG.bits();
const SMALL_SCREEN = DebugFlags::SMALL_SCREEN.bits();
const DISABLE_OPAQUE_PASS = DebugFlags::DISABLE_OPAQUE_PASS.bits();
const DISABLE_ALPHA_PASS = DebugFlags::DISABLE_ALPHA_PASS.bits();
const DISABLE_CLIP_MASKS = DebugFlags::DISABLE_CLIP_MASKS.bits();
const DISABLE_TEXT_PRIMS = DebugFlags::DISABLE_TEXT_PRIMS.bits();
const DISABLE_GRADIENT_PRIMS = DebugFlags::DISABLE_GRADIENT_PRIMS.bits();
const OBSCURE_IMAGES = DebugFlags::OBSCURE_IMAGES.bits();
const GLYPH_FLASHING = DebugFlags::GLYPH_FLASHING.bits();
const SMART_PROFILER = DebugFlags::SMART_PROFILER.bits();
const INVALIDATION_DBG = DebugFlags::INVALIDATION_DBG.bits();
const PROFILER_CAPTURE = DebugFlags::PROFILER_CAPTURE.bits();
const FORCE_PICTURE_INVALIDATION = DebugFlags::FORCE_PICTURE_INVALIDATION.bits();
const WINDOW_VISIBILITY_DBG = DebugFlags::WINDOW_VISIBILITY_DBG.bits();
const RESTRICT_BLOB_SIZE = DebugFlags::RESTRICT_BLOB_SIZE.bits();
}
}
impl From<DebugFlagsRef> for DebugFlags {
fn from(value: DebugFlagsRef) -> Self {
DebugFlags::from_bits(value.bits()).unwrap()
}
}
impl From<DebugFlags> for DebugFlagsRef {
fn from(value: DebugFlags) -> Self {
DebugFlagsRef::from_bits(value.bits()).unwrap()
}
}
pub fn serialize<S: serde::Serializer>(flags: &DebugFlags, serializer: S) -> Result<S::Ok, S::Error> {
DebugFlagsRef::from(*flags).serialize(serializer)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<DebugFlags, D::Error> {
DebugFlagsRef::deserialize(deserializer).map(Into::into)
}
}

View File

@ -17,7 +17,7 @@ use zero_ui_view_api::{
window::{CursorIcon, FocusIndicator, RenderMode, VideoMode, WindowState},
};
use crate::{AutoSize, CursorImg, FrameCaptureMode, MonitorQuery, RendererDebug, WindowIcon};
use crate::{AutoSize, CursorImg, FrameCaptureMode, MonitorQuery, WindowIcon};
pub(super) struct WindowVarsData {
chrome: ArcVar<bool>,
@ -74,8 +74,6 @@ pub(super) struct WindowVarsData {
frame_capture_mode: ArcVar<FrameCaptureMode>,
pub(super) render_mode: ArcVar<RenderMode>,
renderer_debug: ArcVar<RendererDebug>,
pub(super) access_enabled: ArcVar<AccessEnabled>,
}
@ -150,8 +148,6 @@ impl WindowVars {
frame_capture_mode: var(FrameCaptureMode::Sporadic),
render_mode: var(default_render_mode),
renderer_debug: var(RendererDebug::disabled()),
access_enabled: var(AccessEnabled::empty()),
});
Self(vars)
@ -654,11 +650,6 @@ impl WindowVars {
self.0.render_mode.read_only()
}
/// Renderer debug flags and profiler UI.
pub fn renderer_debug(&self) -> ArcVar<RendererDebug> {
self.0.renderer_debug.clone()
}
/// If an accessibility service has requested info from this window.
///
/// This variable can only add flags, you can enable it in the app-process using [`enable_access`], the

View File

@ -1432,13 +1432,39 @@ impl DisplayItem {
extend_mode: (*extend_mode).into(),
})
}
NinePatchSource::RadialGradient { gradient, stops } => {
NinePatchSource::RadialGradient {
center,
radius,
start_offset,
end_offset,
extend_mode,
stops,
} => {
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr::NinePatchBorderSource::RadialGradient(*gradient)
wr::NinePatchBorderSource::RadialGradient(wr::RadialGradient {
center: center.cast_unit(),
radius: radius.cast_unit(),
start_offset: *start_offset,
end_offset: *end_offset,
extend_mode: (*extend_mode).into(),
})
}
NinePatchSource::ConicGradient { gradient, stops } => {
NinePatchSource::ConicGradient {
center,
angle,
start_offset,
end_offset,
extend_mode,
stops,
} => {
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr::NinePatchBorderSource::ConicGradient(*gradient)
wr::NinePatchBorderSource::ConicGradient(wr::ConicGradient {
center: center.cast_unit(),
angle: angle.0,
start_offset: *start_offset,
end_offset: *end_offset,
extend_mode: (*extend_mode).into(),
})
}
};
@ -1771,11 +1797,19 @@ pub enum NinePatchSource {
stops: Box<[GradientStop]>,
},
RadialGradient {
gradient: wr::RadialGradient,
center: euclid::Point2D<f32, Px>,
radius: euclid::Size2D<f32, Px>,
start_offset: f32,
end_offset: f32,
extend_mode: ExtendMode,
stops: Box<[GradientStop]>,
},
ConicGradient {
gradient: wr::ConicGradient,
center: euclid::Point2D<f32, Px>,
angle: AngleRadian,
start_offset: f32,
end_offset: f32,
extend_mode: ExtendMode,
stops: Box<[GradientStop]>,
},
}

View File

@ -15,9 +15,6 @@
#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#[doc(inline)]
pub use webrender_api;
#[cfg(feature = "ipc")]
use serde::{Deserialize, Serialize};

View File

@ -7,16 +7,15 @@
use std::{any::Any, sync::Arc};
use webrender::api::{
units::TexelRect, AsyncBlobImageRasterizer, BlobImageHandler, BlobImageParams, BlobImageRequest, BlobImageResult, DocumentId,
ExternalImageId, PipelineId,
};
use webrender::{DebugFlags, RenderApi};
use zero_ui_unit::{Factor, PxSize};
use zero_ui_view_api::{
api_extension::{ApiExtensionId, ApiExtensionName, ApiExtensionPayload, ApiExtensions},
display_list,
webrender_api::{
units::TexelRect, AsyncBlobImageRasterizer, BlobImageHandler, BlobImageParams, BlobImageRequest, BlobImageResult, DocumentId,
ExternalImageId, PipelineId,
},
Event,
display_list, Event,
};
/// The extension API.
@ -119,7 +118,7 @@ pub struct RenderArgs<'a> {
pub frame_id: zero_ui_view_api::window::FrameId,
/// The webrender display list.
pub list: &'a mut zero_ui_view_api::webrender_api::DisplayListBuilder,
pub list: &'a mut webrender::api::DisplayListBuilder,
/// Space and clip tracker.
pub sc: &'a mut display_list::SpaceAndClip,
@ -147,7 +146,7 @@ pub struct RenderItemArgs<'a> {
pub is_reuse: bool,
/// The webrender display list.
pub list: &'a mut zero_ui_view_api::webrender_api::DisplayListBuilder,
pub list: &'a mut webrender::api::DisplayListBuilder,
/// Space and clip tracker.
pub sc: &'a mut display_list::SpaceAndClip,
@ -179,7 +178,7 @@ pub struct RenderUpdateArgs<'a> {
///
/// If no other extension and update handlers request a new frame these properties
/// will be send to Webrender to update the current frame.
pub properties: &'a mut zero_ui_view_api::webrender_api::DynamicProperties,
pub properties: &'a mut webrender::api::DynamicProperties,
/// The transaction that will send the properties update.
pub transaction: &'a mut webrender::Transaction,
@ -244,20 +243,20 @@ pub trait BlobExtension: Send + Any {
fn update(&mut self, args: &BlobUpdateArgs);
/// Remove a blob image if the key was generated by this extension.
fn delete(&mut self, key: zero_ui_view_api::webrender_api::BlobImageKey);
fn delete(&mut self, key: webrender::api::BlobImageKey);
/// Cleanup any prepared resource for the font.
fn delete_font(&mut self, key: zero_ui_view_api::webrender_api::FontKey) {
fn delete_font(&mut self, key: webrender::api::FontKey) {
let _ = key;
}
/// Cleanup any prepared resource for the font instance.
fn delete_font_instance(&mut self, key: zero_ui_view_api::webrender_api::FontInstanceKey) {
fn delete_font_instance(&mut self, key: webrender::api::FontInstanceKey) {
let _ = key;
}
/// Cleanup any state related with the namespace.
fn clear_namespace(&mut self, namespace: zero_ui_view_api::webrender_api::IdNamespace) {
fn clear_namespace(&mut self, namespace: webrender::api::IdNamespace) {
let _ = namespace;
}
@ -300,7 +299,7 @@ pub trait AsyncBlobRasterizer: Send + Any {
/// Arguments for [`BlobExtension::prepare_resources`].
pub struct BlobPrepareArgs<'a> {
///
pub services: &'a dyn zero_ui_view_api::webrender_api::BlobImageResources,
pub services: &'a dyn webrender::api::BlobImageResources,
/// Requests targeting any of the blob extensions. Each extension must
/// inspect the requests to find the ones targeting it.
pub requests: &'a [BlobImageParams],
@ -311,14 +310,14 @@ pub struct BlobAddArgs {
/// Blob key.
///
/// Blob extension must ignore this request if it did not generate this key.
pub key: zero_ui_view_api::webrender_api::BlobImageKey,
pub key: webrender::api::BlobImageKey,
/// Encoded data.
pub data: std::sync::Arc<zero_ui_view_api::webrender_api::BlobImageData>,
pub data: std::sync::Arc<webrender::api::BlobImageData>,
///
pub visible_rect: zero_ui_view_api::webrender_api::units::DeviceIntRect,
pub visible_rect: webrender::api::units::DeviceIntRect,
///
pub tile_size: zero_ui_view_api::webrender_api::TileSize,
pub tile_size: webrender::api::TileSize,
}
/// Arguments for [`BlobExtension::update`].
@ -326,13 +325,13 @@ pub struct BlobUpdateArgs {
/// Blob key.
///
/// Blob extension must ignore this request if it did not generate this key.
pub key: zero_ui_view_api::webrender_api::BlobImageKey,
pub key: webrender::api::BlobImageKey,
/// Encoded data.
pub data: std::sync::Arc<zero_ui_view_api::webrender_api::BlobImageData>,
pub data: std::sync::Arc<webrender::api::BlobImageData>,
///
pub visible_rect: zero_ui_view_api::webrender_api::units::DeviceIntRect,
pub visible_rect: webrender::api::units::DeviceIntRect,
///
pub dirty_rect: zero_ui_view_api::webrender_api::units::BlobDirtyRect,
pub dirty_rect: webrender::api::units::BlobDirtyRect,
}
/// Arguments for [`AsyncBlobRasterizer::rasterize`].
@ -434,7 +433,7 @@ impl ExternalImages {
/// [`unregister`]: Self::unregister
pub fn register_image(
&mut self,
descriptor: zero_ui_view_api::webrender_api::ImageDescriptor,
descriptor: webrender::api::ImageDescriptor,
pixels: zero_ui_view_api::ipc::IpcBytes,
) -> ExternalImageId {
self.register(crate::image_cache::ImageData::RawData {
@ -794,7 +793,7 @@ impl BlobImageHandler for BlobExtensionsImgHandler {
Box::new(Self(self.0.iter().map(|e| e.create_similar()).collect()))
}
fn prepare_resources(&mut self, services: &dyn zero_ui_view_api::webrender_api::BlobImageResources, requests: &[BlobImageParams]) {
fn prepare_resources(&mut self, services: &dyn webrender::api::BlobImageResources, requests: &[BlobImageParams]) {
for ext in self.0.iter_mut() {
ext.prepare_resources(&mut BlobPrepareArgs { services, requests })
}
@ -802,10 +801,10 @@ impl BlobImageHandler for BlobExtensionsImgHandler {
fn add(
&mut self,
key: zero_ui_view_api::webrender_api::BlobImageKey,
data: std::sync::Arc<zero_ui_view_api::webrender_api::BlobImageData>,
visible_rect: &zero_ui_view_api::webrender_api::units::DeviceIntRect,
tile_size: zero_ui_view_api::webrender_api::TileSize,
key: webrender::api::BlobImageKey,
data: std::sync::Arc<webrender::api::BlobImageData>,
visible_rect: &webrender::api::units::DeviceIntRect,
tile_size: webrender::api::TileSize,
) {
let args = BlobAddArgs {
key,
@ -820,10 +819,10 @@ impl BlobImageHandler for BlobExtensionsImgHandler {
fn update(
&mut self,
key: zero_ui_view_api::webrender_api::BlobImageKey,
data: std::sync::Arc<zero_ui_view_api::webrender_api::BlobImageData>,
visible_rect: &zero_ui_view_api::webrender_api::units::DeviceIntRect,
dirty_rect: &zero_ui_view_api::webrender_api::units::BlobDirtyRect,
key: webrender::api::BlobImageKey,
data: std::sync::Arc<webrender::api::BlobImageData>,
visible_rect: &webrender::api::units::DeviceIntRect,
dirty_rect: &webrender::api::units::BlobDirtyRect,
) {
let args = BlobUpdateArgs {
key,
@ -836,25 +835,25 @@ impl BlobImageHandler for BlobExtensionsImgHandler {
}
}
fn delete(&mut self, key: zero_ui_view_api::webrender_api::BlobImageKey) {
fn delete(&mut self, key: webrender::api::BlobImageKey) {
for ext in self.0.iter_mut() {
ext.delete(key);
}
}
fn delete_font(&mut self, key: zero_ui_view_api::webrender_api::FontKey) {
fn delete_font(&mut self, key: webrender::api::FontKey) {
for ext in self.0.iter_mut() {
ext.delete_font(key);
}
}
fn delete_font_instance(&mut self, key: zero_ui_view_api::webrender_api::FontInstanceKey) {
fn delete_font_instance(&mut self, key: webrender::api::FontInstanceKey) {
for ext in self.0.iter_mut() {
ext.delete_font_instance(key);
}
}
fn clear_namespace(&mut self, namespace: zero_ui_view_api::webrender_api::IdNamespace) {
fn clear_namespace(&mut self, namespace: webrender::api::IdNamespace) {
for ext in self.0.iter_mut() {
ext.clear_namespace(namespace);
}

View File

@ -859,7 +859,7 @@ pub(crate) enum ImageData {
ppi: Option<ImagePpi>,
},
NativeTexture {
uv: zero_ui_view_api::webrender_api::units::TexelRect,
uv: webrender::api::units::TexelRect,
texture: gleam::gl::GLuint,
},
}

View File

@ -0,0 +1,15 @@
[package]
name = "zero-ui-wgt-webrender-debug"
version = "0.1.0"
authors = ["Samuel Guerra <sam.rodr.g@gmail.com>", "Well <well-r@hotmail.com>"]
edition = "2021"
license = "Apache-2.0"
readme = "../zero-ui-app/README.md"
[dependencies]
zero-ui-app = { path = "../zero-ui-app" }
zero-ui-wgt = { path = "../zero-ui-wgt" }
zero-ui-view-api = { path = "../zero-ui-view-api" }
webrender_api = { git = "https://github.com/SamRodri/webrender.git" }
serde = "1"
bitflags = "2"

View File

@ -0,0 +1,203 @@
#![doc = include_str!("../../zero-ui-app/README.md")]
//!
//! Webrender debug flags property for use with `zero-ui-view` view-process.
pub use webrender_api::DebugFlags;
use zero_ui_view_api::api_extension::{ApiExtensionId, ApiExtensionPayload};
use zero_ui_wgt::prelude::*;
#[property(CONTEXT, default(RendererDebug::disabled()))]
pub fn renderer_debug(child: impl UiNode, debug: impl IntoVar<RendererDebug>) -> impl UiNode {
// !! TODO, on window init
/*
{
let mut exts = vec![];
self.vars.renderer_debug().with(|d| d.push_extension(&mut exts));
exts
}
*/
let debug = debug.into_var();
match_node(child, move |c, op| match op {
UiNodeOp::Init => {
WIDGET.sub_var(&debug);
}
UiNodeOp::Update { .. } => {
if let Some(dbg) = debug.get_new() {
// !!: TODO
// if let Some(view) = &self.window {
// if let Some(key) = dbg.extension_id() {
// let _ = view.renderer().render_extension::<_, ()>(key, dbg);
// }
// }
}
}
_ => {}
})
}
/// Webrender renderer debug flags and profiler UI.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct RendererDebug {
/// Debug flags.
#[serde(with = "serde_debug_flags")]
pub flags: DebugFlags,
/// Profiler UI rendered when [`DebugFlags::PROFILER_DBG`] is set.
///
/// # Syntax
///
/// Comma-separated list of of tokens with trailing and leading spaces trimmed.
/// Each tokens can be:
/// - A counter name with an optional prefix. The name corresponds to the displayed name.
/// - By default (no prefix) the counter is shown as average + max over half a second.
/// - With a '#' prefix the counter is shown as a graph.
/// - With a '*' prefix the counter is shown as a change indicator.
/// - Some special counters such as GPU time queries have specific visualizations ignoring prefixes.
/// - A preset name to append the preset to the UI.
/// - An empty token to insert a bit of vertical space.
/// - A '|' token to start a new column.
/// - A '_' token to start a new row.
///
/// # Preset & Counter Names
///
/// * `"Default"`: `"FPS,|,Slow indicators,_,Time graphs,|,Frame times, ,Transaction times, ,Frame stats, ,Memory, ,Interners,_,GPU time queries,_,Paint phase graph"`
/// * `"Compact"`: `"FPS, ,Frame times, ,Frame stats"`
///
/// See the `webrender/src/profiler.rs` file for more details and more counter names.
pub profiler_ui: String,
}
impl Default for RendererDebug {
/// Disabled
fn default() -> Self {
Self::disabled()
}
}
impl RendererDebug {
/// Default mode, no debugging enabled.
pub fn disabled() -> Self {
Self {
flags: DebugFlags::empty(),
profiler_ui: String::new(),
}
}
/// Enable profiler UI rendering.
pub fn profiler(ui: impl Into<String>) -> Self {
Self {
flags: DebugFlags::PROFILER_DBG,
profiler_ui: ui.into(),
}
}
/// Custom flags with no UI string.
pub fn flags(flags: DebugFlags) -> Self {
Self {
flags,
profiler_ui: String::new(),
}
}
/// If no flag nor profiler UI are set.
pub fn is_empty(&self) -> bool {
self.flags.is_empty() && self.profiler_ui.is_empty()
}
fn extension_id(&self) -> Option<ApiExtensionId> {
zero_ui_app::view_process::VIEW_PROCESS
.extension_id("zero-ui-view.webrender_debug")
.ok()
.flatten()
}
fn push_extension(&self, exts: &mut Vec<(ApiExtensionId, ApiExtensionPayload)>) {
if !self.is_empty() {
if let Some(id) = self.extension_id() {
exts.push((id, ApiExtensionPayload::serialize(self).unwrap()));
}
}
}
}
impl_from_and_into_var! {
fn from(profiler_default: bool) -> RendererDebug {
if profiler_default {
Self::profiler("Default")
} else {
Self::disabled()
}
}
fn from(profiler: &str) -> RendererDebug {
Self::profiler(profiler)
}
fn from(profiler: Txt) -> RendererDebug {
Self::profiler(profiler)
}
fn from(flags: DebugFlags) -> RendererDebug {
Self::flags(flags)
}
}
/// Named DebugFlags in JSON serialization.
mod serde_debug_flags {
use super::*;
use serde::*;
bitflags::bitflags! {
#[repr(C)]
#[derive(Default, Deserialize, Serialize)]
#[serde(transparent)]
struct DebugFlagsRef: u32 {
const PROFILER_DBG = DebugFlags::PROFILER_DBG.bits();
const RENDER_TARGET_DBG = DebugFlags::RENDER_TARGET_DBG.bits();
const TEXTURE_CACHE_DBG = DebugFlags::TEXTURE_CACHE_DBG.bits();
const GPU_TIME_QUERIES = DebugFlags::GPU_TIME_QUERIES.bits();
const GPU_SAMPLE_QUERIES = DebugFlags::GPU_SAMPLE_QUERIES.bits();
const DISABLE_BATCHING = DebugFlags::DISABLE_BATCHING.bits();
const EPOCHS = DebugFlags::EPOCHS.bits();
const ECHO_DRIVER_MESSAGES = DebugFlags::ECHO_DRIVER_MESSAGES.bits();
const SHOW_OVERDRAW = DebugFlags::SHOW_OVERDRAW.bits();
const GPU_CACHE_DBG = DebugFlags::GPU_CACHE_DBG.bits();
const TEXTURE_CACHE_DBG_CLEAR_EVICTED = DebugFlags::TEXTURE_CACHE_DBG_CLEAR_EVICTED.bits();
const PICTURE_CACHING_DBG = DebugFlags::PICTURE_CACHING_DBG.bits();
const PRIMITIVE_DBG = DebugFlags::PRIMITIVE_DBG.bits();
const ZOOM_DBG = DebugFlags::ZOOM_DBG.bits();
const SMALL_SCREEN = DebugFlags::SMALL_SCREEN.bits();
const DISABLE_OPAQUE_PASS = DebugFlags::DISABLE_OPAQUE_PASS.bits();
const DISABLE_ALPHA_PASS = DebugFlags::DISABLE_ALPHA_PASS.bits();
const DISABLE_CLIP_MASKS = DebugFlags::DISABLE_CLIP_MASKS.bits();
const DISABLE_TEXT_PRIMS = DebugFlags::DISABLE_TEXT_PRIMS.bits();
const DISABLE_GRADIENT_PRIMS = DebugFlags::DISABLE_GRADIENT_PRIMS.bits();
const OBSCURE_IMAGES = DebugFlags::OBSCURE_IMAGES.bits();
const GLYPH_FLASHING = DebugFlags::GLYPH_FLASHING.bits();
const SMART_PROFILER = DebugFlags::SMART_PROFILER.bits();
const INVALIDATION_DBG = DebugFlags::INVALIDATION_DBG.bits();
const PROFILER_CAPTURE = DebugFlags::PROFILER_CAPTURE.bits();
const FORCE_PICTURE_INVALIDATION = DebugFlags::FORCE_PICTURE_INVALIDATION.bits();
const WINDOW_VISIBILITY_DBG = DebugFlags::WINDOW_VISIBILITY_DBG.bits();
const RESTRICT_BLOB_SIZE = DebugFlags::RESTRICT_BLOB_SIZE.bits();
}
}
impl From<DebugFlagsRef> for DebugFlags {
fn from(value: DebugFlagsRef) -> Self {
DebugFlags::from_bits(value.bits()).unwrap()
}
}
impl From<DebugFlags> for DebugFlagsRef {
fn from(value: DebugFlags) -> Self {
DebugFlagsRef::from_bits(value.bits()).unwrap()
}
}
pub fn serialize<S: serde::Serializer>(flags: &DebugFlags, serializer: S) -> Result<S::Ok, S::Error> {
DebugFlagsRef::from(*flags).serialize(serializer)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<DebugFlags, D::Error> {
DebugFlagsRef::deserialize(deserializer).map(Into::into)
}
}

View File

@ -2,8 +2,8 @@ use std::time::Duration;
use zero_ui_ext_config::{AnyConfig as _, ConfigKey, ConfigStatus, CONFIG};
use zero_ui_ext_window::{
AutoSize, FrameCaptureMode, MonitorQuery, RendererDebug, WINDOW_Ext as _, WindowIcon, WindowLoadingHandle, WindowState, WindowVars,
MONITORS, WINDOW_LOAD_EVENT,
AutoSize, FrameCaptureMode, MonitorQuery, WINDOW_Ext as _, WindowIcon, WindowLoadingHandle, WindowState, WindowVars, MONITORS,
WINDOW_LOAD_EVENT,
};
use zero_ui_wgt::prelude::*;
@ -92,8 +92,6 @@ set_properties! {
color_scheme: Option<ColorScheme>,
frame_capture_mode: FrameCaptureMode,
renderer_debug: RendererDebug,
}
macro_rules! map_properties {

View File

@ -95,15 +95,13 @@ pub use zero_ui_app::window::{MonitorId, StaticMonitorId, StaticWindowId, Window
pub use zero_ui_ext_window::{
AppRunWindowExt, AutoSize, CloseWindowResult, FocusIndicator, FrameCaptureMode, FrameImageReadyArgs, HeadlessAppWindowExt,
HeadlessMonitor, ImeArgs, MonitorInfo, MonitorQuery, MonitorsChangedArgs, ParallelWin, RenderMode, RendererDebug, StartPosition,
VideoMode, WINDOW_Ext, WidgetInfoBuilderImeArea, WidgetInfoImeArea, WindowChangedArgs, WindowCloseArgs, WindowCloseRequestedArgs,
WindowIcon, WindowLoadingHandle, WindowOpenArgs, WindowRoot, WindowRootExtenderArgs, WindowState, WindowStateAllowed, WindowVars,
HeadlessMonitor, ImeArgs, MonitorInfo, MonitorQuery, MonitorsChangedArgs, ParallelWin, RenderMode, StartPosition, VideoMode,
WINDOW_Ext, WidgetInfoBuilderImeArea, WidgetInfoImeArea, WindowChangedArgs, WindowCloseArgs, WindowCloseRequestedArgs, WindowIcon,
WindowLoadingHandle, WindowOpenArgs, WindowRoot, WindowRootExtenderArgs, WindowState, WindowStateAllowed, WindowVars,
FRAME_IMAGE_READY_EVENT, IME_EVENT, MONITORS, MONITORS_CHANGED_EVENT, WINDOWS, WINDOW_CHANGED_EVENT, WINDOW_CLOSE_EVENT,
WINDOW_CLOSE_REQUESTED_EVENT, WINDOW_LOAD_EVENT, WINDOW_OPEN_EVENT,
};
pub use zero_ui_view_api::webrender_api::DebugFlags;
/// Window commands.
pub mod cmd {
pub use zero_ui_ext_window::cmd::*;