yangqiaosheng / angleproject

Automatically exported from code.google.com/p/angleproject
Other
0 stars 0 forks source link

Diagonal screen tearing for WebGL content on GTX 970M with D3D11 and D3D9 ANGLE in Chrome #893

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
---------------------------------------

1. Visit these WebGL demos:

http://alteredqualia.com/xg/examples/deferred_skin.html
http://alteredqualia.com/three/examples/webgl_materials_bumpmap_skin.html
http://alteredqualia.com/three/examples/webgl_deferred_shadowmap_point.html

2. Move your mouse quickly left-to-right or diagonally so that camera angle 
changes.

3. Look for screen tearing artefacts.

What is the expected output? What do you see instead?
-----------------------------------------------------

WebGL content should look continuous. Instead there appear some sort of 
diagonal tears (starting upper-left going lower-right), as if parts of image 
came from one frame and parts from another one.

See attached image (ignore ghosting artefacts coming from phone camera). Please 
note that these artefacts don't appear on screenshots. They have to be seen 
with own eyes or taken photo.

What version of the product are you using? On what operating system?

Current stable Chrome 40 on Windows 8.1 64 bit. Also same issues appear in 
current Chrome Canary 42.

Important note: problems only show on my MSI GS60 2QE notebook with Nvidia GTX 
970M (running Optimus). On my Thinkpad W520 with Nvidia Quadro 2000M there is 
no tearing.

Please provide any additional information below.
------------------------------------------------

These problems seem to be very fickle. Dependent on very tiny framerate 
differences they may or may not exhibit in one or another of demos. That's why 
I put 3 tests. In general at least one of them should be showing tearing. 

It's much easier to get tearing in Chrome 35 than in Chrome Canary 42.

It's easier to get tearing with D3D11 ANGLE than D3D9 ANGLE.

I haven't observed yet tearing when running Chrome with OpenGL rendering 
backend.

Another way how to get tearing sometime is simply to open one of these demos, 
then open empty new tab, and quickly change between them with ctrl+tab. This 
sometimes lead to piece of white triangle shown in upper-left corner in WebGL 
content.

Running WebGL fullscreen (F11 key) seem to almost eliminate tearing, but this 
could be simply due to framerate difference induced by more pixels needing to 
be drawn.

Things I tried:

To see if this is GPU driver version or driver settings dependent:

- my current Nvidia GPU drivers are 347.09, I tried downgrading to 344.75 but 
tearing was still there
- also tried brand new 347.25 drivers from today (January 22) and tearing is 
still there
- I tried to enforce v-sync for Chrome in Nvidia Control Panel (instead of "use 
application preference"), still there was tearing

To see if other WebGL capable browsers show problems:

- Internet Explorer doesn't seem to have tearing
- Opera 26 with D3D9 ANGLE does have some tearing, though it's harder to induce 
(seems to happen there when framerate stutters)
- Firefox 35 with D3D9 ANGLE doesn't seem to have tearing (though Firefox 35 
had WebGL regress, so it can't run 2 out of 3 tests, see here 
https://bugzilla.mozilla.org/show_bug.cgi?id=1124187)

To see if this is some machine specific issue:

- running Chrome on Intel HD 4600 GPU (second GPU on the MSI notebook, it's 
Optimus) doesn't show tearing, though Intel GPU is much slower, so could simple 
never get problematic high framerates
- native 3D applications (games) can sometimes have tearing, but for games 
where I could explicitly verify that v-sync was enabled I haven't yet observed 
tearing
- YouTube video screen tearing test doesn't show any tearing in Chrome: 
https://www.youtube.com/watch?v=ceX18O9pvLs

To try to identify potential cause:

- those 3 tests use different rendering methods: three.js demos use full-screen 
quad or directly render to screen, XG demo uses full-screen triangle, so it 
doesn't seem it would be tear between two triangles on WebGL application side
- I haven't yet observed any tearing on WebGL demos with static camera, where 
instead content is moving, which could point either to some precision issue, or 
maybe just coincidence (moving camera manually quickly gets much bigger 
inter-frame differenes so tearing is easier to observe)

To see if this is three.js / XG specific issue:

- tested Tojiro's Quake 3 demo: http://media.tojicode.com/q3bsp/
   - it doesn't appear to have any tearing in regular browser session, though it does show tearing in WebVR session Oculus Rift DK2 in experimental Chrome build (in fact that's the first time I observed this issue)
   - this could be again just performance sensitivity: tears are harder to observe when they are small, VR makes them easier to see

