| Index: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h | 
| diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h | 
| index a568fd06e4b752ac3ad1cb5ce139dde57c4b2f05..7a32f35c3f8c3b2eeb9fb369e8ed06690ac6daa3 100644 | 
| --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h | 
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h | 
| @@ -69,6 +69,36 @@ class WebExternalTextureLayer; | 
| class WebGraphicsContext3DProvider; | 
| class WebLayer; | 
|  | 
| +// OpenGL state the the DrawingBuffer may modify, which it will need to | 
| +// restore before returning from any of its methods. | 
| +struct PLATFORM_EXPORT DrawingBufferRestoreState { | 
| +  bool scissorEnabled = false; | 
| + | 
| +  GLfloat clearColor[4] = {0, 0, 0, 0}; | 
| +  GLfloat clearDepth = 0; | 
| +  GLint clearStencil = 0; | 
| + | 
| +  GLboolean colorMask[4] = {0, 0, 0, 0}; | 
| +  GLboolean depthMask = 0; | 
| +  GLuint stencilMask = 0; | 
| + | 
| +  GLint packAlignment = 4; | 
| + | 
| +  // The bound 2D texture for the active texture unit. | 
| +  GLuint activeTexture2DBinding = 0; | 
| +  GLuint renderbufferBinding = 0; | 
| +  GLuint drawFramebufferBinding = 0; | 
| +  GLuint readFramebufferBinding = 0; | 
| +  GLuint pixelUnpackBufferBinding = 0; | 
| +}; | 
| + | 
| +// An interface through which DrawingBuffer may query the state that it will | 
| +// need to reset from an object that is tracking this state. | 
| +class PLATFORM_EXPORT DrawingBufferStateTracker { | 
| + public: | 
| +  virtual void GetDrawingBufferRestoreState(DrawingBufferRestoreState*) = 0; | 
| +}; | 
| + | 
| // Manages a rendering target (framebuffer + attachment) for a canvas.  Can | 
| // publish its rendering results to a WebLayer for compositing. | 
| class PLATFORM_EXPORT DrawingBuffer | 
| @@ -93,6 +123,7 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| static PassRefPtr<DrawingBuffer> create( | 
| std::unique_ptr<WebGraphicsContext3DProvider>, | 
| +      DrawingBufferStateTracker*, | 
| const IntSize&, | 
| bool premultipliedAlpha, | 
| bool wantAlphaChannel, | 
| @@ -111,7 +142,7 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| // Issues a glClear() on all framebuffers associated with this DrawingBuffer. | 
| // The caller is responsible for making the context current and setting the | 
| -  // clear values and masks. Modifies the framebuffer binding. | 
| +  // clear values and masks. | 
| void clearFramebuffers(GLbitfield clearMask); | 
|  | 
| // Indicates whether the DrawingBuffer internally allocated a packed | 
| @@ -130,86 +161,21 @@ class PLATFORM_EXPORT DrawingBuffer | 
| int maxTextureSize); | 
|  | 
| // Resizes (or allocates if necessary) all buffers attached to the default | 
| -  // framebuffer. Returns whether the operation was successful. Leaves GL | 
| -  // bindings dirtied. | 
| -  bool reset(const IntSize&); | 
| +  // framebuffer. Returns whether the operation was successful. | 
| +  bool resize(const IntSize&); | 
|  | 
| // Bind the default framebuffer to |target|. |target| must be | 
| // GL_FRAMEBUFFER, GL_READ_FRAMEBUFFER, or GL_DRAW_FRAMEBUFFER. | 
| void bind(GLenum target); | 
| IntSize size() const { return m_size; } | 
|  | 
| -  // Copies the multisample color buffer to the normal color buffer and leaves | 
| -  // m_fbo bound. | 
| -  void commit(); | 
| - | 
| -  // commit should copy the full multisample buffer, and not respect the | 
| -  // current scissor bounds. Track the state of the scissor test so that it | 
| -  // can be disabled during calls to commit. | 
| -  void setScissorEnabled(bool scissorEnabled) { | 
| -    m_scissorEnabled = scissorEnabled; | 
| -  } | 
| - | 
| -  // The DrawingBuffer needs to track the texture bound to texture unit 0. | 
| -  // The bound texture is tracked to avoid costly queries during rendering. | 
| -  void setTexture2DBinding(GLuint texture) { m_texture2DBinding = texture; } | 
| - | 
| -  void setPixelUnpackBufferBinding(GLuint buffer) { | 
| -    DCHECK(m_webGLVersion > WebGL1); | 
| -    m_pixelUnpackBufferBinding = buffer; | 
| -  } | 
| - | 
| -  void notifyBufferDeleted(GLuint buffer) { | 
| -    if (m_webGLVersion > WebGL1 && buffer == m_pixelUnpackBufferBinding) { | 
| -      setPixelUnpackBufferBinding(0); | 
| -    } | 
| -  } | 
| - | 
| -  // The DrawingBuffer needs to track the currently bound framebuffer so it | 
| -  // restore the binding when needed. | 
| -  void setFramebufferBinding(GLenum target, GLuint fbo) { | 
| -    switch (target) { | 
| -      case GL_FRAMEBUFFER: | 
| -        m_drawFramebufferBinding = fbo; | 
| -        m_readFramebufferBinding = fbo; | 
| -        break; | 
| -      case GL_DRAW_FRAMEBUFFER: | 
| -        m_drawFramebufferBinding = fbo; | 
| -        break; | 
| -      case GL_READ_FRAMEBUFFER: | 
| -        m_readFramebufferBinding = fbo; | 
| -        break; | 
| -      default: | 
| -        ASSERT(0); | 
| -    } | 
| -  } | 
| - | 
| -  // The DrawingBuffer needs to track the color mask and clear color so that | 
| -  // it can restore it when needed. | 
| -  void setClearColor(GLfloat* clearColor) { | 
| -    memcpy(m_clearColor, clearColor, 4 * sizeof(GLfloat)); | 
| -  } | 
| - | 
| -  void setColorMask(GLboolean* colorMask) { | 
| -    memcpy(m_colorMask, colorMask, 4 * sizeof(GLboolean)); | 
| -  } | 
| - | 
| -  // The DrawingBuffer needs to track the currently bound renderbuffer so it | 
| -  // restore the binding when needed. | 
| -  void setRenderbufferBinding(GLuint renderbuffer) { | 
| -    m_renderbufferBinding = renderbuffer; | 
| -  } | 
| - | 
| -  // Track the currently active texture unit. Texture unit 0 is used as host for | 
| -  // a scratch texture. | 
| -  void setActiveTextureUnit(GLint textureUnit) { | 
| -    m_activeTextureUnit = textureUnit; | 
| -  } | 
| +  // Resolves the multisample color buffer to the normal color buffer and leaves | 
| +  // the resolved color buffer bound to GL_READ_FRAMEBUFFER and | 
| +  // GL_DRAW_FRAMEBUFFER. | 
| +  void resolveAndBindForReadAndDraw(); | 
|  | 
| bool multisample() const; | 
|  | 
| -  GLuint framebuffer() const; | 
| - | 
| bool discardFramebufferSupported() const { | 
| return m_discardFramebufferSupported; | 
| } | 
| @@ -246,7 +212,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
| // DrawingBuffer. | 
| PassRefPtr<StaticBitmapImage> transferToStaticBitmapImage(); | 
|  | 
| -  // Destroys the TEXTURE_2D binding for the owned context | 
| bool copyToPlatformTexture(gpu::gles2::GLES2Interface*, | 
| GLuint texture, | 
| GLenum internalFormat, | 
| @@ -256,8 +221,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
| bool flipY, | 
| SourceDrawingBuffer); | 
|  | 
| -  void setPackAlignment(GLint param); | 
| - | 
| bool paintRenderingResultsToImageData(int&, | 
| int&, | 
| SourceDrawingBuffer, | 
| @@ -268,14 +231,9 @@ class PLATFORM_EXPORT DrawingBuffer | 
| return m_antiAliasingMode == MSAAExplicitResolve; | 
| } | 
|  | 
| -  void restorePixelUnpackBufferBindings(); | 
| - | 
| -  // Bind to m_drawFramebufferBinding or m_readFramebufferBinding if it's not 0. | 
| -  // Otherwise, bind to the default FBO. | 
| +  // Rebind the read and draw framebuffers that WebGL is expecting. | 
| void restoreFramebufferBindings(); | 
|  | 
| -  void restoreTextureBindings(); | 
| - | 
| void addNewMailboxCallback(std::unique_ptr<WTF::Closure> closure) { | 
| m_newMailboxCallback = std::move(closure); | 
| } | 
| @@ -283,6 +241,7 @@ class PLATFORM_EXPORT DrawingBuffer | 
| protected:  // For unittests | 
| DrawingBuffer(std::unique_ptr<WebGraphicsContext3DProvider>, | 
| std::unique_ptr<Extensions3DUtil>, | 
| +                DrawingBufferStateTracker*, | 
| bool discardFramebufferSupported, | 
| bool wantAlphaChannel, | 
| bool premultipliedAlpha, | 
| @@ -303,9 +262,38 @@ class PLATFORM_EXPORT DrawingBuffer | 
| Vector<RecycledBitmap> m_recycledBitmaps; | 
|  | 
| private: | 
| -  // All parameters necessary to generate the texture that will be passed to | 
| -  // prepareMailbox. | 
| -  struct TextureParameters { | 
| +  friend class ScopedStateRestorer; | 
| +  friend class ColorBuffer; | 
| + | 
| +  // This structure should wrap all public entrypoints that may modify GL state. | 
| +  // It will restore all state when it drops out of scope. | 
| +  class ScopedStateRestorer { | 
| +   public: | 
| +    ScopedStateRestorer(DrawingBuffer*); | 
| +    ~ScopedStateRestorer(); | 
| + | 
| +    // Mark parts of the state that are dirty and need to be restored. | 
| +    void setClearStateDirty() { m_clearStateDirty = true; } | 
| +    void setPixelPackAlignmentDirty() { m_pixelPackAlignmentDirty = true; } | 
| +    void setTextureBindingDirty() { m_textureBindingDirty = true; } | 
| +    void setRenderbufferBindingDirty() { m_renderbufferBindingDirty = true; } | 
| +    void setFramebufferBindingDirty() { m_framebufferBindingDirty = true; } | 
| +    void setPixelUnpackBufferBindingDirty() { | 
| +      m_pixelUnpackBufferBindingDirty = true; | 
| +    } | 
| + | 
| +   private: | 
| +    RefPtr<DrawingBuffer> m_drawingBuffer; | 
| +    bool m_clearStateDirty = false; | 
| +    bool m_pixelPackAlignmentDirty = false; | 
| +    bool m_textureBindingDirty = false; | 
| +    bool m_renderbufferBindingDirty = false; | 
| +    bool m_framebufferBindingDirty = false; | 
| +    bool m_pixelUnpackBufferBindingDirty = false; | 
| +  }; | 
| + | 
| +  // All parameters necessary to generate the texture for the ColorBuffer. | 
| +  struct ColorBufferParameters { | 
| DISALLOW_NEW(); | 
| GLenum target = 0; | 
| GLenum internalColorFormat = 0; | 
| @@ -318,7 +306,11 @@ class PLATFORM_EXPORT DrawingBuffer | 
| }; | 
|  | 
| struct ColorBuffer : public RefCounted<ColorBuffer> { | 
| -    ColorBuffer(DrawingBuffer*, const TextureParameters&, const IntSize&); | 
| +    ColorBuffer(DrawingBuffer*, | 
| +                const ColorBufferParameters&, | 
| +                const IntSize&, | 
| +                GLuint textureId, | 
| +                GLuint imageId); | 
| ~ColorBuffer(); | 
|  | 
| // The owning DrawingBuffer. Note that DrawingBuffer is explicitly destroyed | 
| @@ -326,11 +318,11 @@ class PLATFORM_EXPORT DrawingBuffer | 
| // ColorBuffers. | 
| RefPtr<DrawingBuffer> drawingBuffer; | 
|  | 
| -    const TextureParameters parameters; | 
| +    const ColorBufferParameters parameters; | 
| const IntSize size; | 
|  | 
| -    GLuint textureId = 0; | 
| -    GLuint imageId = 0; | 
| +    const GLuint textureId = 0; | 
| +    const GLuint imageId = 0; | 
|  | 
| // The mailbox used to send this buffer to the compositor. | 
| gpu::Mailbox mailbox; | 
| @@ -346,31 +338,44 @@ class PLATFORM_EXPORT DrawingBuffer | 
| WTF_MAKE_NONCOPYABLE(ColorBuffer); | 
| }; | 
|  | 
| +  // The same as clearFramebuffers(), but leaves GL state dirty. | 
| +  void clearFramebuffersInternal(GLbitfield clearMask); | 
| + | 
| +  // The same as reset(), but leaves GL state dirty. | 
| +  bool resizeFramebufferInternal(const IntSize&); | 
| + | 
| +  // The same as commit(), but leaves GL state dirty. | 
| +  void resolveMultisampleFramebufferInternal(); | 
| + | 
| bool prepareTextureMailboxInternal( | 
| cc::TextureMailbox* outMailbox, | 
| std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 
| bool forceGpuResult); | 
|  | 
| -  // Callbacks for mailboxes given to the compositor from PrepareTextureMailbox. | 
| -  void gpuMailboxReleased(RefPtr<ColorBuffer>, | 
| +  // Helper functions to be called only by prepareTextureMailboxInternal. | 
| +  bool finishPrepareTextureMailboxGpu( | 
| +      cc::TextureMailbox* outMailbox, | 
| +      std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback); | 
| +  bool finishPrepareTextureMailboxSoftware( | 
| +      cc::TextureMailbox* outMailbox, | 
| +      std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback); | 
| + | 
| +  // Callbacks for mailboxes given to the compositor from | 
| +  // finishPrepareTextureMailboxGpu and finishPrepareTextureMailboxSoftware. | 
| +  void mailboxReleasedGpu(RefPtr<ColorBuffer>, | 
| const gpu::SyncToken&, | 
| bool lostResource); | 
| -  void softwareMailboxReleased(std::unique_ptr<cc::SharedBitmap>, | 
| +  void mailboxReleasedSoftware(std::unique_ptr<cc::SharedBitmap>, | 
| const IntSize&, | 
| const gpu::SyncToken&, | 
| bool lostResource); | 
|  | 
| // The texture parameters to use for a texture that will be backed by a | 
| -  // CHROMIUM_image. | 
| -  TextureParameters chromiumImageTextureParameters(); | 
| - | 
| -  // The texture parameters to use for a default texture. | 
| -  TextureParameters defaultTextureParameters(); | 
| +  // CHROMIUM_image, backed by a GpuMemoryBuffer. | 
| +  ColorBufferParameters gpuMemoryBufferColorBufferParameters(); | 
|  | 
| -  // Creates and binds a texture with the given parameters. Returns 0 on | 
| -  // failure, or the newly created texture id on success. The caller takes | 
| -  // ownership of the newly created texture. | 
| -  GLuint createColorTexture(const TextureParameters&); | 
| +  // The texture parameters to use for an ordinary GL texture. | 
| +  ColorBufferParameters textureColorBufferParameters(); | 
|  | 
| // Attempts to allocator storage for, or resize all buffers. Returns whether | 
| // the operation was successful. | 
| @@ -378,8 +383,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| void clearPlatformLayer(); | 
|  | 
| -  PassRefPtr<ColorBuffer> takeRecycledMailbox(); | 
| - | 
| std::unique_ptr<cc::SharedBitmap> createOrRecycleBitmap(); | 
|  | 
| // Updates the current size of the buffer, ensuring that | 
| @@ -400,16 +403,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
| // Helper function to flip a bitmap vertically. | 
| void flipVertically(uint8_t* data, int width, int height); | 
|  | 
| -  // Allocate a storage texture if possible. Otherwise, allocate a regular | 
| -  // texture. | 
| -  void allocateConditionallyImmutableTexture(GLenum target, | 
| -                                             GLenum internalformat, | 
| -                                             GLsizei width, | 
| -                                             GLsizei height, | 
| -                                             GLint border, | 
| -                                             GLenum format, | 
| -                                             GLenum type); | 
| - | 
| // If RGB emulation is required, then the CHROMIUM image's alpha channel | 
| // must be immediately cleared after it is bound to a texture. Nothing | 
| // should be allowed to change the alpha channel after this. | 
| @@ -417,11 +410,12 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| // Tries to create a CHROMIUM_image backed texture if | 
| // RuntimeEnabledFeatures::webGLImageChromiumEnabled() is true. On failure, | 
| -  // or if the flag is false, creates a default texture. | 
| -  RefPtr<ColorBuffer> createTextureAndAllocateMemory(const IntSize&); | 
| +  // or if the flag is false, creates a default texture. Always returns a valid | 
| +  // ColorBuffer. | 
| +  RefPtr<ColorBuffer> createColorBuffer(const IntSize&); | 
|  | 
| -  // Creates and allocates space for a default texture. | 
| -  RefPtr<ColorBuffer> createDefaultTextureAndAllocateMemory(const IntSize&); | 
| +  // Creates or recycles a ColorBuffer of size |m_size|. | 
| +  PassRefPtr<ColorBuffer> createOrRecycleColorBuffer(); | 
|  | 
| // Attaches |m_backColorBuffer| to |m_fbo|, which is always the source for | 
| // read operations. | 
| @@ -438,17 +432,11 @@ class PLATFORM_EXPORT DrawingBuffer | 
| // The format to use when creating a multisampled renderbuffer. | 
| GLenum getMultisampledRenderbufferFormat(); | 
|  | 
| +  // Weak, reset by beginDestruction. | 
| +  DrawingBufferStateTracker* m_stateTracker = nullptr; | 
| + | 
| const PreserveDrawingBuffer m_preserveDrawingBuffer; | 
| const WebGLVersion m_webGLVersion; | 
| -  bool m_scissorEnabled = false; | 
| -  GLuint m_texture2DBinding = 0; | 
| -  GLuint m_pixelUnpackBufferBinding = 0; | 
| -  GLuint m_drawFramebufferBinding = 0; | 
| -  GLuint m_readFramebufferBinding = 0; | 
| -  GLuint m_renderbufferBinding = 0; | 
| -  GLenum m_activeTextureUnit = GL_TEXTURE0; | 
| -  GLfloat m_clearColor[4]; | 
| -  GLboolean m_colorMask[4]; | 
|  | 
| std::unique_ptr<WebGraphicsContext3DProvider> m_contextProvider; | 
| // Lifetime is tied to the m_contextProvider. | 
| @@ -462,12 +450,13 @@ class PLATFORM_EXPORT DrawingBuffer | 
| bool m_hasImplicitStencilBuffer = false; | 
| bool m_storageTextureSupported = false; | 
|  | 
| -  // This is the ColorBuffer that was most recently presented to the compositor | 
| -  // by prepareTextureMailboxInternal. | 
| -  RefPtr<ColorBuffer> m_frontColorBuffer; | 
| - | 
| std::unique_ptr<WTF::Closure> m_newMailboxCallback; | 
|  | 
| +  // The current state restorer, which is used to track state dirtying. It is in | 
| +  // error to dirty state shared with WebGL while there is no existing state | 
| +  // restorer. It is also in error to instantiate two state restorers at once. | 
| +  ScopedStateRestorer* m_stateRestorer = nullptr; | 
| + | 
| // This is used when the user requests either a depth or stencil buffer. | 
| GLuint m_depthStencilBuffer = 0; | 
|  | 
| @@ -480,13 +469,16 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| // When wantExplicitResolve() returns false, the target of all draw and | 
| // read operations. When wantExplicitResolve() returns true, the target of | 
| -  // all read operations. A swap is performed by exchanging |m_backColorBuffer| | 
| -  // with |m_frontColorBuffer|. | 
| +  // all read operations. | 
| GLuint m_fbo = 0; | 
|  | 
| -  // All information about the texture storage for |m_fbo|. | 
| +  // The ColorBuffer that backs |m_fbo|. | 
| RefPtr<ColorBuffer> m_backColorBuffer; | 
|  | 
| +  // The ColorBuffer that was most recently presented to the compositor by | 
| +  // prepareTextureMailboxInternal. | 
| +  RefPtr<ColorBuffer> m_frontColorBuffer; | 
| + | 
| // True if our contents have been modified since the last presentation of this | 
| // buffer. | 
| bool m_contentsChanged = true; | 
| @@ -511,7 +503,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| int m_maxTextureSize = 0; | 
| int m_sampleCount = 0; | 
| -  int m_packAlignment = 4; | 
| bool m_destructionInProgress = false; | 
| bool m_isHidden = false; | 
| SkFilterQuality m_filterQuality = kLow_SkFilterQuality; | 
| @@ -520,7 +511,7 @@ class PLATFORM_EXPORT DrawingBuffer | 
|  | 
| // Mailboxes that were released by the compositor can be used again by this | 
| // DrawingBuffer. | 
| -  Deque<RefPtr<ColorBuffer>> m_recycledMailboxQueue; | 
| +  Deque<RefPtr<ColorBuffer>> m_recycledColorBufferQueue; | 
|  | 
| // If the width and height of the Canvas's backing store don't | 
| // match those that we were given in the most recent call to | 
| @@ -529,9 +520,6 @@ class PLATFORM_EXPORT DrawingBuffer | 
| // used to resize the Canvas. | 
| SkBitmap m_resizingBitmap; | 
|  | 
| -  // Used to flip a bitmap vertically. | 
| -  Vector<uint8_t> m_scanline; | 
| - | 
| // In the case of OffscreenCanvas, we do not want to enable the | 
| // WebGLImageChromium flag, so we replace all the | 
| // RuntimeEnabledFeatures::webGLImageChromiumEnabled() call with | 
|  |