{"action":"created","comment":{"url":"https://api.github.com/repos/kripken/emscripten/pulls/comments/68384146","id":68384146,"diff_hunk":"@@ -416,6 +465,69 @@ var LibraryPThread = {\n       Module['printErr']('pthread_create called with a null thread pointer!');\n       return {{{ cDefine('EINVAL') }}};\n     }\n+\n+    // Deduce which WebGL canvases (HTMLCanvasElements or OffscreenCanvases) should be passed over to the\n+    // Worker that hosts the spawned pthread.\n+    var transferedCanvasNames = {{{ makeGetValue('attr', 36, 'i32') }}}; // Comma-delimited list of IDs \"canvas1, canvas2, ...\"\n+    if (transferedCanvasNames) {\n+      transferedCanvasNames = Pointer_stringify(transferedCanvasNames);\n+      transferedCanvasNames = transferedCanvasNames.split(',');\n+    }\n+    var offscreenCanvases = {}; // Dictionary of OffscreenCanvas objects we'll transfer to the created thread to own\n+    var transferList = []; // List of JS objects that will transfer ownership to the Worker hosting the thread\n+    for (var i in transferedCanvasNames) {\n+      var name = transferedCanvasNames[i].trim();\n+      var offscreenCanvas;\n+      try {\n+        if (name == '#canvas') {\n+          if (GL.offscreenCanvases[Module['canvas'].id]) {\n+            offscreenCanvas = GL.offscreenCanvases[Module['canvas'].id];\n+            GL.offscreenCanvases[Module['canvas'].id] = null;\n+          }\n+          else if (Module['canvas'] instanceof OffscreenCanvas) {\n+            offscreenCanvas = Module['canvas'];\n+            Module['canvas'] = null;\n+          }\n+          else {\n+            if (Module['canvas'].controlTransferredOffscreen) {\n+              Module['printErr']('pthread_create: cannot transfer canvas with ID \"' + name + '\" to thread, since the current thread does not have control over it!');\n+              return {{{ cDefine('EINVAL') }}};\n+            }\n+            offscreenCanvas = Module['canvas'].transferControlToOffscreen();\n+            Module['canvas'].controlTransferredOffscreen = true;\n+          }\n+          offscreenCanvas.id = Module['canvas'].id;\n+        } else if (GL.offscreenCanvases[name]) {\n+          offscreenCanvas = GL.offscreenCanvases[name];\n+          GL.offscreenCanvases[name] = null; // This thread no longer owns this canvas.\n+        } else {\n+          var canvas = document.getElementByID(name);\n+          if (!canvas) {\n+            Module['printErr']('pthread_create: could not find canvas with ID \"' + name + '\" to transfer to thread!');\n+            return {{{ cDefine('EINVAL') }}};\n+          }\n+          if (canvas.controlTransferredOffscreen) {","path":"src/library_pthread.js","position":171,"original_position":171,"commit_id":"078b98e27259700b09143e844f14e65017257fd3","original_commit_id":"078b98e27259700b09143e844f14e65017257fd3","user":{"login":"OleksandrChekhovskyi","id":11211653,"avatar_url":"https://avatars.githubusercontent.com/u/11211653?v=3","gravatar_id":"","url":"https://api.github.com/users/OleksandrChekhovskyi","html_url":"https://github.com/OleksandrChekhovskyi","followers_url":"https://api.github.com/users/OleksandrChekhovskyi/followers","following_url":"https://api.github.com/users/OleksandrChekhovskyi/following{/other_user}","gists_url":"https://api.github.com/users/OleksandrChekhovskyi/gists{/gist_id}","starred_url":"https://api.github.com/users/OleksandrChekhovskyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OleksandrChekhovskyi/subscriptions","organizations_url":"https://api.github.com/users/OleksandrChekhovskyi/orgs","repos_url":"https://api.github.com/users/OleksandrChekhovskyi/repos","events_url":"https://api.github.com/users/OleksandrChekhovskyi/events{/privacy}","received_events_url":"https://api.github.com/users/OleksandrChekhovskyi/received_events","type":"User","site_admin":false},"body":"Very similar code to the block above, could be refactored to be shared.","created_at":"2016-06-24T11:09:49Z","updated_at":"2016-06-24T11:09:49Z","html_url":"https://github.com/kripken/emscripten/pull/4412#discussion_r68384146","pull_request_url":"https://api.github.com/repos/kripken/emscripten/pulls/4412","_links":{"self":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/comments/68384146"},"html":{"href":"https://github.com/kripken/emscripten/pull/4412#discussion_r68384146"},"pull_request":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/4412"}}},"pull_request":{"url":"https://api.github.com/repos/kripken/emscripten/pulls/4412","id":75022865,"html_url":"https://github.com/kripken/emscripten/pull/4412","diff_url":"https://github.com/kripken/emscripten/pull/4412.diff","patch_url":"https://github.com/kripken/emscripten/pull/4412.patch","issue_url":"https://api.github.com/repos/kripken/emscripten/issues/4412","number":4412,"state":"open","locked":false,"title":"offscreencanvas_support","user":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"body":"Implements support for transfering WebGL contexts to pthreads and rendering via using OffscreenCanvas.\r\n\r\nThis PR adds support for rendering in pthreads via the OffscreenCanvas object. The logic and semantics are as discussed in #4303, notably:\r\n\r\n   - at pthread creation time, one can signal in the `pthread_attr_t` object a list of canvases to transfer to the pthread. Transferring a canvas to a pthread means that the pthread takes exclusive ownership of manipulating the canvas via WebGL in that thread. As an invariant, each canvas is owned by a single thread at any given time.\r\n   - this signaling is performed by calling the function `emscripten_pthread_attr_settransferedcanvases` on the attribute object before creating the thread. After a thread is created, canvases cannot be transfered into it (at least not right now, though this would be possible to add support for later if needed).\r\n   - a requirement for transferring is that the calling thread owns the canvas and doesn't have any GL contexts currently active on that canvas.\r\n   - when a thread quits, the ownership of all its canvases fall back to its parent thread.\r\n\r\nThe PR also adds a new property for all GL contexts: implicit vs explicit swap control. Implicit swap control mode is the default and aligns with the existing behavior: when one returns from `rAF` event handler, GL buffer swap implicitly occurs. In explicit swap control mode, one instead manually uses the function `emscripten_webgl_commit_frame()` to present the rendered content.\r\n\r\nThe implicit vs explicit swap control modes are symmetrically available to all threads, i.e. including the main thread. Since explicit swap control mode is implemented by using the `OffscreenCanvas` API, GL context creation will fail in C-like manner (return value instead of aborting the page on an exception) if the API is not supported.\r\n\r\n@OleksandrChekhovskyi highlighted an OffscreenCanvas API limitation that once a regular HTMLCanvasElement is once turned into an OffscreenCanvas, it cannot be reverted back in the current spec form. This is hidden under the hood by noting that if one is limited to operating on an OffscreenCanvas (which always has explicit swap control), we perform the implicit swap for the user if implicit swap had been requested at WebGL context creation time.\r\n\r\nWill need documentation and cross-browser testing (tried Firefox Nightly only so far), but posting the PR for review first to discuss the API before writing. Also, it should be noted that OffscreenCanvas is still an unstable draft, so it's unclear if things might change there at some point.","created_at":"2016-06-23T20:36:56Z","updated_at":"2016-06-24T11:09:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"13e2c24d8b9ec855fbc37c1b67a167b4eda42e19","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/kripken/emscripten/pulls/4412/commits","review_comments_url":"https://api.github.com/repos/kripken/emscripten/pulls/4412/comments","review_comment_url":"https://api.github.com/repos/kripken/emscripten/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kripken/emscripten/issues/4412/comments","statuses_url":"https://api.github.com/repos/kripken/emscripten/statuses/078b98e27259700b09143e844f14e65017257fd3","head":{"label":"juj:offscreencanvas_support","ref":"offscreencanvas_support","sha":"078b98e27259700b09143e844f14e65017257fd3","user":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"repo":{"id":4149606,"name":"emscripten","full_name":"juj/emscripten","owner":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/juj/emscripten","description":"Emscripten: An LLVM-to-JavaScript Compiler","fork":true,"url":"https://api.github.com/repos/juj/emscripten","forks_url":"https://api.github.com/repos/juj/emscripten/forks","keys_url":"https://api.github.com/repos/juj/emscripten/keys{/key_id}","collaborators_url":"https://api.github.com/repos/juj/emscripten/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/juj/emscripten/teams","hooks_url":"https://api.github.com/repos/juj/emscripten/hooks","issue_events_url":"https://api.github.com/repos/juj/emscripten/issues/events{/number}","events_url":"https://api.github.com/repos/juj/emscripten/events","assignees_url":"https://api.github.com/repos/juj/emscripten/assignees{/user}","branches_url":"https://api.github.com/repos/juj/emscripten/branches{/branch}","tags_url":"https://api.github.com/repos/juj/emscripten/tags","blobs_url":"https://api.github.com/repos/juj/emscripten/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/juj/emscripten/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/juj/emscripten/git/refs{/sha}","trees_url":"https://api.github.com/repos/juj/emscripten/git/trees{/sha}","statuses_url":"https://api.github.com/repos/juj/emscripten/statuses/{sha}","languages_url":"https://api.github.com/repos/juj/emscripten/languages","stargazers_url":"https://api.github.com/repos/juj/emscripten/stargazers","contributors_url":"https://api.github.com/repos/juj/emscripten/contributors","subscribers_url":"https://api.github.com/repos/juj/emscripten/subscribers","subscription_url":"https://api.github.com/repos/juj/emscripten/subscription","commits_url":"https://api.github.com/repos/juj/emscripten/commits{/sha}","git_commits_url":"https://api.github.com/repos/juj/emscripten/git/commits{/sha}","comments_url":"https://api.github.com/repos/juj/emscripten/comments{/number}","issue_comment_url":"https://api.github.com/repos/juj/emscripten/issues/comments{/number}","contents_url":"https://api.github.com/repos/juj/emscripten/contents/{+path}","compare_url":"https://api.github.com/repos/juj/emscripten/compare/{base}...{head}","merges_url":"https://api.github.com/repos/juj/emscripten/merges","archive_url":"https://api.github.com/repos/juj/emscripten/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/juj/emscripten/downloads","issues_url":"https://api.github.com/repos/juj/emscripten/issues{/number}","pulls_url":"https://api.github.com/repos/juj/emscripten/pulls{/number}","milestones_url":"https://api.github.com/repos/juj/emscripten/milestones{/number}","notifications_url":"https://api.github.com/repos/juj/emscripten/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/juj/emscripten/labels{/name}","releases_url":"https://api.github.com/repos/juj/emscripten/releases{/id}","deployments_url":"https://api.github.com/repos/juj/emscripten/deployments","created_at":"2012-04-26T16:19:07Z","updated_at":"2015-10-14T22:05:06Z","pushed_at":"2016-06-23T20:35:15Z","git_url":"git://github.com/juj/emscripten.git","ssh_url":"git@github.com:juj/emscripten.git","clone_url":"https://github.com/juj/emscripten.git","svn_url":"https://github.com/juj/emscripten","homepage":"","size":135313,"stargazers_count":3,"watchers_count":3,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":3,"default_branch":"master"}},"base":{"label":"kripken:incoming","ref":"incoming","sha":"e2276a93cde6af63dcf425626c29ee40d2a8bb88","user":{"login":"kripken","id":173661,"avatar_url":"https://avatars.githubusercontent.com/u/173661?v=3","gravatar_id":"","url":"https://api.github.com/users/kripken","html_url":"https://github.com/kripken","followers_url":"https://api.github.com/users/kripken/followers","following_url":"https://api.github.com/users/kripken/following{/other_user}","gists_url":"https://api.github.com/users/kripken/gists{/gist_id}","starred_url":"https://api.github.com/users/kripken/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kripken/subscriptions","organizations_url":"https://api.github.com/users/kripken/orgs","repos_url":"https://api.github.com/users/kripken/repos","events_url":"https://api.github.com/users/kripken/events{/privacy}","received_events_url":"https://api.github.com/users/kripken/received_events","type":"User","site_admin":false},"repo":{"id":1357796,"name":"emscripten","full_name":"kripken/emscripten","owner":{"login":"kripken","id":173661,"avatar_url":"https://avatars.githubusercontent.com/u/173661?v=3","gravatar_id":"","url":"https://api.github.com/users/kripken","html_url":"https://github.com/kripken","followers_url":"https://api.github.com/users/kripken/followers","following_url":"https://api.github.com/users/kripken/following{/other_user}","gists_url":"https://api.github.com/users/kripken/gists{/gist_id}","starred_url":"https://api.github.com/users/kripken/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kripken/subscriptions","organizations_url":"https://api.github.com/users/kripken/orgs","repos_url":"https://api.github.com/users/kripken/repos","events_url":"https://api.github.com/users/kripken/events{/privacy}","received_events_url":"https://api.github.com/users/kripken/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kripken/emscripten","description":"Emscripten: An LLVM-to-JavaScript Compiler","fork":false,"url":"https://api.github.com/repos/kripken/emscripten","forks_url":"https://api.github.com/repos/kripken/emscripten/forks","keys_url":"https://api.github.com/repos/kripken/emscripten/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kripken/emscripten/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kripken/emscripten/teams","hooks_url":"https://api.github.com/repos/kripken/emscripten/hooks","issue_events_url":"https://api.github.com/repos/kripken/emscripten/issues/events{/number}","events_url":"https://api.github.com/repos/kripken/emscripten/events","assignees_url":"https://api.github.com/repos/kripken/emscripten/assignees{/user}","branches_url":"https://api.github.com/repos/kripken/emscripten/branches{/branch}","tags_url":"https://api.github.com/repos/kripken/emscripten/tags","blobs_url":"https://api.github.com/repos/kripken/emscripten/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kripken/emscripten/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kripken/emscripten/git/refs{/sha}","trees_url":"https://api.github.com/repos/kripken/emscripten/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kripken/emscripten/statuses/{sha}","languages_url":"https://api.github.com/repos/kripken/emscripten/languages","stargazers_url":"https://api.github.com/repos/kripken/emscripten/stargazers","contributors_url":"https://api.github.com/repos/kripken/emscripten/contributors","subscribers_url":"https://api.github.com/repos/kripken/emscripten/subscribers","subscription_url":"https://api.github.com/repos/kripken/emscripten/subscription","commits_url":"https://api.github.com/repos/kripken/emscripten/commits{/sha}","git_commits_url":"https://api.github.com/repos/kripken/emscripten/git/commits{/sha}","comments_url":"https://api.github.com/repos/kripken/emscripten/comments{/number}","issue_comment_url":"https://api.github.com/repos/kripken/emscripten/issues/comments{/number}","contents_url":"https://api.github.com/repos/kripken/emscripten/contents/{+path}","compare_url":"https://api.github.com/repos/kripken/emscripten/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kripken/emscripten/merges","archive_url":"https://api.github.com/repos/kripken/emscripten/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kripken/emscripten/downloads","issues_url":"https://api.github.com/repos/kripken/emscripten/issues{/number}","pulls_url":"https://api.github.com/repos/kripken/emscripten/pulls{/number}","milestones_url":"https://api.github.com/repos/kripken/emscripten/milestones{/number}","notifications_url":"https://api.github.com/repos/kripken/emscripten/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kripken/emscripten/labels{/name}","releases_url":"https://api.github.com/repos/kripken/emscripten/releases{/id}","deployments_url":"https://api.github.com/repos/kripken/emscripten/deployments","created_at":"2011-02-12T05:23:30Z","updated_at":"2016-06-24T07:07:39Z","pushed_at":"2016-06-23T21:39:07Z","git_url":"git://github.com/kripken/emscripten.git","ssh_url":"git@github.com:kripken/emscripten.git","clone_url":"https://github.com/kripken/emscripten.git","svn_url":"https://github.com/kripken/emscripten","homepage":"","size":169457,"stargazers_count":10320,"watchers_count":10320,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1265,"mirror_url":null,"open_issues_count":812,"forks":1265,"open_issues":812,"watchers":10320,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/4412"},"html":{"href":"https://github.com/kripken/emscripten/pull/4412"},"issue":{"href":"https://api.github.com/repos/kripken/emscripten/issues/4412"},"comments":{"href":"https://api.github.com/repos/kripken/emscripten/issues/4412/comments"},"review_comments":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/4412/comments"},"review_comment":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kripken/emscripten/pulls/4412/commits"},"statuses":{"href":"https://api.github.com/repos/kripken/emscripten/statuses/078b98e27259700b09143e844f14e65017257fd3"}}}}
{"actor":{"display_login":"OleksandrChekhovskyi"}}