- tested PlayCanvas Star Lord demo: http://playcanv.as/b/FQbBsJTd
  - tearing very noticeable when quickly dragging camera left-right, but just in D3D11 ANGLE

- tested ShaderToy
  - tearing happens occasionally, though it's hard to find shaders that would qualify: they must be fast to be safely over 60 fps, with camera controls and content that's clear enough to see difference between frames
  - one such example: https://www.shadertoy.com/view/ldfXzS (if you move mouse quickly up-down, there is diagonal tear between blue sky and brown ground)

Original issue reported on code.google.com by postfil...@gmail.com on 23 Jan 2015 at 4:03

Attachments:

GoogleCodeExporter commented 9 years ago
Additional info: I tried Tojiro's Chrome WebVR custom build forcing OpenGL 
rendering backend. There were no diagonal tears in Quake 3 demo.

It seems even that very first observation of tearing had the same cause. Also 
on Oculus Rift DK2 tearing appears just with ANGLE but not OpenGL (DK2 
connected via HDMI as primary display, running at 75 Hz).

While it's unfortunate that tearing now appears also on regular display, at 
least this should make it easier to replicate and debug than if it was just 
WebVR thing.

Original comment by postfil...@gmail.com on 28 Jan 2015 at 11:22

GoogleCodeExporter commented 9 years ago
Another observation that may indicate a potential source of tearing: I tried to 
see where exactly tearing was occuring when I resized Chrome window and moved 
it around the screen.

To my surprise that tear wasn't happening on the diagonal inside WebGL canvas 
content rectangle, or even on the diagonal within the rectangle inside the tab 
with WebGL content. 

Instead tear kept happening at the diagonal of rectangle inside the whole 
Chrome window, including navigation buttons chrome bar (except the top title 
bar Windows chrome) - see attached image.

This seems like it could be some compositor issue (or whatever Chrome component 
that's responsible for painting that rectangle, whose diagonal is tearing).

Original comment by postfil...@gmail.com on 31 Jan 2015 at 12:22

Attachments:

GoogleCodeExporter commented 9 years ago
New info: today I observed diagonal tearing happening also in Firefox Nightly 
(D3D11 ANGLE). 

Before a very recent update Firefox had a regress which prevented running 
multiple demos I used to test this issue (both with stable Firefox 35 and 
Nightly 38). The ones I could run didn't have tearing issues.

Now I can run also this one and it does show diagonal tearing:

http://alteredqualia.com/three/examples/webgl_deferred_shadowmap_point.html

Interestingly, in Firefox case tearing happens along a different diagonal than 
in Chrome: this time exactly inside WebGL canvas rectangle (as opposed to the 
whole browser rectangle in Chrome). See attached image.

Unlike Chrome, there is no tearing in Firefox when changing tabs (so less 
likely compositor issue there).

To make sure it's not some hardware issue on my notebook, I ran additional 
tests to see if I could replicate diagonal tears elsewhere. And so far I 
couldn't.

Applications without diagonal tears: Chrome with OpenGL rendering backend, 
Internet Explorer with D3D11 rendering backend, Half-life 2 (D3D9), Skyrim 
(D3D9), Tomb Raider (D3D11), Civilization V (D3D9 & D3D10/D3D11).

In games where I could explicitly disable v-sync, I was sometimes able to see 
horizontal tears, as expected, though never diagonal ones (it takes quite an 
effort, unlike those diagonal tears which are very obvious).

So my working theory is: there are at least two places where this happens. 
Likely Chrome compositor and then maybe also something in ANGLE. Both likely 
sharing the same root cause, but manifested in different parts of codebase. 
Could be some implementation assumption which doesn't hold for Maxwell GPUs (or 
maybe just notebook variants of Maxwell GPUs running with Optimus).

Original comment by postfil...@gmail.com on 31 Jan 2015 at 6:38

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Hi, thanks for putting together this information postfilter. I'm not sure if 
I've seen this tearing myself, and my quick attempts to repro didn't work on my 
Quadro 600. I don't think we have an Optimus system here, but we might be able 
to procure one. If it is a regression issue it's potentially fixable, but we've 
had a ton of problems in general with Optimus and switchable-GPU systems.

