title: Is it possible to prevent tearing artifacts when drawing using GDI on a window with DWM composition?
body: <p>I am drawing an animation using double-buffered GDI on a window, on a system where DWM composition is enabled, and seeing clearly visible <a href="https://en.wikipedia.org/wiki/Screen_tearing">tearing</a> onscreen.  Is there a way to prevent this?</p>
  
  <h1>Details</h1>
  
  <p>The animation takes the same image, and moves it right to left over the screen; the number of pixels across is determined by the difference between the current time and the time the animation started and the time to end, to get a fraction complete which is applied to the whole window width, using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx"><code>timeGetTime</code></a> with a <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v=vs.85).aspx">1ms resolution</a>. The animation draws in a loop without processing application messages; it calls the (VCL library) method <a href="http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Controls.TWinControl.Repaint"><code>Repaint</code></a> which internally invalidates and then calls <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd145167(v=vs.85).aspx"><code>UpdateWindow</code></a> for the window in question, directly calling into the message procedure with <code>WM_PAINT</code>.  The VCL implementation of the paint handler uses <code>BeginBufferedPaint</code>. Painting is itself double-buffered.</p>
  
  <p>The aim of this is to have as high a frame-rate as possible to get a smooth animation across the screen. (The drawing uses double-buffering to remove flickering and to ensure a whole image or frame is onscreen at any one time. It invalidates and updates directly by calling into the message procedure, without doing other message processing. Painting is implemented using modern techniques (eg BeginBufferedPaint) for Aero composition.)  Within this, painting is done in a couple of BitBlt calls (one for the left side of the animation, ie what's moving offscreen, and one for the right side of the animation, ie what's moving onscreen.)</p>
  
  <p><strong>When watching the animation, there is clearly visible <a href="https://en.wikipedia.org/wiki/Screen_tearing">tearing</a>.</strong> This occurs on Windows Vista, 7 and 8.1 on multiple systems with different graphics cards.</p>
  
  <p>My approach to handle this has been to reduce the rate at which it is drawing, or to try to wait for VSync before painting again.  This might be the wrong approach, so the answer to this question might be "Do something else completely: X". If so, great :)</p>
  
  <p>(What I'd really like is a way to ask the DWM to compose / use only fully-painted frames for this specific window.)</p>
  
  <p>I've tried the following approaches, none of which remove all visible tearing. Therefore the question is, <em>Is it possible to avoid tearing when using DWM composition, and if so how?</em></p>
  
  <h1>Approaches tried:</h1>
  
  <ul>
  <li><p>Getting the monitor refresh rate via <code>GetDeviceCaps(Application.MainForm.Handle, VREFRESH)</code>; sleeping for 1 / refresh rate milliseconds. Slightly improved over painting as fast as possible, but may be wishful thinking. Perceptually slightly less smooth animation rate.  (Tweaks: normal <code>Sleep</code> and a high-resolution spin-wait using <code>timeGetTime</code>.)</p></li>
  <li><p>Using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa969523(v=vs.85).aspx"><code>DwmSetPresentParameters</code></a> to try to limit updating to the same rate at which the code draws.  (Variations: lots of buffers (cBuffer = 8) (no visible effect); specifying a source rate of monitor refresh rate / 1 and sleeping using the above code (the same as just trying the sleeping approach); specifying a refresh per frame of 1, 10, etc (no visible effect); changing the source frame coverage (no visible effect.)</p></li>
  <li><p>Using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa969514(v=vs.85).aspx"><code>DwmGetCompositionTimingInfo</code></a> in a variety of ways:</p>
  
  <ul>
  <li><ul>
  <li>While <code>cFramesPending</code> > 0, spin;</li>
  </ul></li>
  <li><ul>
  <li>Get <code>cFrame</code> (frame composed) and spin while this number doesn't change; </li>
  </ul></li>
  <li><ul>
  <li>Get <code>cFrameDisplayed</code> and spin while this doesn't change;</li>
  </ul></li>
  <li><ul>
  <li>Calculating a time to sleep to by adding <code>qpcVBlank + qpcRefreshPeriod</code>, and then while <code>QueryPerformanceCounter</code> returns a time less than this, spin</li>
  </ul></li>
  </ul></li>
  <li><p>All these approaches have also been varied by painting, then spinning/sleeping before painting again; or the reverse: sleeping and then painting.</p></li>
  </ul>
  
  <p>Few seem to have any visible effect and what effect there is is hard to qualify and may just be a result of a lower frame rate.  None prevent tearing, ie none make the DWM compose the window with a "whole" copy of the contents of the window's DC.</p>
  
  <p>Advice appreciated :)</p>