How to minimize shader jank on linux? - linux

In the official documentation on how to minimize shader jank, they mention how to do that for android and ios, but mention nothing about linux, so I tried running the command they mention flutter run --profile --cache-sksl --purge-persistent-cache , interacted with the app (as they request), and pressed M in the command line to
save the captured shaders into a file. but when I do this, I get this output
No data was received. To ensure SkSL data can be generated use a physical device then:
1. Pass "--cache-sksl" as an argument to flutter run.
2. Interact with the application to force shaders to be compiled.
My question Is this shader optimization technique available for linux, and if yes, then why no data is being received?
note I am sure that there are slow frames due to jank shaders in my app because I spot this in the devtools
and on the page above they say
Definitive evidence for the presence of shader compilation jank is to
see GrGLProgramBuilder::finalize in the tracing with --trace-skia
enabled.

Related

How to intercept Skia draw commands from Chromium Browser

This is an experimental project of mine related to remote browser isolation. I'm trying to intercept Skia draw commands in a running Chromium instance and later replay them in a different browser instance at client-side via CanvasKit, a WebAssembly build of Skia.
However, I'm having a hard time figuring out where and how to intercept those draw commands within Chromium source code. Any advice on how to approach my problem is much appreciated!
In Chromium, all the draw operations will be recorded in a DisplayItemList which you can find in the definition of class GraphicsContext in blink module. Second, these recorded operations will be replayed later when the CC thinks it will be right time.
On blink's end, all the things above related code was scattered mostly in blink/renderer/platform/graphics/graphics_context.cc and its related files. But if you see all Chromium as a whole, all the graphics things were triggered by CC (Chrome Compositor) which maintain a state machine and runs a draw frame loops triggered by system's vsync signal in Android. On this loop start, blink ends draw recording operations will be pushed. At the end of this loop, the composited frame's image will be translated to a serial of GPU ops and calling the system's GPU devices related APIs to do them. The CC related code files can
be found in components/viz/. You should read code of class Display as a starting key point.
My opinion comes from version 68 and you know code in Chromium changes frequently. So I cannot confirm the files and locations are still correct.

Get screenshot of EGL DRM/KMS application