Original comment by jmad...@chromium.org on 2 Feb 2015 at 2:53

GoogleCodeExporter commented 9 years ago
Finally I was able to observe those diagonal artefacts also elsewhere. Seems 
troubles may go deeper than just Chrome or ANGLE.

I remembered Tojiro mentioning in Windows true full-screen mode is somehow 
special, and that Chrome can't easily use it, so it always runs just in some 
different mode, even if it appears as if was full-screen (this was in the 
context of WebVR).

So I did try running a game (Stanley Parable) in windowed mode and lo and 
behold: diagonal tearing artefacts were there, independent of v-sync setting 
(off/double-buffered/tripple-buffered). When running in full-screen mode, there 
were no artefacts when v-sync was on. When v-sync was off there was just the 
usual (and expected) horizontal tearing.

I tried also Talos Principle, which like Chrome has three different rendering 
backends (DX11, DX9, OpenGL). In fullscreen mode there was no tearing (as 
everywhere else I tried so far). In windowed mode only DX9 renderer had 
diagonal tearing, DX11 and OpenGL ones didn't have any.

So it could be for example Desktop Window Manager that's messing up content it 
gets from 3D applications. Additional info: that GTX 970M notebook is running 
Windows 8.1 (unlike other Quadro 2000M one, without tearing, which runs on 
Windows 7).

Original comment by postfil...@gmail.com on 2 Feb 2015 at 10:34

GoogleCodeExporter commented 9 years ago
And new info that should help to narrow this tricky issue down:

Finally these troubles were replicated also on a different machine than my 
notebook (I keep asking people I know). This should rule out faulty GPU on my 
particular notebook unit.

It was also MSI GS60, but a different model, with GTX 870M (vs my GTX 970M). 
This is Kepler GPU, so those problems are not happening just with Maxwell GPUs.

Another clue: I tried running Chrome in "Windows 8 mode" and I didn't observe 
any tearings.

Also I was able to observe tearings even just with regular HTML content, no 
WebGL needed, though again just when running Chrome with ANGLE rendering 
backend, not OpenGL one.

Tearing can be replicated for example also with this YouTube video (epilepsy 
warning, these are rapidly strobing colors):

https://www.youtube.com/watch?v=AjbrmfjJRk0

Also for example opening one black and one white page and just quickly changing 
tabs.

So my updated guess would be: there is some extra fast DirectX pipeline in 
Chrome compositor that's not doing proper syncing, with problems noticeable 
especially on very fast GPUs (e.g. my framerates for those WebGL demos I 
noticed it first are ~200 fps without v-sync), likely just on Windows 8 (and 
possibly just with Optimus).

This seems to be quite common issue, probably something that's easy to miss, as 
other applications suffer from those artefacts too (in windowed mode). 

But, as there are also applications that don't have those artefacts in windowed 
mode, it should be definitely possible to fix this (e.g. Internet Explorer or 
Talos Principle).

Original comment by postfil...@gmail.com on 5 Feb 2015 at 8:26

GoogleCodeExporter commented 9 years ago
@postfilter: I've asked NVIDIA for help with this. It looks to me like the 
synchronization problem is in Windows' compositor itself. Chrome does not draw 
a single full-window quad for the region in which you're seeing the tearing. 
Windows' compositor, on the other hand, will, I believe -- that looks like the 
client region of the window. (The non-client region, including the tab strip, 
is drawn in a separate pass I think.)

Original comment by kbr@chromium.org on 5 Feb 2015 at 10:55

GoogleCodeExporter commented 9 years ago
@kbr Thanks for looking into this. It's really weird problem. 

My bet would be also on Windows compositor (in Windows 8 it's apparently doing 
double-buffering no matter what, so there should be no tearing, unless 
application feeds DWM already mixed up frames, e.g. from multi-threaded 
rendering?). 

Just I'm puzzled that some applications apparently don't have this problem 
(especially Explorer, which could point to Microsoft doing something others are 
not aware of).

Also maybe some clue is what are differences in Chrome vs Windows 8 (desktop 
window manager) cooperation in these different modes (which do lead to 
different results):

