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

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

Issue 1950053003: Clean up DrawingBuffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix completeness checks. Created 4 years, 7 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.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index bf75d4505c27cac412baba4f600d23414397e50b..52d33ed7b985b76d51a924bb855591845fc8c24c 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -110,8 +110,8 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3DP
if (discardFramebufferSupported)
extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer");
- RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(contextProvider), extensionsUtil.release(), discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, preserve));
- if (!drawingBuffer->initialize(size, wantDepthBuffer, wantStencilBuffer, multisampleSupported)) {
+ RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(contextProvider), extensionsUtil.release(), discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, preserve, wantDepthBuffer, wantStencilBuffer));
+ if (!drawingBuffer->initialize(size, multisampleSupported)) {
drawingBuffer->beginDestruction();
return PassRefPtr<DrawingBuffer>();
}
@@ -129,38 +129,18 @@ DrawingBuffer::DrawingBuffer(
bool discardFramebufferSupported,
bool wantAlphaChannel,
bool premultipliedAlpha,
- PreserveDrawingBuffer preserve)
+ PreserveDrawingBuffer preserve,
+ bool wantDepth,
+ bool wantStencil)
: m_preserveDrawingBuffer(preserve)
- , m_scissorEnabled(false)
- , m_texture2DBinding(0)
- , m_drawFramebufferBinding(0)
- , m_readFramebufferBinding(0)
- , m_renderbufferBinding(0)
- , m_activeTextureUnit(GL_TEXTURE0)
, m_contextProvider(std::move(contextProvider))
, m_gl(m_contextProvider->contextGL())
, m_extensionsUtil(std::move(extensionsUtil))
- , m_size(-1, -1)
, m_discardFramebufferSupported(discardFramebufferSupported)
, m_wantAlphaChannel(wantAlphaChannel)
, m_premultipliedAlpha(premultipliedAlpha)
- , m_hasImplicitStencilBuffer(false)
- , m_fbo(0)
- , m_depthStencilBuffer(0)
- , m_multisampleFBO(0)
- , m_intermediateFBO(0)
- , m_intermediateRenderbuffer(0)
- , m_multisampleColorBuffer(0)
- , m_contentsChanged(true)
- , m_contentsChangeCommitted(false)
- , m_bufferClearNeeded(false)
- , m_antiAliasingMode(None)
- , m_maxTextureSize(0)
- , m_sampleCount(0)
- , m_packAlignment(4)
- , m_destructionInProgress(false)
- , m_isHidden(false)
- , m_filterQuality(kLow_SkFilterQuality)
+ , m_wantDepth(wantDepth)
+ , m_wantStencil(wantStencil)
{
memset(m_colorMask, 0, 4 * sizeof(GLboolean));
memset(m_clearColor, 0, 4 * sizeof(GLfloat));
@@ -224,7 +204,7 @@ void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality)
}
}
-bool DrawingBuffer::requiresRGBEmulation()
+bool DrawingBuffer::requiresAlphaChannelToBePreserved()
{
// When an explicit resolve is required, clients draw into a render buffer
// which is never backed by an IOSurface.
@@ -285,16 +265,11 @@ bool DrawingBuffer::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExt
if (m_preserveDrawingBuffer == Discard) {
std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer);
- // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a
- // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding.
- // If this stops being true at some point, we should track the current framebuffer binding in the DrawingBuffer and restore
- // it after attaching the new back buffer here.
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
- attachColorBufferToCurrentFBO();
+ attachColorBufferToReadFramebuffer();
if (m_discardFramebufferSupported) {
// Explicitly discard framebuffer to save GPU memory bandwidth for tile-based GPU arch.
- const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
+ const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
}
} else {
@@ -462,7 +437,7 @@ void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox)
ASSERT_NOT_REACHED();
}
-bool DrawingBuffer::initialize(const IntSize& size, bool wantDepthBuffer, bool wantStencilBuffer, bool useMultisampling)
+bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling)
{
if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
// Need to try to restore the context again later.
@@ -485,15 +460,18 @@ bool DrawingBuffer::initialize(const IntSize& size, bool wantDepthBuffer, bool w
m_sampleCount = std::min(4, maxSampleCount);
m_gl->GenFramebuffers(1, &m_fbo);
-
m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
- createSecondaryBuffers();
- if (!reset(size, wantDepthBuffer || wantStencilBuffer))
+ if (wantExplicitResolve()) {
+ m_gl->GenFramebuffers(1, &m_multisampleFBO);
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
+ m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer);
+ }
+ if (!reset(size))
return false;
if (m_depthStencilBuffer) {
- DCHECK(wantDepthBuffer || wantStencilBuffer);
- m_hasImplicitStencilBuffer = !wantStencilBuffer;
+ DCHECK(wantDepthOrStencil());
+ m_hasImplicitStencilBuffer = !m_wantStencil;
}
if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
@@ -607,8 +585,8 @@ void DrawingBuffer::beginDestruction()
if (m_fbo)
m_gl->DeleteFramebuffers(1, &m_fbo);
- if (m_multisampleColorBuffer)
- m_gl->DeleteRenderbuffers(1, &m_multisampleColorBuffer);
+ if (m_multisampleRenderbuffer)
+ m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);
if (m_intermediateFBO)
m_gl->DeleteFramebuffers(1, &m_intermediateFBO);
@@ -628,7 +606,7 @@ void DrawingBuffer::beginDestruction()
m_colorBuffer = TextureInfo();
m_frontColorBuffer = FrontBufferInfo();
- m_multisampleColorBuffer = 0;
+ m_multisampleRenderbuffer = 0;
m_depthStencilBuffer = 0;
m_multisampleFBO = 0;
m_fbo = 0;
@@ -649,65 +627,38 @@ GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters)
return offscreenColorTexture;
}
-void DrawingBuffer::createSecondaryBuffers()
+bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size)
{
- // create a multisample FBO
- if (m_antiAliasingMode == MSAAExplicitResolve) {
- m_gl->GenFramebuffers(1, &m_multisampleFBO);
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
- m_gl->GenRenderbuffers(1, &m_multisampleColorBuffer);
- }
-}
+ DCHECK(wantExplicitResolve());
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
+ m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer);
+ m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCount, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.height());
-bool DrawingBuffer::resizeFramebuffer(const IntSize& size, bool wantDepthOrStencilBuffer)
-{
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
- if (m_antiAliasingMode != MSAAExplicitResolve && wantDepthOrStencilBuffer)
- resizeDepthStencil(size);
- if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ if (m_gl->GetError() == GL_OUT_OF_MEMORY)
return false;
- return true;
-}
+ m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleRenderbuffer);
-bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size, bool wantDepthOrStencilBuffer)
-{
- if (m_antiAliasingMode == MSAAExplicitResolve) {
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
-
- m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer);
- m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCount, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.height());
+ if (m_intermediateFBO) {
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_intermediateFBO);
+ m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_intermediateRenderbuffer);
+ m_gl->RenderbufferStorage(GL_RENDERBUFFER, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.height());
if (m_gl->GetError() == GL_OUT_OF_MEMORY)
return false;
- m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer);
- if (wantDepthOrStencilBuffer)
- resizeDepthStencil(size);
+ m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_intermediateRenderbuffer);
if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
- if (m_intermediateFBO) {
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_intermediateFBO);
- m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_intermediateRenderbuffer);
- m_gl->RenderbufferStorage(GL_RENDERBUFFER, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.height());
-
- if (m_gl->GetError() == GL_OUT_OF_MEMORY)
- return false;
-
- m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_intermediateRenderbuffer);
- if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- return false;
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
- }
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
}
-
return true;
}
void DrawingBuffer::resizeDepthStencil(const IntSize& size)
{
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
if (!m_depthStencilBuffer)
m_gl->GenRenderbuffers(1, &m_depthStencilBuffer);
m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
@@ -723,7 +674,34 @@ void DrawingBuffer::resizeDepthStencil(const IntSize& size)
m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0);
}
+bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size)
+{
+ // Resize or create m_colorBuffer.
+ if (m_colorBuffer.textureId) {
+ resizeTextureMemory(&m_colorBuffer, size);
+ } else {
+ m_colorBuffer = createTextureAndAllocateMemory(size);
+ }
+ attachColorBufferToReadFramebuffer();
+
+ if (wantExplicitResolve()) {
+ if (!resizeMultisampleFramebuffer(size))
+ return false;
+ }
+
+ if (wantDepthOrStencil())
+ resizeDepthStencil(size);
+
+ if (wantExplicitResolve()) {
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
+ if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ return false;
+ }
+
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
+}
void DrawingBuffer::clearFramebuffers(GLbitfield clearMask)
{
@@ -759,7 +737,7 @@ IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, const IntSize& cur
return adjustedSize;
}
-bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer)
+bool DrawingBuffer::reset(const IntSize& newSize)
{
ASSERT(!newSize.isEmpty());
IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize);
@@ -768,18 +746,7 @@ bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer)
if (adjustedSize != m_size) {
do {
- if (m_colorBuffer.textureId) {
- resizeTextureMemory(&m_colorBuffer, adjustedSize);
- } else {
- m_colorBuffer = createTextureAndAllocateMemory(adjustedSize);
- }
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
- attachColorBufferToCurrentFBO();
-
- // resize multisample FBO
- if (!resizeMultisampleFramebuffer(adjustedSize, wantDepthOrStencilBuffer)
- || !resizeFramebuffer(adjustedSize, wantDepthOrStencilBuffer)) {
+ if (!resizeDefaultFramebuffer(adjustedSize)) {
adjustedSize.scale(s_resourceAdjustedRatio);
continue;
}
@@ -794,7 +761,7 @@ bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer)
m_gl->Disable(GL_SCISSOR_TEST);
m_gl->ClearColor(0, 0, 0, 0);
- m_gl->ColorMask(true, true, true, !requiresRGBEmulation());
+ m_gl->ColorMask(true, true, true, !requiresAlphaChannelToBePreserved());
GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
if (!!m_depthStencilBuffer) {
@@ -814,7 +781,7 @@ bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer)
void DrawingBuffer::commit()
{
- if (m_multisampleFBO && !m_contentsChangeCommitted) {
+ if (wantExplicitResolve() && !m_contentsChangeCommitted) {
m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);
@@ -897,10 +864,7 @@ bool DrawingBuffer::multisample() const
void DrawingBuffer::bind(GLenum target)
{
- if (target != GL_READ_FRAMEBUFFER)
- m_gl->BindFramebuffer(target, m_multisampleFBO ? m_multisampleFBO : m_fbo);
- else
- m_gl->BindFramebuffer(target, m_fbo);
+ m_gl->BindFramebuffer(target, wantExplicitResolve() ? m_multisampleFBO : m_fbo);
}
void DrawingBuffer::setPackAlignment(GLint param)
@@ -1086,17 +1050,39 @@ void DrawingBuffer::resizeTextureMemory(TextureInfo* info, const IntSize& size)
texImage2DResourceSafe(info->parameters.target, 0, info->parameters.creationInternalColorFormat, size.width(), size.height(), 0, info->parameters.colorFormat, GL_UNSIGNED_BYTE);
}
-void DrawingBuffer::attachColorBufferToCurrentFBO()
+void DrawingBuffer::attachColorBufferToReadFramebuffer()
{
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
GLenum target = m_colorBuffer.parameters.target;
+ GLenum id = m_colorBuffer.textureId;
- m_gl->BindTexture(target, m_colorBuffer.textureId);
+ m_gl->BindTexture(target, id);
if (m_antiAliasingMode == MSAAImplicitResolve)
- m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_colorBuffer.textureId, 0, m_sampleCount);
+ m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount);
else
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_colorBuffer.textureId, 0);
+ m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0);
+
+ restoreTextureBindings();
+ restoreFramebufferBindings();
+}
+bool DrawingBuffer::wantExplicitResolve()
+{
+ return m_antiAliasingMode == MSAAExplicitResolve;
+}
+
+bool DrawingBuffer::wantDepthOrStencil()
+{
+ return m_wantDepth || m_wantStencil;
+}
+
+void DrawingBuffer::restoreTextureBindings()
+{
+ // This class potentially modifies the bindings for GL_TEXTURE_2D and
+ // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since
+ // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
}

Powered by Google App Engine
This is Rietveld 408576698