Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Unified Diff: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h

Issue 2402603002: State management cleanup (Closed)
Patch Set: Make state dirtying explosive Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698