- ANGLE rendering backend (desktop mode): tearing
- OpenGL rendering backend (desktop mode): no tearing
- ANGLE rendering backend (Windows 8 mode): no tearing

Maybe those non-tearing modes have some extra framebuffer copy step that 
fixes/hides the issue?

Original comment by postfil...@gmail.com on 5 Feb 2015 at 11:34

GoogleCodeExporter commented 9 years ago
Again, since you've seen this with native applications, I highly doubt it is 
something Chrome is doing specifically.

My understanding is that Chrome's Windows 8 mode does in fact incur another 
texture copy.

The bug may be lack of synchronization in the driver when the app is doing many 
draw calls to the window's "real" back buffer, and Windows is picking up that 
result to draw via its compositor.

Original comment by kbr@chromium.org on 6 Feb 2015 at 1:46

GoogleCodeExporter commented 9 years ago

Original comment by kbr@chromium.org on 6 Feb 2015 at 10:19

GoogleCodeExporter commented 9 years ago
I did some more observations, now on my Thinkpad with Quadro 2000M and Windows 
7:

I managed to get Chrome running there with Optimus on Nvidia GPU. I couldn't 
replicate tearing there. So it seems to be just Windows 8 thing, or Kepler and 
Maxwell GPU thing (Quadro 2000M is Fermi), or maybe Optimus on Intel HD 4600 
thing (Quadro goes with Intel HD 3000, GTX 970M and 870M both had HD 4600 
iGPUs).

Then I tried running Windows 7 in basic mode (as opposed to Aero) and surprise: 
there was pretty bad tearing, but now in usual horizontal stripes.

Which would suggest Chrome doesn't do any v-syncing (or double-buffering) on 
its own? Seems it just relies on Windows (which in Win7 basic mode apparently 
doesn't do anything to prevent tearing and in Win8 it may have some bugs?).

Original comment by postfil...@gmail.com on 7 Feb 2015 at 12:31

GoogleCodeExporter commented 9 years ago
Another confirmation of those tearing artefacts, now on a completely different 
notebook and GPU (but still with Windows 8 and Optimus) - Clevo P651SG with GTX 
980M:

https://forums.geforce.com/default/topic/809482/geforce-mobile-gpus/strange-scre
en-tearing-in-directx-windowed-mode-on-gtx-970m-amp-gtx-870m/

So far all three systems with artefacts have in common: Windows 8.1, Nvidia 
Optimus, Intel HD4600 iGPU.

Original comment by postfil...@gmail.com on 7 Feb 2015 at 3:05

GoogleCodeExporter commented 9 years ago
I accidentally ran into this while investigating a separate Chrome issue: there 
is a special Chromium build for checking v-sync related animation jerkiness:

https://code.google.com/p/chromium/issues/detail?id=422000#c97

When running that Chromium build with "--software-vsync-only" flag, I don't see 
any tearings anymore. With no flags or "--hardware-vsync-only" flags tearings 
are still there as usual.

So if that option would end up being adopted into regular Chrome, it would fix 
(or mask) this tearing issue.

Original comment by postfil...@gmail.com on 8 Feb 2015 at 11:48

GoogleCodeExporter commented 9 years ago
That "software-vsync-only" option turned out to be indeed just masking the real 
issue. Later on I was able to induce tearing by resizing Chrome tab e.g. when 
opening console or going fullscreen. 

Just browsing through multiple WebGL demos with "software-vsync-only" seems ok 
(unlike regular Chrome which tears immediately).

Original comment by postfil...@gmail.com on 9 Feb 2015 at 12:42

GoogleCodeExporter commented 9 years ago
I do not think this is an ANGLE, Windows 8, or video card specific bug.

With the webgl_deferred_shadowmap_point.html demo, I can reproduce the tearing 
under 64-bit Windows 7 Chrome Version 42.0.2301.0 canary with both the D3D11 
ANGLE and OpenGL backend.

I can also reproduce this under Firefox 38.0a1 Nightly with the D3D11 ANGLE 
backend, webgl.angle.try-d3d11 = FALSE, and webgl.disable-angle=TRUE.

GL_RENDERER GeForce GTX 650/PCIe/SSE2
GL_VERSION  4.5.0 NVIDIA 347.25

Original comment by lukebe...@gmail.com on 11 Feb 2015 at 8:29

GoogleCodeExporter commented 9 years ago
@lukebe Thanks. That's very intriguing. Having artefacts replicated on your 
system busted all my assumptions (you are first one to see them on 
Win7/OpenGL/desktop GPU).

Based on GPU I presume it's a desktop PC, so also no Optimus there (or whatever 
desktops use to deal with secondary Intel GPUs, if you have any)?

