Changeset 59683 in webkit


Ignore:
Timestamp:
May 18, 2010 12:33:10 PM (14 years ago)
Author:
Adam Roben
Message:

Make WKCACFLayerRenderer robust against temporary failure of Direct3DCreate9 and IDirect3D9::CreateDevice

For a short time after waking from sleep, Direct3DCreate9() will
return an IDirect3D9 for which IDirect3D9::CreateDevice will always
fail. Also during this time period, IDirect3D9::CreateDevice
will fail even for non-bad IDirect3D9s. (It will later start
succeeding.) WKCACFLayerRenderer now works around this behavior by
detecting when it might be in this situation and calling these
functions again later.

Fixes <http://webkit.org/b/39297> <rdar://problem/7997431> WebView
doesn't repaint until page reloads when page using hardware
acceleration loads just after waking from sleep

Reviewed by John Sullivan.

  • manual-tests/crash-and-no-repaint-after-wake-from-sleep.html:

Renamed from WebCore/manual-tests/crash-after-wake-from-sleep.html.
Modified to also include instructions for reproducing this bug.

  • platform/graphics/win/WKCACFLayerRenderer.cpp:

(WebCore::WKCACFLayerRenderer::WKCACFLayerRenderer): Replaced
m_triedToCreateD3DRenderer with m_mightBeAbleToCreateDeviceLater. The
new member is initialized to true, since we haven't even tried to
create a device once yet.
(WebCore::WKCACFLayerRenderer::createRenderer): If we already have a
D3D device, or we don't have one and are sure that we won't be able to
create one later, just return the previously-created device, if any.
We assume that we won't be able to create a device later if this
function fails, unless the function fails due to CreateDevice failing.
As noted above, CreateDevice will sometimes temporarily fail and then
later start working again. When CreateDevice fails, we also assume
that we might have a bad IDirect3D9, so we get rid of the one we have
so a new (and hopefully non-bad) one will be allocated later.
(WebCore::WKCACFLayerRenderer::destroyRenderer): Reset
m_mightBeAbleToCreateDeviceLater to true, since we no longer have a
device.
(WebCore::WKCACFLayerRenderer::paint): Before trying to paint, try to
create our D3D device and renderer. If this fails, we bail out, but if
we think we might be able to create a device later we schedule another
paint (via renderSoon()) so that we'll try again soon.

  • platform/graphics/win/WKCACFLayerRenderer.h: Replaced

m_triedToCreateD3DRenderer with m_mightBeAbleToCreateDeviceLater.

