| Index: third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h | 
| diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h | 
| index 8ee8c7beb228ae9f03ab58cb1585c862520e5a24..8d12db23968e2a966062b1890d3643bf8c5d98b9 100644 | 
| --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h | 
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h | 
| @@ -21,13 +21,15 @@ class DrawingBufferForTests : public DrawingBuffer { | 
| public: | 
| static PassRefPtr<DrawingBufferForTests> create( | 
| std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
| +      DrawingBufferStateTracker* stateTracker, | 
| const IntSize& size, | 
| PreserveDrawingBuffer preserve) { | 
| std::unique_ptr<Extensions3DUtil> extensionsUtil = | 
| Extensions3DUtil::create(contextProvider->contextGL()); | 
| RefPtr<DrawingBufferForTests> drawingBuffer = | 
| -        adoptRef(new DrawingBufferForTests( | 
| -            std::move(contextProvider), std::move(extensionsUtil), preserve)); | 
| +        adoptRef(new DrawingBufferForTests(std::move(contextProvider), | 
| +                                           std::move(extensionsUtil), | 
| +                                           stateTracker, preserve)); | 
| bool multisampleExtensionSupported = false; | 
| if (!drawingBuffer->initialize(size, multisampleExtensionSupported)) { | 
| drawingBuffer->beginDestruction(); | 
| @@ -39,10 +41,12 @@ class DrawingBufferForTests : public DrawingBuffer { | 
| DrawingBufferForTests( | 
| std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
| std::unique_ptr<Extensions3DUtil> extensionsUtil, | 
| +      DrawingBufferStateTracker* stateTracker, | 
| PreserveDrawingBuffer preserve) | 
| : DrawingBuffer( | 
| std::move(contextProvider), | 
| std::move(extensionsUtil), | 
| +            stateTracker, | 
| false /* discardFramebufferSupported */, | 
| true /* wantAlphaChannel */, | 
| false /* premultipliedAlpha */, | 
| @@ -104,13 +108,83 @@ GLenum drawingBufferTextureTarget() { | 
| class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 
| public: | 
| void BindTexture(GLenum target, GLuint texture) override { | 
| -    if (target != m_boundTextureTarget && texture == 0) | 
| -      return; | 
| +    if (target == GL_TEXTURE_2D) | 
| +      m_state.activeTexture2DBinding = texture; | 
| +    m_boundTextures[target] = texture; | 
| +  } | 
| + | 
| +  void BindFramebuffer(GLenum target, GLuint framebuffer) override { | 
| +    switch (target) { | 
| +      case GL_FRAMEBUFFER: | 
| +        m_state.drawFramebufferBinding = framebuffer; | 
| +        m_state.readFramebufferBinding = framebuffer; | 
| +        break; | 
| +      case GL_DRAW_FRAMEBUFFER: | 
| +        m_state.drawFramebufferBinding = framebuffer; | 
| +        break; | 
| +      case GL_READ_FRAMEBUFFER: | 
| +        m_state.readFramebufferBinding = framebuffer; | 
| +        break; | 
| +      default: | 
| +        break; | 
| +    } | 
| +  } | 
| + | 
| +  void BindRenderbuffer(GLenum target, GLuint renderbuffer) override { | 
| +    m_state.renderbufferBinding = renderbuffer; | 
| +  } | 
| + | 
| +  void Enable(GLenum cap) { | 
| +    if (cap == GL_SCISSOR_TEST) | 
| +      m_state.scissorEnabled = true; | 
| +  } | 
| + | 
| +  void Disable(GLenum cap) { | 
| +    if (cap == GL_SCISSOR_TEST) | 
| +      m_state.scissorEnabled = false; | 
| +  } | 
| + | 
| +  void ClearColor(GLfloat red, | 
| +                  GLfloat green, | 
| +                  GLfloat blue, | 
| +                  GLfloat alpha) override { | 
| +    m_state.clearColor[0] = red; | 
| +    m_state.clearColor[1] = green; | 
| +    m_state.clearColor[2] = blue; | 
| +    m_state.clearColor[3] = alpha; | 
| +  } | 
| + | 
| +  void ClearDepthf(GLfloat depth) override { m_state.clearDepth = depth; } | 
|  | 
| -    // For simplicity, only allow one target to ever be bound. | 
| -    ASSERT_TRUE(m_boundTextureTarget == 0 || target == m_boundTextureTarget); | 
| -    m_boundTextureTarget = target; | 
| -    m_boundTexture = texture; | 
| +  void ClearStencil(GLint s) override { m_state.clearStencil = s; } | 
| + | 
| +  void ColorMask(GLboolean red, | 
| +                 GLboolean green, | 
| +                 GLboolean blue, | 
| +                 GLboolean alpha) override { | 
| +    m_state.colorMask[0] = red; | 
| +    m_state.colorMask[1] = green; | 
| +    m_state.colorMask[2] = blue; | 
| +    m_state.colorMask[3] = alpha; | 
| +  } | 
| + | 
| +  void DepthMask(GLboolean flag) override { m_state.depthMask = flag; } | 
| + | 
| +  void StencilMask(GLuint mask) override { m_state.stencilMask = mask; } | 
| + | 
| +  void StencilMaskSeparate(GLenum face, GLuint mask) override { | 
| +    if (face == GL_FRONT) | 
| +      m_state.stencilMask = mask; | 
| +  } | 
| + | 
| +  void PixelStorei(GLenum pname, GLint param) override { | 
| +    if (pname == GL_PACK_ALIGNMENT) | 
| +      m_state.packAlignment = param; | 
| +  } | 
| + | 
| +  void BindBuffer(GLenum target, GLuint buffer) override { | 
| +    if (target == GL_PIXEL_UNPACK_BUFFER) | 
| +      m_state.pixelUnpackBufferBinding = buffer; | 
| } | 
|  | 
| GLuint64 InsertFenceSyncCHROMIUM() override { | 
| @@ -158,7 +232,7 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 
| GLenum type, | 
| const void* pixels) override { | 
| if (target == GL_TEXTURE_2D && !level) { | 
| -      m_textureSizes.set(m_boundTexture, IntSize(width, height)); | 
| +      m_textureSizes.set(m_boundTextures[target], IntSize(width, height)); | 
| } | 
| } | 
|  | 
| @@ -184,8 +258,9 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 
| MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); | 
| void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { | 
| if (target == imageCHROMIUMTextureTarget()) { | 
| -      m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value); | 
| -      m_imageToTextureMap.set(imageId, m_boundTexture); | 
| +      m_textureSizes.set(m_boundTextures[target], | 
| +                         m_imageSizes.find(imageId)->value); | 
| +      m_imageToTextureMap.set(imageId, m_boundTextures[target]); | 
| BindTexImage2DMock(imageId); | 
| } | 
| } | 
| @@ -212,8 +287,6 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 
| textures[i] = id++; | 
| } | 
|  | 
| -  GLuint boundTexture() const { return m_boundTexture; } | 
| -  GLuint boundTextureTarget() const { return m_boundTextureTarget; } | 
| gpu::SyncToken mostRecentlyWaitedSyncToken() const { | 
| return m_mostRecentlyWaitedSyncToken; | 
| } | 
| @@ -226,9 +299,17 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 
| m_createImageChromiumFail = fail; | 
| } | 
|  | 
| +  const DrawingBufferRestoreState& getActualRestoreState() const { | 
| +    return m_state; | 
| +  } | 
| + | 
| private: | 
| -  GLuint m_boundTexture = 0; | 
| -  GLuint m_boundTextureTarget = 0; | 
| +  std::map<GLenum, GLuint> m_boundTextures; | 
| + | 
| +  // The actual state set by GL commands. This is compared against an | 
| +  // expected value. | 
| +  DrawingBufferRestoreState m_state; | 
| + | 
| gpu::SyncToken m_mostRecentlyWaitedSyncToken; | 
| GLbyte m_currentMailboxByte = 0; | 
| IntSize m_mostRecentlyProducedSize; | 
|  |