Title: [128646] trunk/Source/WebCore
Revision
128646
Author
[email protected]
Date
2012-09-14 13:08:09 -0700 (Fri, 14 Sep 2012)

Log Message

[CSS Shaders] Enable anti-aliasing on the FECustomFilter
https://bugs.webkit.org/show_bug.cgi?id=96668

Reviewed by Dean Jackson.

Added multisample frame buffer for the FECustomFilter. It will try to allocate a multisample framebuffer
with a maximum sample count of 4. At the end it will blit the samples back to the original frame buffer,
so that we can read the pixels back.

This patch uses extensions GL_ANGLE_framebuffer_multisample, GL_ANGLE_framebuffer_blit
and GL_OES_rgb8_rgba8.

No new tests, multisampling is not working in Chromium DRT and has not pixel effect on WebKit Mac.

* platform/graphics/filters/FECustomFilter.cpp:
(WebCore::FECustomFilter::FECustomFilter):
(WebCore::FECustomFilter::deleteRenderBuffers):
(WebCore):
(WebCore::FECustomFilter::deleteMultisampleRenderBuffers):
(WebCore::FECustomFilter::drawFilterMesh):
(WebCore::FECustomFilter::createMultisampleBuffer):
(WebCore::FECustomFilter::resolveMultisampleBuffer):
(WebCore::FECustomFilter::canUseMultisampleBuffers):
(WebCore::FECustomFilter::resizeMultisampleBuffers):
(WebCore::FECustomFilter::resizeContext):
* platform/graphics/filters/FECustomFilter.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (128645 => 128646)


--- trunk/Source/WebCore/ChangeLog	2012-09-14 20:04:30 UTC (rev 128645)
+++ trunk/Source/WebCore/ChangeLog	2012-09-14 20:08:09 UTC (rev 128646)
@@ -1,3 +1,32 @@
+2012-09-14  Alexandru Chiculita  <[email protected]>
+
+        [CSS Shaders] Enable anti-aliasing on the FECustomFilter
+        https://bugs.webkit.org/show_bug.cgi?id=96668
+
+        Reviewed by Dean Jackson.
+
+        Added multisample frame buffer for the FECustomFilter. It will try to allocate a multisample framebuffer
+        with a maximum sample count of 4. At the end it will blit the samples back to the original frame buffer,
+        so that we can read the pixels back.
+
+        This patch uses extensions GL_ANGLE_framebuffer_multisample, GL_ANGLE_framebuffer_blit
+        and GL_OES_rgb8_rgba8.
+
+        No new tests, multisampling is not working in Chromium DRT and has not pixel effect on WebKit Mac.
+
+        * platform/graphics/filters/FECustomFilter.cpp:
+        (WebCore::FECustomFilter::FECustomFilter):
+        (WebCore::FECustomFilter::deleteRenderBuffers):
+        (WebCore):
+        (WebCore::FECustomFilter::deleteMultisampleRenderBuffers):
+        (WebCore::FECustomFilter::drawFilterMesh):
+        (WebCore::FECustomFilter::createMultisampleBuffer):
+        (WebCore::FECustomFilter::resolveMultisampleBuffer):
+        (WebCore::FECustomFilter::canUseMultisampleBuffers):
+        (WebCore::FECustomFilter::resizeMultisampleBuffers):
+        (WebCore::FECustomFilter::resizeContext):
+        * platform/graphics/filters/FECustomFilter.h:
+
 2012-09-14  Bo Liu  <[email protected]>
 
         Add in-place reload behavior to ImagesEnabled setting

Modified: trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp (128645 => 128646)


--- trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp	2012-09-14 20:04:30 UTC (rev 128645)
+++ trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp	2012-09-14 20:08:09 UTC (rev 128646)
@@ -43,12 +43,12 @@
 #include "CustomFilterTransformParameter.h"
 #include "CustomFilterValidatedProgram.h"
 #include "DrawingBuffer.h"
+#include "Extensions3D.h"
 #include "GraphicsContext3D.h"
 #include "ImageData.h"
 #include "NotImplemented.h"
 #include "RenderTreeAsText.h"
 #include "TextStream.h"
-#include "Texture.h"
 #include "TilingData.h"
 #include "TransformationMatrix.h"
 
