| Index: cc/layer_tree_host_unittest.cc | 
| diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc | 
| index f2bf6dd2e9c7466d9ba70d25026dccdf6a961919..98cbe6d81923f3151c020b4b06f366bf1776e9e4 100644 | 
| --- a/cc/layer_tree_host_unittest.cc | 
| +++ b/cc/layer_tree_host_unittest.cc | 
| @@ -1989,55 +1989,105 @@ public: | 
|  | 
| SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestManySurfaces) | 
|  | 
| -// A loseOutputSurface(1) should lead to a didRecreateOutputSurface(true) | 
| +// Losing the context should lead to a didRecreateOutputSurface(true). | 
| class LayerTreeHostTestSetSingleLostContext : public LayerTreeHostTest { | 
| public: | 
| LayerTreeHostTestSetSingleLostContext() | 
| +        : m_context3d(NULL) | 
| +        , m_timesToLose(1) | 
| +        , m_timesToLoseDuringDraw(1) | 
| { | 
| } | 
|  | 
| +    virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE | 
| +    { | 
| +        scoped_ptr<CompositorFakeWebGraphicsContext3DWithTextureTracking> context3d = | 
| +                CompositorFakeWebGraphicsContext3DWithTextureTracking::create(WebKit::WebGraphicsContext3D::Attributes()); | 
| +        m_context3d = context3d.get(); | 
| +        return FakeOutputSurface::Create3d(context3d.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>(); | 
| +    } | 
| + | 
| virtual void beginTest() OVERRIDE | 
| { | 
| postSetNeedsCommitToMainThread(); | 
| } | 
|  | 
| -    virtual void didCommitAndDrawFrame() OVERRIDE | 
| +    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE | 
| { | 
| -        m_layerTreeHost->loseOutputSurface(1); | 
| +        if (!m_timesToLose) | 
| +            return; | 
| +        m_context3d->loseContext(); | 
| +        m_context3d = NULL; | 
| +        --m_timesToLose; | 
| +    } | 
| + | 
| +    virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE | 
| +    { | 
| +        // Lose during commit first, then during draw. | 
| +        if (m_timesToLose || !m_timesToLoseDuringDraw || !m_context3d) | 
| +            return; | 
| +        m_context3d->loseContext(); | 
| +        m_context3d = NULL; | 
| +        --m_timesToLoseDuringDraw; | 
| } | 
|  | 
| virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE | 
| { | 
| EXPECT_TRUE(succeeded); | 
| -        endTest(); | 
| +        if (!m_timesToLose && !m_timesToLoseDuringDraw) | 
| +            endTest(); | 
| } | 
|  | 
| virtual void afterTest() OVERRIDE | 
| { | 
| } | 
| + | 
| +private: | 
| +    FakeWebGraphicsContext3D* m_context3d; | 
| +    int m_timesToLose; | 
| +    int m_timesToLoseDuringDraw; | 
| }; | 
|  | 
| -TEST_F(LayerTreeHostTestSetSingleLostContext, runMultiThread) | 
| -{ | 
| -    runTest(true); | 
| -} | 
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetSingleLostContext) | 
|  | 
| -// A loseOutputSurface(10) should lead to a didRecreateOutputSurface(false), and | 
| +// Failing to recreate the context should lead to a didRecreateOutputSurface(false) and | 
| // a finishAllRendering() should not hang. | 
| class LayerTreeHostTestSetRepeatedLostContext : public LayerTreeHostTest { | 
| public: | 
| LayerTreeHostTestSetRepeatedLostContext() | 
| +        : m_context3d(NULL) | 
| +        , m_timesToLose(1) | 
| +        , m_timesToFailCreate(0) | 
| { | 
| } | 
|  | 
| +    virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE | 
| +    { | 
| +        if (m_timesToFailCreate) { | 
| +            --m_timesToFailCreate; | 
| +            return scoped_ptr<OutputSurface>(); | 
| +        } | 
| + | 
| +        scoped_ptr<CompositorFakeWebGraphicsContext3DWithTextureTracking> context3d = | 
| +                CompositorFakeWebGraphicsContext3DWithTextureTracking::create(WebKit::WebGraphicsContext3D::Attributes()); | 
| +        m_context3d = context3d.get(); | 
| +        return FakeOutputSurface::Create3d(context3d.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>(); | 
| +    } | 
| + | 
| virtual void beginTest() OVERRIDE | 
| { | 
| postSetNeedsCommitToMainThread(); | 
| } | 
|  | 
| -    virtual void didCommitAndDrawFrame() OVERRIDE | 
| +    virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE | 
| { | 
| -        m_layerTreeHost->loseOutputSurface(10); | 
| +        if (!m_timesToLose) | 
| +            return; | 
| +        m_context3d->loseContext(); | 
| +        m_context3d = NULL; | 
| +        --m_timesToLose; | 
| + | 
| +        m_timesToFailCreate = 10; | 
| } | 
|  | 
| virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE | 
| @@ -2050,12 +2100,14 @@ public: | 
| virtual void afterTest() OVERRIDE | 
| { | 
| } | 
| + | 
| +private: | 
| +    FakeWebGraphicsContext3D* m_context3d; | 
| +    int m_timesToLose; | 
| +    int m_timesToFailCreate; | 
| }; | 
|  | 
| -TEST_F(LayerTreeHostTestSetRepeatedLostContext, runMultiThread) | 
| -{ | 
| -    runTest(true); | 
| -} | 
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetRepeatedLostContext) | 
|  | 
| class LayerTreeHostTestFractionalScroll : public LayerTreeHostTest { | 
| public: | 
| @@ -2866,9 +2918,18 @@ public: | 
| : m_layer(EvictionTestLayer::create()) | 
| , m_implForEvictTextures(0) | 
| , m_numCommits(0) | 
| +        , m_context3d(NULL) | 
| { | 
| } | 
|  | 
| +    virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE | 
| +    { | 
| +        scoped_ptr<CompositorFakeWebGraphicsContext3DWithTextureTracking> context3d = | 
| +                CompositorFakeWebGraphicsContext3DWithTextureTracking::create(WebKit::WebGraphicsContext3D::Attributes()); | 
| +        m_context3d = context3d.get(); | 
| +        return FakeOutputSurface::Create3d(context3d.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>(); | 
| +    } | 
| + | 
| virtual void beginTest() OVERRIDE | 
| { | 
| m_layerTreeHost->setRootLayer(m_layer); | 
| @@ -2880,13 +2941,16 @@ public: | 
| postSetNeedsCommitToMainThread(); | 
| } | 
|  | 
| -    void postEvictTextures() | 
| +    void loseContextAndPostEvictTextures() | 
| { | 
| if (implThread()) { | 
| +            implThread()->postTask(base::Bind(&FakeWebGraphicsContext3D::loseContext, | 
| +                                              base::Unretained(m_context3d))); | 
| implThread()->postTask(base::Bind(&LayerTreeHostTestLostContextAfterEvictTextures::evictTexturesOnImplThread, | 
| base::Unretained(this))); | 
| } else { | 
| DebugScopedSetImplThread impl(proxy()); | 
| +            m_context3d->loseContext(); | 
| evictTexturesOnImplThread(); | 
| } | 
| } | 
| @@ -2899,8 +2963,8 @@ public: | 
|  | 
| // Commit 1: Just commit and draw normally, then at the end, set ourselves | 
| // invisible (to prevent a commit that would recreate textures after | 
| -    // eviction, before the context recovery), and post a task that will evict | 
| -    // textures, then cause the context to be lost, and then set ourselves | 
| +    // eviction, before the context recovery). Then lose the graphics context | 
| +    // and post a task that will evict textures. Finally, set ourselves | 
| // visible again (to allow commits, since that's what causes context | 
| // recovery in single thread). | 
| virtual void didCommitAndDrawFrame() OVERRIDE | 
| @@ -2910,8 +2974,7 @@ public: | 
| case 1: | 
| EXPECT_TRUE(m_layer->haveBackingTexture()); | 
| m_layerTreeHost->setVisible(false); | 
| -            postEvictTextures(); | 
| -            m_layerTreeHost->loseOutputSurface(1); | 
| +            loseContextAndPostEvictTextures(); | 
| m_layerTreeHost->setVisible(true); | 
| break; | 
| default: | 
| @@ -2939,6 +3002,7 @@ private: | 
| scoped_refptr<EvictionTestLayer> m_layer; | 
| LayerTreeHostImpl* m_implForEvictTextures; | 
| int m_numCommits; | 
| +    FakeWebGraphicsContext3D* m_context3d; | 
| }; | 
|  | 
| SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLostContextAfterEvictTextures) | 
|  |