| Index: third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp | 
| diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp | 
| index ca2d94135deea63d6b2b6908bfb359519af156df..08f38fca1509785fe7ca1ac534cc669c56c49eef 100644 | 
| --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp | 
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp | 
| @@ -49,25 +49,99 @@ using testing::_; | 
|  | 
| namespace blink { | 
|  | 
| -class DrawingBufferTest : public Test { | 
| +class DrawingBufferTest : public Test, public DrawingBufferStateTracker { | 
| protected: | 
| void SetUp() override { | 
| IntSize initialSize(InitialWidth, InitialHeight); | 
| std::unique_ptr<GLES2InterfaceForTests> gl = | 
| wrapUnique(new GLES2InterfaceForTests); | 
| m_gl = gl.get(); | 
| +    InitializeRestoreState(); | 
| +    SetRestoreState(); | 
| std::unique_ptr<WebGraphicsContext3DProviderForTests> provider = | 
| wrapUnique(new WebGraphicsContext3DProviderForTests(std::move(gl))); | 
| m_drawingBuffer = DrawingBufferForTests::create( | 
| -        std::move(provider), initialSize, DrawingBuffer::Preserve); | 
| +        std::move(provider), this, initialSize, DrawingBuffer::Preserve); | 
| CHECK(m_drawingBuffer); | 
| } | 
|  | 
| +  void GetDrawingBufferRestoreState( | 
| +      DrawingBufferRestoreState* restoreState) override { | 
| +    *restoreState = m_restoreState; | 
| +  } | 
| + | 
| +  void InitializeRestoreState() { | 
| +    m_restoreState.scissorEnabled = true; | 
| +    m_restoreState.clearColor[0] = 0.5; | 
| +    m_restoreState.clearColor[3] = 0.8; | 
| +    m_restoreState.clearDepth = 0.8; | 
| +    m_restoreState.clearStencil = 37; | 
| +    m_restoreState.colorMask[1] = GL_TRUE; | 
| +    m_restoreState.colorMask[2] = GL_TRUE; | 
| +    m_restoreState.depthMask = GL_FALSE; | 
| +    m_restoreState.stencilMask = GL_FALSE; | 
| +    m_restoreState.packAlignment = 7; | 
| +    m_restoreState.activeTexture2DBinding = 0xbeef1; | 
| +    m_restoreState.renderbufferBinding = 0xbeef2; | 
| +    m_restoreState.drawFramebufferBinding = 0xbeef3; | 
| +    m_restoreState.readFramebufferBinding = 0xbeef4; | 
| +    m_restoreState.pixelUnpackBufferBinding = 0xbeef5; | 
| +  } | 
| + | 
| +  void SetRestoreState() { | 
| +    if (m_restoreState.scissorEnabled) | 
| +      m_gl->Enable(GL_SCISSOR_TEST); | 
| +    else | 
| +      m_gl->Disable(GL_SCISSOR_TEST); | 
| + | 
| +    m_gl->ClearColor(m_restoreState.clearColor[0], m_restoreState.clearColor[1], | 
| +                     m_restoreState.clearColor[2], | 
| +                     m_restoreState.clearColor[3]); | 
| +    m_gl->ClearDepthf(m_restoreState.clearDepth); | 
| +    m_gl->ClearStencil(m_restoreState.clearStencil); | 
| +    m_gl->ColorMask(m_restoreState.colorMask[0], m_restoreState.colorMask[1], | 
| +                    m_restoreState.colorMask[2], m_restoreState.colorMask[3]); | 
| +    m_gl->DepthMask(m_restoreState.depthMask); | 
| +    m_gl->StencilMask(m_restoreState.stencilMask); | 
| +    m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_restoreState.packAlignment); | 
| +    m_gl->BindTexture(GL_TEXTURE_2D, m_restoreState.activeTexture2DBinding); | 
| +    m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_restoreState.renderbufferBinding); | 
| +    m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, | 
| +                          m_restoreState.drawFramebufferBinding); | 
| +    m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, | 
| +                          m_restoreState.readFramebufferBinding); | 
| +    m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, | 
| +                     m_restoreState.pixelUnpackBufferBinding); | 
| +  } | 
| +  void VerifyStateWasRestored() { | 
| +    DrawingBufferRestoreState actual = m_gl->getActualRestoreState(); | 
| +    for (size_t i = 0; i < 4; ++i) { | 
| +      EXPECT_EQ(actual.clearColor[0], m_restoreState.clearColor[0]); | 
| +      EXPECT_EQ(actual.colorMask[0], m_restoreState.colorMask[0]); | 
| +    } | 
| +    EXPECT_EQ(actual.clearDepth, m_restoreState.clearDepth); | 
| +    EXPECT_EQ(actual.clearStencil, m_restoreState.clearStencil); | 
| +    EXPECT_EQ(actual.depthMask, m_restoreState.depthMask); | 
| +    EXPECT_EQ(actual.stencilMask, m_restoreState.stencilMask); | 
| +    EXPECT_EQ(actual.packAlignment, m_restoreState.packAlignment); | 
| +    EXPECT_EQ(actual.activeTexture2DBinding, | 
| +              m_restoreState.activeTexture2DBinding); | 
| +    EXPECT_EQ(actual.renderbufferBinding, m_restoreState.renderbufferBinding); | 
| +    EXPECT_EQ(actual.drawFramebufferBinding, | 
| +              m_restoreState.drawFramebufferBinding); | 
| +    EXPECT_EQ(actual.readFramebufferBinding, | 
| +              m_restoreState.readFramebufferBinding); | 
| +    EXPECT_EQ(actual.pixelUnpackBufferBinding, | 
| +              m_restoreState.pixelUnpackBufferBinding); | 
| +  } | 
| + | 
| GLES2InterfaceForTests* m_gl; | 
| RefPtr<DrawingBufferForTests> m_drawingBuffer; | 
| +  DrawingBufferRestoreState m_restoreState; | 
| }; | 
|  | 
| TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes) { | 
| +  VerifyStateWasRestored(); | 
| cc::TextureMailbox textureMailbox; | 
| std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 
|  | 
| @@ -78,33 +152,41 @@ TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes) { | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox, | 
| &releaseCallback)); | 
| +  VerifyStateWasRestored(); | 
| EXPECT_EQ(initialSize, m_gl->mostRecentlyProducedSize()); | 
|  | 
| // Resize to 100x50. | 
| -  m_drawingBuffer->reset(alternateSize); | 
| +  m_drawingBuffer->resize(alternateSize); | 
| +  VerifyStateWasRestored(); | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Produce a mailbox at this size. | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox, | 
| &releaseCallback)); | 
| EXPECT_EQ(alternateSize, m_gl->mostRecentlyProducedSize()); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Reset to initial size. | 
| -  m_drawingBuffer->reset(initialSize); | 
| +  m_drawingBuffer->resize(initialSize); | 
| +  VerifyStateWasRestored(); | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Prepare another mailbox and verify that it's the correct size. | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox, | 
| &releaseCallback)); | 
| EXPECT_EQ(initialSize, m_gl->mostRecentlyProducedSize()); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Prepare one final mailbox and verify that it's the correct size. | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox, | 
| &releaseCallback)); | 
| +  VerifyStateWasRestored(); | 
| EXPECT_EQ(initialSize, m_gl->mostRecentlyProducedSize()); | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| m_drawingBuffer->beginDestruction(); | 
| @@ -125,12 +207,18 @@ TEST_F(DrawingBufferTest, verifyDestructionCompleteAfterAllMailboxesReleased) { | 
|  | 
| // Produce mailboxes. | 
| m_drawingBuffer->markContentsChanged(); | 
| +  m_drawingBuffer->clearFramebuffers(GL_STENCIL_BUFFER_BIT); | 
| +  VerifyStateWasRestored(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox1, | 
| &releaseCallback1)); | 
| m_drawingBuffer->markContentsChanged(); | 
| +  m_drawingBuffer->clearFramebuffers(GL_DEPTH_BUFFER_BIT); | 
| +  VerifyStateWasRestored(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox2, | 
| &releaseCallback2)); | 
| m_drawingBuffer->markContentsChanged(); | 
| +  m_drawingBuffer->clearFramebuffers(GL_COLOR_BUFFER_BIT); | 
| +  VerifyStateWasRestored(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox3, | 
| &releaseCallback3)); | 
|  | 
| @@ -167,12 +255,15 @@ TEST_F(DrawingBufferTest, verifyDrawingBufferStaysAliveIfResourcesAreLost) { | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox1, | 
| &releaseCallback1)); | 
| +  VerifyStateWasRestored(); | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox2, | 
| &releaseCallback2)); | 
| +  VerifyStateWasRestored(); | 
| m_drawingBuffer->markContentsChanged(); | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox3, | 
| &releaseCallback3)); | 
| +  VerifyStateWasRestored(); | 
|  | 
| m_drawingBuffer->markContentsChanged(); | 
| releaseCallback1->Run(gpu::SyncToken(), true /* lostResource */); | 
| @@ -287,13 +378,15 @@ class DrawingBufferImageChromiumTest : public DrawingBufferTest { | 
| std::unique_ptr<GLES2InterfaceForTests> gl = | 
| wrapUnique(new GLES2InterfaceForTests); | 
| m_gl = gl.get(); | 
| +    InitializeRestoreState(); | 
| +    SetRestoreState(); | 
| std::unique_ptr<WebGraphicsContext3DProviderForTests> provider = | 
| wrapUnique(new WebGraphicsContext3DProviderForTests(std::move(gl))); | 
| RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(true); | 
| m_imageId0 = m_gl->nextImageIdToBeCreated(); | 
| EXPECT_CALL(*m_gl, BindTexImage2DMock(m_imageId0)).Times(1); | 
| m_drawingBuffer = DrawingBufferForTests::create( | 
| -        std::move(provider), initialSize, DrawingBuffer::Preserve); | 
| +        std::move(provider), this, initialSize, DrawingBuffer::Preserve); | 
| CHECK(m_drawingBuffer); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
| } | 
| @@ -321,6 +414,7 @@ TEST_F(DrawingBufferImageChromiumTest, verifyResizingReallocatesImages) { | 
| EXPECT_EQ(initialSize, m_gl->mostRecentlyProducedSize()); | 
| EXPECT_TRUE(textureMailbox.is_overlay_candidate()); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
| +  VerifyStateWasRestored(); | 
|  | 
| GLuint m_imageId2 = m_gl->nextImageIdToBeCreated(); | 
| EXPECT_CALL(*m_gl, BindTexImage2DMock(m_imageId2)).Times(1); | 
| @@ -329,8 +423,10 @@ TEST_F(DrawingBufferImageChromiumTest, verifyResizingReallocatesImages) { | 
| EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId1)).Times(1); | 
| EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId1)).Times(1); | 
| // Resize to 100x50. | 
| -  m_drawingBuffer->reset(alternateSize); | 
| +  m_drawingBuffer->resize(alternateSize); | 
| +  VerifyStateWasRestored(); | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| +  VerifyStateWasRestored(); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
|  | 
| GLuint m_imageId3 = m_gl->nextImageIdToBeCreated(); | 
| @@ -350,8 +446,10 @@ TEST_F(DrawingBufferImageChromiumTest, verifyResizingReallocatesImages) { | 
| EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId3)).Times(1); | 
| EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId3)).Times(1); | 
| // Reset to initial size. | 
| -  m_drawingBuffer->reset(initialSize); | 
| +  m_drawingBuffer->resize(initialSize); | 
| +  VerifyStateWasRestored(); | 
| releaseCallback->Run(gpu::SyncToken(), false /* lostResource */); | 
| +  VerifyStateWasRestored(); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
|  | 
| GLuint m_imageId5 = m_gl->nextImageIdToBeCreated(); | 
| @@ -398,6 +496,7 @@ TEST_F(DrawingBufferImageChromiumTest, allocationFailure) { | 
| &releaseCallback1)); | 
| EXPECT_TRUE(textureMailbox1.is_overlay_candidate()); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Force image CHROMIUM creation failure. Request another mailbox. It should | 
| // still be provided, but this time with allowOverlay = false. | 
| @@ -406,6 +505,7 @@ TEST_F(DrawingBufferImageChromiumTest, allocationFailure) { | 
| EXPECT_TRUE(m_drawingBuffer->PrepareTextureMailbox(&textureMailbox2, | 
| &releaseCallback2)); | 
| EXPECT_FALSE(textureMailbox2.is_overlay_candidate()); | 
| +  VerifyStateWasRestored(); | 
|  | 
| // Check that if image CHROMIUM starts working again, mailboxes are | 
| // correctly created with allowOverlay = true. | 
| @@ -416,6 +516,7 @@ TEST_F(DrawingBufferImageChromiumTest, allocationFailure) { | 
| &releaseCallback3)); | 
| EXPECT_TRUE(textureMailbox3.is_overlay_candidate()); | 
| testing::Mock::VerifyAndClearExpectations(m_gl); | 
| +  VerifyStateWasRestored(); | 
|  | 
| releaseCallback1->Run(gpu::SyncToken(), false /* lostResource */); | 
| releaseCallback2->Run(gpu::SyncToken(), false /* lostResource */); | 
| @@ -532,7 +633,7 @@ TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported) { | 
| bool wantStencilBuffer = cases[i].requestStencil; | 
| bool wantAntialiasing = false; | 
| RefPtr<DrawingBuffer> drawingBuffer = DrawingBuffer::create( | 
| -        std::move(provider), IntSize(10, 10), premultipliedAlpha, | 
| +        std::move(provider), nullptr, IntSize(10, 10), premultipliedAlpha, | 
| wantAlphaChannel, wantDepthBuffer, wantStencilBuffer, wantAntialiasing, | 
| preserve, DrawingBuffer::WebGL1, DrawingBuffer::AllowChromiumImage); | 
|  | 
| @@ -553,7 +654,7 @@ TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported) { | 
| EXPECT_EQ(0u, trackingGL->stencilAttachment()); | 
| } | 
|  | 
| -    drawingBuffer->reset(IntSize(10, 20)); | 
| +    drawingBuffer->resize(IntSize(10, 20)); | 
| EXPECT_EQ(cases[i].requestDepth || cases[i].requestStencil, | 
| drawingBuffer->hasDepthBuffer()); | 
| EXPECT_EQ(cases[i].requestDepth || cases[i].requestStencil, | 
|  |