Location:
trunk/WebCore
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r59682 r59683  
     12010-05-18  Adam Roben  <aroben@apple.com>
     2
     3        Make WKCACFLayerRenderer robust against temporary failure of
     4        Direct3DCreate9 and IDirect3D9::CreateDevice
     5
     6        For a short time after waking from sleep, Direct3DCreate9() will
     7        return an IDirect3D9 for which IDirect3D9::CreateDevice will always
     8        fail. Also during this time period, IDirect3D9::CreateDevice
     9        will fail even for non-bad IDirect3D9s. (It will later start
     10        succeeding.) WKCACFLayerRenderer now works around this behavior by
     11        detecting when it might be in this situation and calling these
     12        functions again later.
     13
     14        Fixes <http://webkit.org/b/39297> <rdar://problem/7997431> WebView
     15        doesn't repaint until page reloads when page using hardware
     16        acceleration loads just after waking from sleep
     17
     18        Reviewed by John Sullivan.
     19
     20        * manual-tests/crash-and-no-repaint-after-wake-from-sleep.html:
     21        Renamed from WebCore/manual-tests/crash-after-wake-from-sleep.html.
     22        Modified to also include instructions for reproducing this bug.
     23
     24        * platform/graphics/win/WKCACFLayerRenderer.cpp:
     25        (WebCore::WKCACFLayerRenderer::WKCACFLayerRenderer): Replaced
     26        m_triedToCreateD3DRenderer with m_mightBeAbleToCreateDeviceLater. The
     27        new member is initialized to true, since we haven't even tried to
     28        create a device once yet.
     29        (WebCore::WKCACFLayerRenderer::createRenderer): If we already have a
     30        D3D device, or we don't have one and are sure that we won't be able to
     31        create one later, just return the previously-created device, if any.
     32        We assume that we won't be able to create a device later if this
     33        function fails, unless the function fails due to CreateDevice failing.
     34        As noted above, CreateDevice will sometimes temporarily fail and then
     35        later start working again. When CreateDevice fails, we also assume
     36        that we might have a bad IDirect3D9, so we get rid of the one we have
     37        so a new (and hopefully non-bad) one will be allocated later.
     38        (WebCore::WKCACFLayerRenderer::destroyRenderer): Reset
     39        m_mightBeAbleToCreateDeviceLater to true, since we no longer have a
     40        device.
     41        (WebCore::WKCACFLayerRenderer::paint): Before trying to paint, try to
     42        create our D3D device and renderer. If this fails, we bail out, but if
     43        we think we might be able to create a device later we schedule another
     44        paint (via renderSoon()) so that we'll try again soon.
     45
     46        * platform/graphics/win/WKCACFLayerRenderer.h: Replaced
     47        m_triedToCreateD3DRenderer with m_mightBeAbleToCreateDeviceLater.
     48
    1492010-05-18  Adam Roben  <aroben@apple.com>
    250
  • trunk/WebCore/manual-tests/crash-and-no-repaint-after-wake-from-sleep.html

    r59682 r59683  
    33<html>
    44  <head>
    5     <title>Test for Bug 39295</title>
     5    <title>Test for Bugs 39295 and 39297</title>
    66    <meta http-equiv="refresh" content="5">
    77    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     
    168168  <body>
    169169
    170     <p>This is a test for <a href="https://bugs.webkit.org/show_bug.cgi?id=39295">Bug 39295: Crash
    171     (preceded by assertion) in WKCACFLayerRenderer::setNeedsDisplay when computer wakes from sleep
    172     on particular page</a>. To test, put your computer to sleep (or "Standby", as Windows calls it).
    173     When you wake your computer up, the browser should not crash.</p>
     170    <p>This is a combined test for <a href="https://bugs.webkit.org/show_bug.cgi?id=39295">Bug 39295: Crash (preceded by
     171    assertion) in WKCACFLayerRenderer::setNeedsDisplay when computer wakes from sleep on particular page</a> and <a
     172    href="https://bugs.webkit.org/show_bug.cgi?id=39297">Bug 39297: WebView doesn't repaint until page reloads when page
     173    using hardware acceleration loads just after waking from sleep</a>. To test, put your computer to sleep (or
     174    "Standby", as Windows calls it). When you wake your computer up, the browser should not crash and the animation
     175    below should still be running without any periods of non-painting of the WebView.</p>
    174176    <div id="stage">
    175177      <div id="rotate">
  • trunk/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp

    r59682 r59683  
    224224
    225225WKCACFLayerRenderer::WKCACFLayerRenderer()
    226     : m_triedToCreateD3DRenderer(false)
     226    : m_mightBeAbleToCreateDeviceLater(true)
    227227    , m_rootLayer(WKCACFRootLayer::create(this))
    228228    , m_scrollLayer(WKCACFLayer::create(WKCACFLayer::Layer))
     
    341341bool WKCACFLayerRenderer::createRenderer()
    342342{
    343     if (m_triedToCreateD3DRenderer)
     343    if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater)
    344344        return m_d3dDevice;
    345345
    346     m_triedToCreateD3DRenderer = true;
     346    m_mightBeAbleToCreateDeviceLater = false;
    347347    D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
    348348
     
    362362
    363363    COMPtr<IDirect3DDevice9> device;
    364     if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hostWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &parameters, &device)))
    365         return false;
     364    if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hostWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &parameters, &device))) {
     365        // In certain situations (e.g., shortly after waking from sleep), Direct3DCreate9() will
     366        // return an IDirect3D9 for which IDirect3D9::CreateDevice will always fail. In case we
     367        // have one of these bad IDirect3D9s, get rid of it so we'll fetch a new one the next time
     368        // we want to call CreateDevice.
     369        s_d3d->Release();
     370        s_d3d = 0;
     371
     372        // Even if we don't have a bad IDirect3D9, in certain situations (e.g., shortly after
     373        // waking from sleep), CreateDevice will fail, but will later succeed if called again.
     374        m_mightBeAbleToCreateDeviceLater = true;
     375
     376        return false;
     377    }
    366378
    367379    // Now that we've created the IDirect3DDevice9 based on the capabilities we
     
    412424    m_rootChildLayer = 0;
    413425
    414     m_triedToCreateD3DRenderer = false;
     426    m_mightBeAbleToCreateDeviceLater = true;
    415427}
    416428
     
    470482void WKCACFLayerRenderer::paint()
    471483{
    472     if (!m_d3dDevice)
    473         return;
     484    createRenderer();
     485    if (!m_d3dDevice) {
     486        if (m_mightBeAbleToCreateDeviceLater)
     487            renderSoon();
     488        return;
     489    }
    474490
    475491    if (m_backingStoreDirty) {
  • trunk/WebCore/platform/graphics/win/WKCACFLayerRenderer.h

    r59681 r59683  
    9595    void paint();
    9696
    97     bool m_triedToCreateD3DRenderer;
     97    bool m_mightBeAbleToCreateDeviceLater;
    9898    COMPtr<IDirect3DDevice9> m_d3dDevice;
    9999    RefPtr<WKCACFRootLayer> m_rootLayer;
Note: See TracChangeset for help on using the changeset viewer.