@@ -56,6 +56,8 @@
 
 namespace WebCore {
 
+static const int kMaxSampleCount = 4;
+
 static void orthogonalProjectionMatrix(TransformationMatrix& matrix, float left, float right, float bottom, float top)
 {
     ASSERT(matrix.isIdentity());
@@ -89,6 +91,10 @@
     , m_frameBuffer(0)
     , m_depthBuffer(0)
     , m_destTexture(0)
+    , m_triedMultisampleBuffer(false)
+    , m_multisampleFrameBuffer(0)
+    , m_multisampleRenderBuffer(0)
+    , m_multisampleDepthBuffer(0)
     , m_parameters(parameters)
     , m_meshRows(meshRows)
     , m_meshColumns(meshColumns)
@@ -134,8 +140,28 @@
         m_context->deleteTexture(m_destTexture);
         m_destTexture = 0;
     }
+    deleteMultisampleRenderBuffers();
 }
 
+void FECustomFilter::deleteMultisampleRenderBuffers()
+{
+    if (m_multisampleFrameBuffer) {
+        // Make sure to unbind any framebuffer from the context first, otherwise
+        // some platforms might refuse to bind the same buffer id again.
+        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+        m_context->deleteFramebuffer(m_multisampleFrameBuffer);
+        m_multisampleFrameBuffer = 0;
+    }
+    if (m_multisampleRenderBuffer) {
+        m_context->deleteRenderbuffer(m_multisampleRenderBuffer);
+        m_multisampleRenderBuffer = 0;
+    }
+    if (m_multisampleDepthBuffer) {
+        m_context->deleteRenderbuffer(m_multisampleDepthBuffer);
+        m_multisampleDepthBuffer = 0;
+    }
+}
+
 void FECustomFilter::platformApplySoftware()
 {
     if (!applyShader())
@@ -157,7 +183,8 @@
 
 void FECustomFilter::drawFilterMesh(Platform3DObject inputTexture)
 {
-    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_frameBuffer);
+    bool multisample = canUseMultisampleBuffers();
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, multisample ? m_multisampleFrameBuffer : m_frameBuffer);
     m_context->viewport(0, 0, m_contextSize.width(), m_contextSize.height());
     
     m_context->clearColor(0, 0, 0, 0);
@@ -166,6 +193,9 @@
     bindProgramAndBuffers(inputTexture);
     m_context->drawElements(GraphicsContext3D::TRIANGLES, m_mesh->indicesCount(), GraphicsContext3D::UNSIGNED_SHORT, 0);
     unbindVertexAttributes();
+
+    if (multisample)
+        resolveMultisampleBuffer();
 }
 
 bool FECustomFilter::prepareForDrawing(CustomFilterDrawType filterDrawType)
@@ -263,6 +293,91 @@
     return m_frameBuffer && m_depthBuffer && m_destTexture;
 }
 