How to get screenshot of graphical application programmatically? Application draw its window using EGL API via DRM/KMS.
I use Ubuntu Server 16.04.3 and graphical application written using Qt 5.9.2 with EGLFS QPA backend. It started from first virtual terminal (if matters), then it switch display to output in full HD graphical mode.
When I use utilities (e.g. fb2png) which operates on /dev/fb?, then only textmode contents of first virtual terminal (Ctrl+Alt+F1) are saved as screenshot.
It is hardly, that there are EGL API to get contents of any buffer from context of another process (it would be insecure), but maybe there are some mechanism (and library) to get access to final output of GPU?
One way would be to get a screenshot from within your application, reading the contents of the back buffer with glReadPixels(). Or use QQuickWindow::grabWindow(), which internally uses glReadPixels() in the correct way. This seems to be not an option for you, as you need to take a screenshot when the Qt app is frozen.
The other way would be to use the DRM API to map the framebuffer and then memcpy the mapped pixels. This is implemented in Chromium OS with Python and can be translated to C easily, see https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/367611. The DRM API can also be used by another process than the Qt UI process that does the rendering.
This is a very interesting question, and I have fought this problem from several angles.
The problem is quite complex and dependant on platform, you seem to be running on EGL, which means embedded, and there you have few options unless your platform offers them.
The options you have are:
glTexSubImage2D
glTexSubImage2D can copy several kinds of buffers from OpenGL textures to CPU memory. Unfortunatly it is not supported in GLES 2/3, but your embedded provider might support it via an extension. This is nice because you can either render to FBO or get the pixels from the specific texture you need. It also needs minimal code intervertion.
glReadPixels
glReadPixels is the most common way to download all or part of the GPU pixels which are already rendered. Albeit slow, it works on GLES and Desktop. On Desktop with a decent GPU is bearable up to interactive framerates, but beware on embedded it might be really slow as it stops your render thread to get the data (horrible framedrops ensured). You can save code as it can be made to work with minimal code modifications.
Pixel Buffer Objects (PBO's)
Once you start doing real research PBO's appear here and there because they can be made to work asynchronously. They are also generally not supported in embedded but can work really well on desktop even on mediocre GPU's. Also a bit tricky to setup and require specific render modifications.
Framebuffer
On embedded, sometimes you already render to the framebuffer, so go there and fetch the pixels. Also works on desktop. You can enven mmap() the buffer to a file and get partial contents easily. But beware in many embedded systems EGL does not work on the framebuffer but on a different 'overlay' so you might be snapshotting the background of it. Also to note some multimedia applications are run with UI's on the EGL and media players on the framebuffer. So if you only need to capture the video players this might work for you. In other cases there is EGL targeting a texture which is copied to the framebuffer, and it will also work just fine.
As far as I know render to texture and stream to a framebuffer is the way they made the sweet Qt UI you see on the Ableton Push 2
More exotic Dispmanx/OpenWF
On some embedded systems (notably the Raspberry Pi and most Broadcom Videocore's) you have DispmanX. Whichs is really interesting:
This is fun:
The lowest level of accessing the GPU seems to be by an API called Dispmanx[...]
It continues...
Just to give you total lack of encouragement from using Dispmanx there are hardly any examples and no serious documentation.
Basically DispmanX is very near to baremetal. So it is even deeper down than the framebuffer or EGL. Really interesting stuff because you can use vc_dispmanx_snapshot() and really get a snapshot of everything really fast. And by fast I mean I got 30FPS RGBA32 screen capture with no noticeable stutter on screen and about 4~6% of extra CPU overhead on a Rasberry Pi. Night and day because glReadPixels got was producing very noticeable framedrops even for 1x1 pixel capture.
That's pretty much what I've found.

Crash at draw call in nvoglv32.dll on new video card

Some days ago I set up my computer and installed a new copy of Windows 8 because of some hardware changes. Among others I changed the video card from Radeon HD 7870 to Nvidia GTX 660.
After setting up Visual Studio 11 again, I downloaded my last OpenGL project from Github and rebuilt the whole project. I ran the application out of Visual Studio and it crashed because of nvoglv32.dll.
Unhandled exception at 0x5D9F74E3 (nvoglv32.dll) in Application.exe: 0xC0000005: Access violation reading location 0x00000000.
In the old environment the application worked as expected. I didn't changed anything of the project or source code. The only difference was the language of the Visual Studio installtion which is English now and was German before. Therefore I created a new project and adopted all settings, but the error remains.
In order to locate the crash, I noticed that all initialization (window, shaders, ...) succeeded and the error is at the draw call glDrawElements() which referrs to the gemoetry pass of my deferred renderer.
After some reseach I found out that nvoglv32.dll is from Nvidia and is about a services called Compatible OpenGL ICD. Does that somehow mean that my application runs in a compatible mode? That sounds like a mode to support older applications and I want mine to run in a regular mode! By the way I installed the lastest stable drivers for my video card.
To be honest, I have no clue how to approach fixing this crash. What could cause it and how to fix it?
Update: I found a post on Geforce Forums about my issue. Although there was no reply, the autor could fix the problem by changing the order of two OpenGL calls.
Hi all,
After poking around with my application source code for a few hours, I found that calling the functions...
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, #)
glBindVertexArray(#)
...in that order causes the crash in nvoglv64.dll.
Reversing the order of these calls to...
glBindVertexArray(#)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, #)
...prevents the crash and appears to be well-behaved.
Cheers,
Robert Graf
Since I do not use vertex arrays I cannot simple do this fix but there might be a similar issue. I will report my progress.
Update: I have absolutely no clue how to solve my problem. I tried different video driver versions but it makes no difference. I completely rewrote the renderer using minimal shaders and simple forward rendering. But the crash sill occurs at the first draw call.
In order to locate the crash, I noticed that all initialization (window, shaders, ...) succeeded and the error is at the draw call glDrawElements().
Most likely you had a out-of-bounds access in your code all the time, but the AMD Radeon Catalyst drivers did reserve more address space, or caught them beforehand. And now your NVidia GeForce driver's don't.
Either you're passing glDrawElements a too large number for count elements to draw, or your index buffer contains values that index beyond the range of your vertex arrays. If it's the later, then you're probably using client side vertex arrays, as VBOs usually catch out-of-bounds accesses; also those wouldn't crash your client side program, but just render garbage.
Finally I came up with a solution to fix the crash.
The SFML framework I use to create the window and more provides a function to reset the OpenGL state of the context. I called it right after window creation.
Even though I can't explain why, removing that function call solved the crash. Maybe it is because GLEW or something else isn't yet initialized that moment.
sf::RenderWindow window;
window.create(VideoMode(1024, 768), "Window Title");
window.resetGLStates(); // removing this line fixed the crash
window.setVerticalSyncEnabled(true);

Communicate with a NES game running in an emulator

I am thinking of creating an arcade machine for fun. Something like this one. I wonder if it's possible to get events from some game, e.g.Super Mario. Assume I finish a level and I want to get that event, with the score and some other data and perform some actions with that data. I am thinking of running the emulator in Windows. Did anybody work on something like this? Are there not too difficult ways to get events and data from old NES games? May be I should run not Windows, but some Linux for that? Well, please share your thoughts about how to do the software part of it.
Modern emulators such as FCEUX make it possible to interact with the running ROM through Lua scripts (see example video). Using this API you could write a Lua script to:
monitor a certain memory location
wait for it to hold some special value (such as level_just_finished)
read out the current score from memory
do something with the score
In order to know which memory locations to check, you will either need to disassemble the ROM or run it through a debugger, or both. As for Super Mario Bros, there's already a commented disassembly available. The FCEUX emulator also has a built-in debugger/disassembler that you can use.
All of this takes a lot of effort and you would need to know Lua, 6502 assembly, and the inner workings of an NES. For your arcade machine, you might be better off just using an emulator such as UberNES, which automatically can track your highscore for many popular titles.
Class NES games don't have standard hooks for achievement reporting. The only options I can think of are the following:
Rebuild the ROMs in question, with your own hooks (which a custom emulator could handle).
Watch the ROM memory footprint directly, and parse the state continually, triggering when you observe some known state.
Both options require that you really understand the internals of a NES ROM.
IRQ...Go for Interrupt_requests..they triger a interrupt...I have read / and seen the code about it somewhere...even x86 also uses IRQs for communciation with various device a simple exmaple:keyboard when a key is pressed a call is made ti PIC and an IRQ is generated and system knows which key is pressed and the same mech is used in NES

How to enable vtk "direct" hardware rendering, X11 / Ubuntu 11.04 x86-64?

I notice that the IsDirect() method which should say whether hardware rendering is on returns false on my vtkRenderWindow*, link to class doc:
http://www.vtk.org/doc/nightly/html/classvtkRenderWindow.html
How do I enable it? Seems like a build option in cmake should do it, but what? My OpenGL libs are found OK. I notice there's a thread from a while back here: http://www.vtk.org/pipermail/vtkusers/2005-July/081034.html but I don't see any more recent info so far, is it just not supported on Linux?
First of all, I doubt it is a cmake option to enable direct HW rendering.
Applications are falling back to the software rending when the hardware rendering is not possible (GPU doesn't support some of the picked options).
Without seeing some code and getting details (which GPU), it is not possible to give a better answer.

Resources