Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use EGL Sync Objects to ensure that shared WebGL textures are ready to be used #1407

Merged
merged 1 commit into from Jul 5, 2017

Conversation

@MortimerGoro
Copy link
Contributor

MortimerGoro commented Jun 20, 2017

Currently a glFlush call is issued at the start of the frame to guarantee that shared WebGL texture data is valid. But glFlush is not enough in some GPUs because it doesn't guarantee the completion of the GL commands when the shared texture is sampled. This leads to some graphic glitches on some demos or even nothing being rendered at all (GPU Mali-T880). glFinish guarantees the completion of the commands but it may hurt performance a lot.

Sync objects are the recommended way to ensure that textures are ready in OpenGL 3.0+. They are more performant than glFinish and guarantee the completion of the GL commands.

I added dirty checking so the sync is only performed when WebGL contexts are being used. This PR might be improved if we move the glClientWaitSync to the WR render thread (before the shared texture is used). The parallelism should be better that way. I don know where is the best place to add the sync wait in WR. If you can guide me on that I'll update the PR.


This change is Reviewable

if self.dirty_webgl_contexts.contains(&id) {
webgl_context.make_current();
// Call FenceSync and ClientWaitSync to ensure that textures are ready.
let sync = webgl_context.gl().fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0);

This comment has been minimized.

@kvark

kvark Jun 20, 2017

Member

we shouldn't be calling any GL functions directly from render_backend

This comment has been minimized.

@MortimerGoro

MortimerGoro Jun 20, 2017

Author Contributor

Do you mean that they should be called using WebGLCommand enum? (as it was done with the existing glFlush call)

This comment has been minimized.

@kvark

kvark Jun 20, 2017

Member

I suppose, yes. Just don't assume there is GL under the hood.

// Sync objects are the recommended way to ensure that textures are ready in OpenGL 3.0+.
// They are more performant than glFinish and guarantee the completion of the GL commands.
for (id, webgl_context) in &self.webgl_contexts {
if self.dirty_webgl_contexts.contains(&id) {

This comment has been minimized.

@kvark

kvark Jun 20, 2017

Member

could be if self.dirty_webgl_context.remove(&id) {..}

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:glsync branch from 57bfec3 to 939400e Jun 20, 2017
@glennw
Copy link
Member

glennw commented Jun 20, 2017

glClientWaitSync is only available on desktop GL 3.2+, I believe. Although we currently do require 3.2, we're meant to be dropping required desktop GL to 3.1...

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:glsync branch from 939400e to 9dd0cee Jun 20, 2017
@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Jun 20, 2017

glClientWaitSync is only available on desktop GL 3.2+, I believe. Although we currently do require 3.2, we're meant to be dropping required desktop GL to 3.1...

Yes, glClientWaitSync is available in GL 3.2+ and GL ES 3.0+. We could check if GL_ARB_sync extension is available in GL 3.1 and fallback to glFlush/glFinish if not. Do you want to do that in this PR or create an issue or handle this in the future WebGL separate crate?

@glennw
Copy link
Member

glennw commented Jun 20, 2017

That's fine to do it as a follow up, so long as we have a valid fallback plan (which it sounds like we do).

Thanks!

@bors-servo
Copy link
Contributor

bors-servo commented Jun 22, 2017

The latest upstream changes (presumably #1409) made this pull request unmergeable. Please resolve the merge conflicts.

@glennw
Copy link
Member

glennw commented Jul 5, 2017

@MortimerGoro This needs a rebase.

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:glsync branch from 9dd0cee to 5881d33 Jul 5, 2017
@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Jul 5, 2017

Done!

Copy link
Member

glennw left a comment

One question, otherwise looks good.

// Call FenceSync and ClientWaitSync to ensure that textures are ready.
let sync = gl.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0);
// SYNC_FLUSH_COMMANDS_BIT is used to automatically generate a glFlush before blocking on the sync object.
gl.client_wait_sync(sync, gl::SYNC_FLUSH_COMMANDS_BIT, gl::TIMEOUT_IGNORED);

This comment has been minimized.

@glennw

glennw Jul 5, 2017

Member

Why does this need to be a glClientWaitSync ? Wouldn't a glWaitSync be more appropriate in this case, so that the CPU isn't blocked? I would have though a glWaitSync would be enough to sync between the two command streams?

This comment has been minimized.

@MortimerGoro

MortimerGoro Jul 5, 2017

Author Contributor

Yes, glWaitSync is enough. Just tried and it works ok.

@MortimerGoro MortimerGoro force-pushed the MortimerGoro:glsync branch from 5881d33 to 969a0d6 Jul 5, 2017
@glennw
glennw approved these changes Jul 5, 2017
@glennw
Copy link
Member

glennw commented Jul 5, 2017

Looks good, thanks!

@bors-servo r+

@bors-servo
Copy link
Contributor

bors-servo commented Jul 5, 2017

📌 Commit 969a0d6 has been approved by glennw

@bors-servo
Copy link
Contributor

bors-servo commented Jul 5, 2017

Testing commit 969a0d6 with merge 0fc57c6...

bors-servo added a commit that referenced this pull request Jul 5, 2017
Use EGL Sync Objects to ensure that shared WebGL textures are ready to be used

Currently a glFlush call is issued at the start of the frame to guarantee that shared WebGL texture data is valid. But glFlush is not enough in some GPUs because it doesn't guarantee the completion of the GL commands when the shared texture is sampled. This leads to some graphic glitches on some demos or even nothing being rendered at all (GPU Mali-T880).  glFinish guarantees the completion of the commands but it may hurt performance a lot.

Sync objects are the recommended way to ensure that textures are ready in OpenGL 3.0+. They are more performant than glFinish and guarantee the completion of the GL commands.

I added dirty checking so the sync is only performed when WebGL contexts are being used. This PR might be improved if we move the glClientWaitSync to the WR render thread (before the shared texture is used). The parallelism should be better that way. I don know where is the best place to add the sync wait in WR. If you can guide me on that I'll update the PR.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/1407)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jul 5, 2017

☀️ Test successful - status-travis
Approved by: glennw
Pushing 0fc57c6 to master...

@bors-servo bors-servo merged commit 969a0d6 into servo:master Jul 5, 2017
3 checks passed
3 checks passed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
mrobinson added a commit to mrobinson/webrender that referenced this pull request Jul 12, 2017
This change caused many WebGL tests to fail in Servo, which is blocking
the WebRender update. Partially revert the change in order to reland it
later with the issue properly fixed.
@mrobinson
Copy link
Member

mrobinson commented Jul 12, 2017

This change is causing many Servo WebGL tests to fail, so I posted a PR to partially revert this (temporarily) in order to move the WebRender update forward. Sorry!

#1471

@MortimerGoro
Copy link
Contributor Author

MortimerGoro commented Jul 12, 2017

Ok, no problem. I'm working on #1353 so the WebGL code will be refactored to a new component. I'll check all the WebGL tests after the refactor.

bors-servo added a commit that referenced this pull request Jul 12, 2017
Partially revert #1407

This change caused many WebGL tests to fail in Servo, which is blocking
the WebRender update. Partially revert the change in order to reland it
later with the issue properly fixed.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/1471)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants
You can’t perform that action at this time.