+bool FECustomFilter::createMultisampleBuffer()
+{
+    ASSERT(!m_triedMultisampleBuffer);
+    m_triedMultisampleBuffer = true;
+
+    Extensions3D* extensions = m_context->getExtensions();
+    if (!extensions 
+        || !extensions->supports("GL_ANGLE_framebuffer_multisample")
+        || !extensions->supports("GL_ANGLE_framebuffer_blit")
+        || !extensions->supports("GL_OES_rgb8_rgba8"))
+        return false;
+
+    extensions->ensureEnabled("GL_ANGLE_framebuffer_blit");
+    extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
+    extensions->ensureEnabled("GL_OES_rgb8_rgba8");
+
+    if (!m_multisampleFrameBuffer)
+        m_multisampleFrameBuffer = m_context->createFramebuffer();
+    if (!m_multisampleRenderBuffer)
+        m_multisampleRenderBuffer = m_context->createRenderbuffer();
+    if (!m_multisampleDepthBuffer)
+        m_multisampleDepthBuffer = m_context->createRenderbuffer();
+
+    return true;
+}
+
+void FECustomFilter::resolveMultisampleBuffer()
+{
+    ASSERT(m_triedMultisampleBuffer && m_multisampleFrameBuffer && m_multisampleRenderBuffer && m_multisampleDepthBuffer);
+    m_context->bindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_multisampleFrameBuffer);
+    m_context->bindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, m_frameBuffer);
+
+    ASSERT(m_context->getExtensions());
+    m_context->getExtensions()->blitFramebuffer(0, 0, m_contextSize.width(), m_contextSize.height(), 0, 0, m_contextSize.width(), m_contextSize.height(), GraphicsContext3D::COLOR_BUFFER_BIT, GraphicsContext3D::NEAREST);
+
+    m_context->bindFramebuffer(Extensions3D::READ_FRAMEBUFFER, 0);
+    m_context->bindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, 0);
+    
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_frameBuffer);
+}
+
+bool FECustomFilter::canUseMultisampleBuffers() const
+{
+    return m_triedMultisampleBuffer && m_multisampleFrameBuffer && m_multisampleRenderBuffer && m_multisampleDepthBuffer;
+}
+
+bool FECustomFilter::resizeMultisampleBuffers(const IntSize& newContextSize)
+{
+    if (!m_triedMultisampleBuffer && !createMultisampleBuffer())
+         return false;
+ 
+    if (!canUseMultisampleBuffers())
+        return false;
+
+    int maxSupportedSampleCount = 0;
+    m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSupportedSampleCount);
+    int sampleCount = std::min(kMaxSampleCount, maxSupportedSampleCount);
+    if (!sampleCount) {
+        deleteMultisampleRenderBuffers();
+        return false;
+    }
+
+    Extensions3D* extensions = m_context->getExtensions();
+    ASSERT(extensions);
+    
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFrameBuffer);
+
+    m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleRenderBuffer);
+    extensions->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, Extensions3D::RGBA8_OES, newContextSize.width(), newContextSize.height());
+    m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, m_multisampleRenderBuffer);
+
+    m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleDepthBuffer);
+    extensions->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::DEPTH_COMPONENT16, newContextSize.width(), newContextSize.height());
+    m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_multisampleDepthBuffer);
+
+    m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+
+    if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+        deleteMultisampleRenderBuffers();
+        return false;
+    }
+
+    return true;
+}
+
 bool FECustomFilter::resizeContextIfNeeded(const IntSize& newContextSize)
 {
     if (newContextSize.isEmpty())
@@ -280,6 +395,8 @@
 
 bool FECustomFilter::resizeContext(const IntSize& newContextSize)
 {
+    bool multisample = resizeMultisampleBuffers(newContextSize);
+
     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_frameBuffer);
     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_destTexture);
     // We are going to clear the output buffer anyway, so we can safely initialize the destination texture with garbage data.
@@ -291,13 +408,23 @@
 #endif
     m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_destTexture, 0);
  
-    m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
-    m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, newContextSize.width(), newContextSize.height());
-    m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+    // We don't need the depth buffer for the texture framebuffer, if we already
+    // have a multisample buffer.
+    if (!multisample) {
+        m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+        m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, newContextSize.width(), newContextSize.height());
+        m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+    }
 
     if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
         return false;
 
+    if (multisample) {
+        // Clear the framebuffer first, otherwise the first blit will fail.
+        m_context->clearColor(0, 0, 0, 0);
+        m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+    }
+
     m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
     
     m_contextSize = newContextSize;

Modified: trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.h (128645 => 128646)


--- trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.h	2012-09-14 20:04:30 UTC (rev 128645)
+++ trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.h	2012-09-14 20:08:09 UTC (rev 128646)
@@ -56,7 +56,6 @@
 class DrawingBuffer;
 class GraphicsContext3D;
 class IntSize;
-class Texture;
 
 class FECustomFilter : public FilterEffect {
 public:
@@ -92,6 +91,12 @@
     bool resizeContextIfNeeded(const IntSize&);
     bool resizeContext(const IntSize&);
 
+    bool canUseMultisampleBuffers() const;
+    bool createMultisampleBuffer();
+    bool resizeMultisampleBuffers(const IntSize&);
+    void resolveMultisampleBuffer();
+    void deleteMultisampleRenderBuffers();
+
     bool ensureFrameBuffer();
     void deleteRenderBuffers();
 
@@ -118,6 +123,11 @@
     Platform3DObject m_depthBuffer;
     Platform3DObject m_destTexture;
 
+    bool m_triedMultisampleBuffer;
+    Platform3DObject m_multisampleFrameBuffer;
+    Platform3DObject m_multisampleRenderBuffer;
+    Platform3DObject m_multisampleDepthBuffer;
+
     RefPtr<CustomFilterProgram> m_program;
     CustomFilterParameterList m_parameters;
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to