How to profile WebGL with ext_disjoint_timer_query extension? - webgl

In WebGL we have special extension EXT_disjoint_timer_query for proper GPU profiling, but I can't find good manual how to use it. For example initialization below works in my machine
let gl = canvas.getContext('webgl');
let ext = gl.getExtension('EXT_disjoint_timer_query');
let startQuery = ext.createQueryEXT();
ext.queryCounterEXT(startQuery, ext.TIMESTAMP_EXT);
But last line return undefined. Also I am inspired from source example in regl library, but it's too sophisticated.

Related

Why do these rustflags give me an out of memory exception?

I am working on a web assembly application in rust. The program relies on streaming a file and storing the data in memory. However I run into a rust_oom issue.
This issue only arises when recompiling the std library with atomic, bulk-memory, and mutable-global flags.
Reproducable via .cargo/config.toml:
[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]
[unstable]
build-std = ["panic_abort", "std"]
Compiling without these flags works fine.
The relevant rust code:
#[wasm_bindgen]
pub async fn start(r: JsValue) {
// javascript response into websys response
let resp: Response = r.dyn_into().unwrap();
// from example here https://github.com/MattiasBuelens/wasm-streams/blob/master/examples/fetch_as_stream.rs
let raw_body = resp.body().unwrap();
let body = ReadableStream::from_raw(raw_body.dyn_into().unwrap());
let mut stream = body.into_stream();
// store the data in memory
let mut v = vec![];
log("start streaming");
while let Some(Ok(chunk)) = stream.next().await {
//convert to vec<u8>
let mut x = chunk.dyn_ref::<Uint8Array>().unwrap().to_vec();
v.append(&mut x);
}
log(&format!("{}", v.len()));
log("done streaming");
}
The full error message provided
at rust_oom (wasm_memtest_bg.wasm:0xfa10)
at __rg_oom (wasm_memtest_bg.wasm:0xfdd4)
at __rust_alloc_error_handler (wasm_memtest_bg.wasm:0xfd38)
at alloc::alloc::handle_alloc_error::rt_error::hf991f317b52eeff2 (wasm_memtest_bg.wasm:0xfdb3)
at core::ops::function::FnOnce::call_once::ha90352dededaa31f (wasm_memtest_bg.wasm:0xfdc9)
at core::intrinsics::const_eval_select::h04f9b6091fe1f42f (wasm_memtest_bg.wasm:0xfdbe)
at alloc::alloc::handle_alloc_error::h82c7beb21e18f5f3 (wasm_memtest_bg.wasm:0xfda8)
at alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle::h65538cba507bb5c9 (wasm_memtest_bg.wasm:0xc149)
at <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::he4014043296c78b9 (wasm_memtest_bg.wasm:0x1c85)
at wasm_bindgen_futures::task::multithread::Task::run::h77f1075b3537ddf9 (wasm_memtest_bg.wasm:0x5a0e)
Here is the full project if you want to test it out.
https://github.com/KivalM/memory-wasm
EDIT: The code required to reproduce the issue is provided in the first snippet. The full wasm application is provided in the repository so that you do not have to create one from scratch. I will include the rust code in the question.
The issue arises when loading a simple 500MB file into memory. Which should be possible via this approach. Yet Chrome(and chromium-based browsers) tend to run out of memory, whereas when the rustflags are not present the program runs just fine.
I will move the links here as they are not part of the question, but can be relevant.
https://rustwasm.github.io/2018/10/24/multithreading-rust-and-wasm.html
https://rustwasm.github.io/wasm-bindgen/examples/raytrace.html

How to manage multiple windows, usercontrols, and customcontrols with Elmish.wpf and F#?