Also, just to make sure - the shape of tearings you have seen is diagonal / 
triangular (not pure horizontal strips)?

As for example here:

http://i.imgur.com/9XINNLZ.jpg
http://i.imgur.com/ldwUxBL.jpg

Did you ever observe such tearings before (I see you are on 347.25 drivers)? 

Now I'm trying to figure out if it's not maybe some Nvidia drivers bug. But on 
my MSI GS60 drivers go back just to 344.24 (first 900 Maxwell drivers, from 
October 2014), and with those artefacts are still there. 

Maybe for your GTX 650 you could try some really old drivers to see if problems 
are still there? First one for GTX 650 is 331.58 (October 2013):

http://www.nvidia.com/Download/Find.aspx?lang=en-us

Original comment by postfil...@gmail.com on 11 Feb 2015 at 9:12

GoogleCodeExporter commented 9 years ago
To clarify, what I said early was only in reference to the 
webgl_deferred_shadowmap_point.html demo. For most other demos such as 
webgl_materials_bumpmap_skin.html, I can only reproduce the tearing with the 
ANGLE back-end in chrome. The openGL back-end does not tear. Yet Firefox has 
tearing issues with both.

I took pictures of all the tearing instances, and it was always a horizontal 
line. And yes, it's a desktop GPU. I'm a big gamer and haven't noticed any 
tearing in desktop games.

Original comment by lukebe...@gmail.com on 11 Feb 2015 at 11:08

GoogleCodeExporter commented 9 years ago
@lukebe Thanks. It seems your tearing artefacts are different from the ones I 
get. Horizontal lines are what you get when v-sync doesn't work (or isn't 
enabled). That could explain why your system doesn't fit the profile (Win8, 
Optimus, DirectX). 

So your artefacts could have a different cause than those diagonal/triangular 
ones. I tried to search the web for GTX 650 artefacts, you may be affected by 
something like these folks (it's GeForce Linux subforum but some commenters 
were reporting such problems also on Windows):

https://devtalk.nvidia.com/default/topic/543305/linux/screen-video-tearing-gtx6x
x-7xx-kepler-9xx-maxwell-in-almost-all-applications-including-desktop/

You may try either disabling or enabling Aero (some people apparently get those 
horizontal tears just with Basic/Classic themes, some just with Aero).

Original comment by postfil...@gmail.com on 12 Feb 2015 at 12:04

GoogleCodeExporter commented 9 years ago
@postfil
Good call. Enabling Aero fixed all the tearing issues in both Chrome and 
Firefox. Sorry for the noise. 

Original comment by lukebe...@gmail.com on 12 Feb 2015 at 3:29

GoogleCodeExporter commented 9 years ago
And meanwhile we've got confirmations from even more affected systems (I'm 
trying to both ask around the web and try notebooks I can physically access). 

So far those tearings were confirmed on at least six different notebooks, with 
six different GPUs, from three different manufacturers:

MSI GS60 with GTX 970M 3 GB, Intel HD 4600 and 1080p screen (60Hz, Optimus, 
Windows 8.1)
MSI GS60 with GTX 870M 3 GB, Intel HD 4600 and 1080p screen (60Hz, Optimus, 
Windows 8.1)
Clevo P651SG with GTX 980M 4 GB, Intel HD 4600 and 4K screen (60Hz, Optimus, 
Windows 8.1)
Clevo P650SE with GTX 970m 3 GB, Intel HD 4600 and 1080p screen (60Hz, Optimus, 
Windows 8.1)
Clevo P650SA with GTX 965m 2 GB, Intel HD 4600 and 1080p screen (60Hz, Optimus, 
Windows 8.1)
Lenovo Y50-70 with GTX 860M, Intel HD 4600 (Optimus, Windows 8.1)

Common to all are: Windows 8.1, Intel HD 4600, Nvidia Optimus.

Original comment by postfil...@gmail.com on 22 Feb 2015 at 1:44