HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Talk about code development, features, specific bugs, enhancements, patches, and similar things.
Forum rules
Please keep everything here strictly on-topic.
This board is meant for Pale Moon source code development related subjects only like code snippets, patches, specific bugs, git, the repositories, etc.

This is not for tech support! Please do not post tech support questions in the "Development" board!
Please make sure not to use this board for support questions. Please post issues with specific websites, extensions, etc. in the relevant boards for those topics.

Please keep things on-topic as this forum will be used for reference for Pale Moon development. Expect topics that aren't relevant as such to be moved or deleted.
smihaila

HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by smihaila » 2017-12-12, 23:00

Hi,

I'm running PaleMoon 27.6.2 x64 version, on a Linux Fedora 26 (Linux kernel 4.14.4-200.fc26.x86_64) under KDE 5 Plasma Desktop X-Windows environment.

The following JavaScript code is supposed to draw an ellipse on a HTML5 <canvas> element named "my_canvas":

<script type="text/javascript">
function drawEllipse(cx, cy, rx, ry)
{
var canvas = document.getElementById("my_canvas");
var canvas_ctx = canvas.getContext("2d");

canvas_ctx.save();

// The line below is IS/SHOULD BE equivalent to: { canvas_ctx.translate(cx - rx, cy - ry); canvas_ctx.scale(rx, ry); }
canvas_ctx.setTransform(rx, 0, 0, ry, cx - rx, cy - ry);

canvas_ctx.beginPath();
canvas_ctx.arc(1, 1, 1, 0, 2 * Math.PI, false);
canvas_ctx.closePath(); // This line is rather superfluous in this particular case.

canvas_ctx.restore();

canvas_ctx.lineWidth = 4;
canvas_ctx.strokeStyle="orange";
canvas_ctx.stroke();
}
</script>

The function above is called from within a "mouseover" event handler that is subscribed to the same "my_canvas" element - subscription that is performed in "event bubbling mode" i.e. via something like:
document.getElementById("my_canvas").addEventListener("mouseover", function (e) { .... });
The event wiring occurs upon HTML document body load.