I am a newbie to F#. I have recently be introduced to Elmish.wpf and the MVU design. The application I am working with is in C# WPF with many WPF usercontrols, customcontrols, and windows. It appears that Elmish.wpf flattens the concept of viewmodels into a single datacontext. (??). Can Elmish.wpf be used with multiple windows, usercontrols, and customcontrols? ("Multiple" here means about 20 windows, usercontrols, and customcontrols.)
If so, is there an example of this?
In looking at the Elmish.wpf webside, it seems that all windows need to be created upon initialization--
let main mainWindow (createWindow1: Func<#Window>) (createWindow2: Func<#Window>) =
let createWindow1 () = createWindow1.Invoke()
let createWindow2 () =
let window = createWindow2.Invoke()
window.Owner <- mainWindow
window
let bindings = App.mainBindings createWindow1 createWindow2
Program.mkSimpleWpf App.init App.update bindings
|> Program.withConsoleTrace
|> Program.runWindowWithConfig
{ ElmConfig.Default with LogConsole = true; Measure = true }
mainWindow
Is there a better way to do this? Am I barking up the wrong tree?
Thanks in advance.
Yes, Elmish.WPF absolutely supports multiple windows and user-defined controls.
Many of the samples in the Elmish.WPF repo demonstrate this one way or another. For example, the NewWindow sample demonstrates how to open new windows, and the SubModel (along with many others) sample demonstrates how to use custom UserControls. The SubModelSeq sample is currently the most complex one, demonstrating arbitrarily deep trees of recursive UserControls.
All of this is also described in the official Elmish.WPF tutorial.
(For future reference, this is the current commit at the time of writing; the samples may have changed since then.)

Download and get HTML code from a website

I need to download HTML code from some web page. What is the best way to approach this task? As I understand there are very few working web frameworks for Rust right now and hyper is the one most people use? But after searching it's documentation I couldn't find a way. The closest I got is this
extern crate hyper;
use hyper::Client;
fn main() {
let client = Client::new();
let res = client.get("http://www.bloomberg.com/")
.send()
.unwrap();
println!("{:?}", res);
}
But it returns Response, which doesn't seem to contain any code from HTML body.
Note: this answer is outdated!
I don't have the time to update this with every hyper release. But please see my answer to a very related question: How can I download a website's content into a string?
It's a bit hidden: The Response type implements the trait Read. One method of Read is read_to_string which reads everything into the a String. That's a simple way you can get the body.
extern crate hyper;
use hyper::Client;
use std::io::Read;
fn main() {
let client = Client::new();
let mut res = client.get("http://www.bloomberg.com/")
.send()
.unwrap();
let mut body = String::new();
res.read_to_string(&mut body).expect("failed to read into string");
println!("{}", body);
}
Currently Rustdoc (the HTML documentation of Rust) is a little bit misleading because Rust beginners think that trait implementations don't add any important functionality. This is not true, so better look out for it. However, the hyper documentation could be better...

F# PCL and System.IO.FileStream

I am writing a PCL using F# and I am trying to write something to disk. All of the PCL examples are in VB.NET and C# and those examples don't work in F#. Specifically, I have this code:
type FileSystemStockProvider(filePath:string) =
member this.PutData(stockData) =
let serializedData = stockData
|> Seq.map(fun row -> JsonConvert.SerializeObject(row))
let outFile = new System.IO.StreamWriter(filePath)
outFile.Write(serializedData)
The problem is that the System.IO.StreamWriter in F# does not have an overload to disk so it does not compile. Does anyone have a suggestion on how to write to disk using a PCL?
Thanks in advance
Confirmed, the overload you were looking for is missing. However, I don't think this is a mistake, as it is missing from the .net framework for C# and F#. It's not F# specific. The reason I expect is because of the sand boxing requirement on different mobile and cross platform devices. So, the Windows / Linux path name which we are used to doesn't apply universally any more.
See https://pclstorage.codeplex.com/. Use Nuget to retrieve
To reduce the number of steps in getFileStream, probably there is some room to do a little string parsing in a c:\ or a \\networkPath, or even a url based aRootWithAFewReservedWords://the/path/to/the/file.json kind of way.
btw: there was a problem with disposing of the file stream in your code. You need to be explicit and use one of the use / using / dispose techniques. Are you definitely not seeing the overload?
namespace PortableLibrary1
open Newtonsoft.Json
[<JsonObject>]
type TestType() =
[<JsonProperty>]
member val Property2 = "testData" with get, set
type FileSystemStockProvider(filePath:string) =
//let getFileStream folder file =
// // for windows / linux?
// new System.IO.StreamWriter("c:\\" + folder + "\\" + filePath)
let getFileStream folder file =
let rootFolder = PCLStorage.FileSystem.Current.LocalStorage
let folder = rootFolder.CreateFolderAsync(folder,PCLStorage.CreationCollisionOption.OpenIfExists).Result
let file = folder.CreateFileAsync(file, PCLStorage.CreationCollisionOption.ReplaceExisting).Result
file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite).Result
member __.PutData(stockData) =
let fs = getFileStream "theFolder" "theFile.json"
use outFile = new System.IO.StreamWriter(fs)
stockData |> Seq.iter (JsonConvert.SerializeObject >> outFile.Write)

How do you interact with js from dart?

No, this isn't the same as the other question of the same name.
There are seemingly identical packages which seem to do this, but with different apis.
http://dart-lang.github.io/js-interop/docs/js.html
https://api.dartlang.org/docs/channels/stable/latest/dart_js.html
Why are there two?
Which one are we supposed to use?
The interop one looks newer and has a better api, but doesn't actually work. According to the documentation, you should be able to convert this javascript:
var stage = new PIXI.Stage(0xFFFFFF);;
renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
Into:
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
document.body.append(renderer.view);
But that errors when you try to compile it:
dart2js
Error occured:/Users/doug/megac/client/public/dart/index.dart:7:27:
Warning: No member named 'PIXI' in class 'Proxy'.
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
^^^^^^^^^^^^^^^
So... js:dart? Is that what you're supposed to use?
Edit: Incidentally, for anyone who stumbles into this, there is also an open bug http://code.google.com/p/dart/issues/detail?id=15795&thanks=15795&ts=1388068177 regarding how minified dart-js interop bridge operations don't currently work. The original issue was reported in May 2013, and there's been no action on it since then, so don't hold your breath.
Js interop started with package:js. It was built with with window.postMessage.
Later dart:js has been added to provide better performance and reduce the size of the compiled js file. Basically the goal were :
removing scopes and lifecycle manual handling
avoiding noSuchMethod to keep compilation size as low as possible
renaming objects to make the api more understandable
Once dart:js has been ready, package:js has been rewrite to use dart:js under the cover.
package:js provides a simpler Api that comes at the cost of an increase of the js size (because package:js uses dart:mirrors and noSuchMethod).
Here is the same thing done with package:js and dart:js :
import 'package:js/js.dart' as js;
main() {
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
document.body.append(renderer.view);
}
import 'dart:js' as js;
main() {
var pixi = new js.JsObject(js.context['PIXI']['Stage'], [0xffffff]);
var renderer = js.context['PIXI'].callMethod('autoDetectRenderer', [400, 400]);
document.body.append(renderer['view']);
}

Resources