Note: The drawEllipse() call actually does NOT happen unconditionally on any type of mouse move, but only when we previously had a "mousedown" event (it's a graphic drawing kind of web app).

The issue is that the ellipse is not seen until I do something to the web browser window that triggers a repaint of the canvas. Resizing the web browser's main window for example. Or bringing up the developer tools via F12 key and resizing its splitter.
The same code works perfectly, as expected, on Chrome (63.0.3239.84), Firefox (57.0.1) and Microsoft Windows 10 Edge - all 3 being x64 editions.

The root cause seems to be any call to CanvasRenderingContext2D that performs translation or scaling or possibly also rotation. If for example:
1. I comment out the "canvas_ctx.setTransform(rx, 0, 0, ry, cx - rx, cy - ry);" line. And,
2. I replace the "canvas_ctx.arc(1, 1, 1, 0, 2 * Math.PI, false);" line by "canvas_ctx.arc(cx, cy, rx, 0, 2 * Math.PI, false);" line (which draws a circle instead of an ellipse), then I see the circle drawing / showing up instantly, during each mousemove event.

My code is heavily inspired from a code similar to the one at the following Url - which you can actually test live to reproduce the problem easily:
http://www.robots.ox.ac.uk/~vgg/softwar ... _demo.html

Just click the ellipse button in the top-left toolbar named "Region Shape" and then: Position the mouse cursor somewhere on the picture, click the mouse left button, and while keeping it pressed, drag the mouse in an attempt to draw the ellipse.
You won't be able to see the resulting ellipse, until you trigger a web browser window repaint. The easiest way to do that is to hit F12 and depending on what layout your "Developer Tools" mini-window has, drag the splitter horizontally or vertically.

The issue was occurring also on PaleMoon 27.1 Linux x64 version (I've just upgraded today 12/12/2017 to the 27.6.2 version).

Your insights into this issue would be greatly appreciated.

smihaila

Re: HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by smihaila » 2017-12-13, 07:17

Addendum: The same 27.6.2 version of Palemoon for Windows (tested under Win7 x86/32-bit edition) works OK.
So, it is only the Linux flavor of it exhibiting the "not-updated canvas" issue.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35473
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by Moonchild » 2017-12-13, 19:20

If it is O.S. specific, then the browser most likely properly issues a repaint, but the texture in the compositor doesn't get updated. This can be an indicator of a driver issue or gfx lib issue.
Did you build from source? If so, try using official binaries.
Please post the output of help -> troubleshooting information (copy text).
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

smihaila

Re: HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by smihaila » 2017-12-13, 20:50

I did NOT build from source - just used the "pminstaller.sh" version 0.2.3.

Please the the output of the help -> troubleshooting information - in text / non-json format below:

Application Basics
------------------

Name: Pale Moon
Version: 27.6.2
Build ID: 20171124201735
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.9) Gecko/20100101 Goanna/3.4 Firefox/52.9 PaleMoon/27.6.2
OS: Linux 4.14.4-200.fc26.x86_64
Multiprocess Windows: 0/1 (default: false)
Safe Mode: false

Extensions
----------

Name: Tab Mix Plus
Version: 0.5.0.4
Enabled: true
ID: {dc572301-7619-498c-a57d-39143191b318}

Name: uBlock Origin
Version: 1.13.8
Enabled: true
ID: uBlock0@raymondhill.net

Graphics
--------

Adapter Description: Intel Open Source Technology Center -- Mesa DRI Intel(R) Haswell Desktop
Device ID: Mesa DRI Intel(R) Haswell Desktop
Driver Version: 3.0 Mesa 17.2.4
GPU Accelerated Windows: 0/1 Basic
Vendor ID: Intel Open Source Technology Center
WebGL Renderer: Intel Open Source Technology Center -- Mesa DRI Intel(R) Haswell Desktop
windowLayerManagerRemote: false
AzureCanvasBackend: cairo
AzureContentBackend: cairo
AzureFallbackCanvasBackend: none
AzureSkiaAccelerated: 0

Important Modified Preferences
------------------------------

accessibility.typeaheadfind.flashBar: 0
browser.cache.disk.capacity: 358400
browser.cache.disk.smart_size.first_run: false
browser.cache.disk.smart_size.use_old_max: false
browser.download.importedFromSqlite: true
browser.newtab.url: about:newtab
browser.places.smartBookmarksVersion: 4
browser.search.useDBForOrder: true
browser.sessionstore.max_tabs_undo: 1000
browser.startup.homepage: about:blank
browser.startup.homepage_override.buildID: 20171124201735
browser.startup.homepage_override.mstone: 3.4.1
browser.tabs.onTop: true
browser.tabs.selectOwnerOnClose: false
browser.tabs.tabMaxWidth: 100
browser.tabs.tabMinWidth: 75
browser.tabs.warnOnClose: false
extensions.lastAppVersion: 27.6.2
font.minimum-size.x-western: 15
image.http.accept: image/webp,image/jxr,image/png,image/*;q=0.8,*/*;q=0.5
network.cookie.prefsMigrated: true
network.http.speculative-parallel-limit: 0
places.database.lastMaintenance: 1512884223
places.history.expiration.transient_current_max_pages: 104858
print.print_bgcolor: false
print.print_bgimages: false
print.print_colorspace: default
print.print_downloadfonts: false
print.print_duplex: 1
print.print_evenpages: true
print.print_in_color: true
print.print_margin_bottom: 0.5
print.print_margin_left: 0.5
print.print_margin_right: 0.5
print.print_margin_top: 0.5
print.print_oddpages: true
print.print_orientation: 0
print.print_page_delay: 50
print.print_paper_data: 0
print.print_paper_height: 279.40
print.print_paper_name: na_letter
print.print_paper_size_type: 1
print.print_paper_size_unit: 1
print.print_paper_width: 215.90
print.print_plex_name: default
print.print_resolution_name: default
print.print_scaling: 1.00
print.print_shrink_to_fit: true
print.print_to_file: false
print.print_unwriteable_margin_bottom: 56
print.print_unwriteable_margin_left: 25
print.print_unwriteable_margin_right: 25
print.print_unwriteable_margin_top: 25
privacy.sanitize.migrateFx3Prefs: true
security.disable_button.openCertManager: false
storage.vacuum.last.index: 1
storage.vacuum.last.places.sqlite: 1512884223

Important Locked Preferences
----------------------------

Places Database
---------------

JavaScript
----------

Incremental GC: true

Accessibility
-------------

Activated: false
Prevent Accessibility: 1

Library Versions
----------------

NSPR
Expected minimum version: 4.16
Version in use: 4.16

NSS
Expected minimum version: 3.32.1
Version in use: 3.32.1

NSSSMIME
Expected minimum version: 3.32.1
Version in use: 3.32.1

NSSSSL
Expected minimum version: 3.32.1
Version in use: 3.32.1

NSSUTIL
Expected minimum version: 3.32.1
Version in use: 3.32.1

Experimental Features
---------------------

Thanks for replying!

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35473
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by Moonchild » 2017-12-14, 05:59

So, the problem occurs on completely un-accelerated graphics for you with the cairo back-end. I'm actually surprised skia isn't selected as canvas back-end there (which should be the preferred rendering engine for canvas).

If you change gfx.canvas.azure.backends in about:config to read "skia" (and nothing else) and restart the browser, what are your results then? To verify, does help -> troubleshooting information in the Graphics section still show "cairo" under AzureCanvasBackend after you make this change?
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

smihaila

Re: HTML5 Canvas CanvasRenderingContext2D.scale/translate/setTransform() not working as expected

Unread post by smihaila » 2017-12-14, 15:34

You have a very interesting find here. After following upon your suggestion and setting gfx.canvas.azure.backends to "skia" instead of the default "cairo" value and restarting Palemoon, the ellipse shows up fine!

Speaking of graphics adapter + drivers, my PC is a desktop / tower PC @ work (Dell Precision T1700) and even though it may not have a discrete graphics card, I do recall installing the latest Intel official drivers (open source plus perhaps some binary blobs in them).
This is what I've used in terms of rpm / dnf packages from Intel:

cairo-gobject-1.15.4-25.intel20171.x86_64
intellinuxgraphics-repo-2.0.5-25.intel20171.noarch
intel-graphics-update-tool-2.0.5-25.intel20171.x86_64
xorg-x11-drv-intel-2.99.917-28.20160929.fc26.x86_64
cairo-1.15.4-25.intel20171.x86_64

I also recall the KDE 5' screen compositor using Open GL 2.0 so these Intel Linux drivers seem to feature a hardware acceleration of some sort?

I also checked what my Linux Firefox is having as default for the same gfx.canvas.azure.backends. And suprisingly, it is "skia".
It also has an additional gfx.canvas.skiagl.dynamic-cache bool value set to "true" (default).

Don't know where the low-level settings in Chrome are, to also check there.

What is this SKIA thing btw? :-)

Thanks so much.

Locked