[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

cmarrin at apple.com cmarrin at apple.com
Wed Dec 22 15:44:36 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 35eb1e5dfb63a6e6cf1c06346ddab5a83f15e6a9
Author: cmarrin at apple.com <cmarrin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Nov 11 17:11:31 2010 +0000

    2010-11-10  Chris Marrin  <cmarrin at apple.com>
    
            Reviewed by James Robinson.
    
            Add multisampling support to DrawingBuffer.
            https://bugs.webkit.org/show_bug.cgi?id=49206
    
            Added support for the GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample
            extensions to Extensions3D. Then I use these to add multisample support to DrawingBuffer.
    
            * platform/graphics/Extensions3D.h:
            * platform/graphics/chromium/DrawingBufferChromium.cpp:
            (WebCore::DrawingBuffer::platformColorBuffer):
            * platform/graphics/chromium/Extensions3DChromium.h:
            (WebCore::Extensions3DChromium::blitFramebuffer):
            (WebCore::Extensions3DChromium::renderbufferStorageMultisample):
            * platform/graphics/gpu/DrawingBuffer.cpp:
            (WebCore::DrawingBuffer::create):
            (WebCore::DrawingBuffer::clear):
            (WebCore::DrawingBuffer::reset):
            (WebCore::DrawingBuffer::commit):
            (WebCore::DrawingBuffer::bind):
            * platform/graphics/gpu/DrawingBuffer.h:
            (WebCore::DrawingBuffer::multisample):
            * platform/graphics/gpu/mac/DrawingBufferMac.mm:
            (WebCore::DrawingBuffer::DrawingBuffer):
            (WebCore::DrawingBuffer::platformLayer):
            (WebCore::DrawingBuffer::platformColorBuffer):
            * platform/graphics/opengl/Extensions3DOpenGL.cpp:
            (WebCore::Extensions3DOpenGL::supports):
            (WebCore::Extensions3DOpenGL::blitFramebuffer):
            (WebCore::Extensions3DOpenGL::renderbufferStorageMultisample):
            * platform/graphics/opengl/Extensions3DOpenGL.h:
            * platform/graphics/skia/ImageBufferSkia.cpp:
            (WebCore::ImageBuffer::draw):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71827 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 495623b..3e890ce 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2010-11-10  Chris Marrin  <cmarrin at apple.com>
+
+        Reviewed by James Robinson.
+
+        Add multisampling support to DrawingBuffer.
+        https://bugs.webkit.org/show_bug.cgi?id=49206
+
+        Added support for the GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample
+        extensions to Extensions3D. Then I use these to add multisample support to DrawingBuffer.
+
+        * platform/graphics/Extensions3D.h:
+        * platform/graphics/chromium/DrawingBufferChromium.cpp:
+        (WebCore::DrawingBuffer::platformColorBuffer):
+        * platform/graphics/chromium/Extensions3DChromium.h:
+        (WebCore::Extensions3DChromium::blitFramebuffer):
+        (WebCore::Extensions3DChromium::renderbufferStorageMultisample):
+        * platform/graphics/gpu/DrawingBuffer.cpp:
+        (WebCore::DrawingBuffer::create):
+        (WebCore::DrawingBuffer::clear):
+        (WebCore::DrawingBuffer::reset):
+        (WebCore::DrawingBuffer::commit):
+        (WebCore::DrawingBuffer::bind):
+        * platform/graphics/gpu/DrawingBuffer.h:
+        (WebCore::DrawingBuffer::multisample):
+        * platform/graphics/gpu/mac/DrawingBufferMac.mm:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        (WebCore::DrawingBuffer::platformLayer):
+        (WebCore::DrawingBuffer::platformColorBuffer):
+        * platform/graphics/opengl/Extensions3DOpenGL.cpp:
+        (WebCore::Extensions3DOpenGL::supports):
+        (WebCore::Extensions3DOpenGL::blitFramebuffer):
+        (WebCore::Extensions3DOpenGL::renderbufferStorageMultisample):
+        * platform/graphics/opengl/Extensions3DOpenGL.h:
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::ImageBuffer::draw):
+
 2010-11-11  Eric Carlson  <eric.carlson at apple.com>
 
         Build fix after r71824.
diff --git a/WebCore/platform/graphics/Extensions3D.h b/WebCore/platform/graphics/Extensions3D.h
index 0aed8e7..d2e6383 100644
--- a/WebCore/platform/graphics/Extensions3D.h
+++ b/WebCore/platform/graphics/Extensions3D.h
@@ -48,12 +48,13 @@ public:
     //   GL_EXT_read_format_bgra
     //   GL_ARB_robustness
     //   GL_EXT_packed_depth_stencil / GL_OES_packed_depth_stencil
+    //   GL_ANGLE_framebuffer_blit / GL_ANGLE_framebuffer_multisample
 
     // Takes full name of extension; for example,
     // "GL_EXT_texture_format_BGRA8888".
     virtual bool supports(const String&) = 0;
 
-    enum {
+    enum ExtensionsEnumType {
         // GL_EXT_texture_format_BGRA8888 enums
         BGRA_EXT = 0x80E1,
 
@@ -63,11 +64,28 @@ public:
         UNKNOWN_CONTEXT_RESET_ARB = 0x8255,
 
         // GL_EXT/OES_packed_depth_stencil enums
-        DEPTH24_STENCIL8 = 0x88F0
+        DEPTH24_STENCIL8 = 0x88F0,
+        
+        // GL_ANGLE_framebuffer_blit names
+        READ_FRAMEBUFFER = 0x8CA8,
+        DRAW_FRAMEBUFFER = 0x8CA9,
+        DRAW_FRAMEBUFFER_BINDING = 0x8CA6, 
+        READ_FRAMEBUFFER_BINDING = 0x8CAA,
+        
+        // GL_ANGLE_framebuffer_multisample names
+        RENDERBUFFER_SAMPLES = 0x8CAB,
+        FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56,
+        MAX_SAMPLES = 0x8D57
     };
 
     // GL_ARB_robustness
     virtual int getGraphicsResetStatusARB() = 0;
+    
+    // GL_ANGLE_framebuffer_blit
+    virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) = 0;
+    
+    // GL_ANGLE_framebuffer_multisample
+    virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) = 0;    
 };
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index e44ec9d..a7085d1 100644
--- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -118,18 +118,8 @@ void DrawingBuffer::publishToPlatformLayer()
 }
 #endif
 
-void DrawingBuffer::reset(const IntSize& newSize)
+void DrawingBuffer::didReset()
 {
-    if (!m_context)
-        return;
-        
-    if (m_size == newSize)
-        return;
-    m_size = newSize;
-
-    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_internal->offscreenColorTexture);
-    m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_size.width(), m_size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
-
 #if USE(ACCELERATED_COMPOSITING)
     if (m_internal->platformLayer)
         m_internal->platformLayer->setTextureChanged();
@@ -145,7 +135,7 @@ PlatformLayer* DrawingBuffer::platformLayer()
 }
 #endif
 
-unsigned DrawingBuffer::getRenderingResultsAsTexture()
+Platform3DObject DrawingBuffer::platformColorBuffer() const
 {
     return m_internal->offscreenColorTexture;
 }
diff --git a/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/WebCore/platform/graphics/chromium/Extensions3DChromium.h
index 0fd1fff..2a71a38 100644
--- a/WebCore/platform/graphics/chromium/Extensions3DChromium.h
+++ b/WebCore/platform/graphics/chromium/Extensions3DChromium.h
@@ -39,6 +39,8 @@ public:
     // Extensions3D methods.
     virtual bool supports(const String&);
     virtual int getGraphicsResetStatusARB();
+    virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) { }
+    virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) { }
 
     enum {
         // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object)
diff --git a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index 2dc0517..dc75104 100644
--- a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -34,11 +34,16 @@
 
 #include "DrawingBuffer.h"
 
+#include "Extensions3D.h"
+
+using namespace std;
+
 namespace WebCore {
 
 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size)
 {
     RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size));
+    drawingBuffer->m_multisampleExtensionSupported = context->getExtensions()->supports("GL_ANGLE_framebuffer_blit") && context->getExtensions()->supports("GL_ANGLE_framebuffer_multisample");
     return (drawingBuffer->m_context) ? drawingBuffer.release() : 0;
 }
 
@@ -46,21 +51,199 @@ void DrawingBuffer::clear()
 {
     if (!m_context)
         return;
-
+        
     m_context->makeContextCurrent();
+    m_context->deleteTexture(m_colorBuffer);
+    m_colorBuffer = 0;
+    
+    if (m_multisampleColorBuffer) {
+        m_context->deleteRenderbuffer(m_multisampleColorBuffer);
+        m_multisampleColorBuffer = 0;
+    }
+    
+    if (m_multisampleDepthStencilBuffer) {
+        m_context->deleteRenderbuffer(m_multisampleDepthStencilBuffer);
+        m_multisampleDepthStencilBuffer = 0;
+    }
+    
+    if (m_depthStencilBuffer) {
+        m_context->deleteRenderbuffer(m_depthStencilBuffer);
+        m_depthStencilBuffer = 0;
+    }
+    
+    if (m_multisampleFBO) {
+        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+        m_context->deleteFramebuffer(m_multisampleFBO);
+        m_multisampleFBO = 0;
+    }
+        
     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
     m_context->deleteFramebuffer(m_fbo);
     m_fbo = 0;
-
+    
     m_context.clear();
 }
 
-void DrawingBuffer::bind()
+void DrawingBuffer::reset(const IntSize& newSize)
 {
+    if (m_size == newSize)
+        return;
+    m_size = newSize;
+
     if (!m_context)
         return;
         
+    m_context->makeContextCurrent();
+    
+    const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
+    unsigned long internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
+    if (attributes.alpha) {
+        internalColorFormat = GraphicsContext3D::RGBA;
+        colorFormat = GraphicsContext3D::RGBA;
+    } else {
+        internalColorFormat = GraphicsContext3D::RGB;
+        colorFormat = GraphicsContext3D::RGB;
+    }
+    if (attributes.stencil || attributes.depth) {
+        // We don't allow the logic where stencil is required and depth is not.
+        // See GraphicsContext3D constructor.
+        if (attributes.stencil && attributes.depth)
+            internalDepthStencilFormat = GraphicsContext3D::DEPTH_STENCIL;
+        else
+            internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT;
+    }
+
+    // Resize the multisample FBO if needed
+    if (multisample()) {
+        int maxSampleCount;
+        
+        m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSampleCount);
+        int sampleCount = min(maximumDesiredNumberOfSamples, maxSampleCount);
+        if (sampleCount > maxSampleCount)
+            sampleCount = maxSampleCount;
+        
+        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+
+        m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
+        m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, internalColorFormat, m_size.width(), m_size.height());
+        m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
+        if (attributes.stencil || attributes.depth) {
+            m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleDepthStencilBuffer);
+            m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, internalDepthStencilFormat, m_size.width(), m_size.height());
+            if (attributes.stencil)
+                m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_multisampleDepthStencilBuffer);
+            if (attributes.depth)
+                m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_multisampleDepthStencilBuffer);
+        }
+        m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+        if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+            // Cleanup
+            clear();
+            return;
+        }
+    }
+
+    // Resize the regular FBO
     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+
+    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
+    m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE, 0);
+    m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE, m_colorBuffer, 0);
+    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+    if (!multisample() && (attributes.stencil || attributes.depth)) {
+        m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+        m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, internalDepthStencilFormat, m_size.width(), m_size.height());
+        if (attributes.stencil)
+            m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+        if (attributes.depth)
+            m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+        m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+    }
+    if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+        // Cleanup
+        clear();
+        return;
+    }
+
+    clearBuffers();
+    m_context->flush();
+    
+    didReset();
+}
+
+void DrawingBuffer::clearBuffers()
+{
+    const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
+
+    if (multisample())
+        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+
+    // Initialize renderbuffers to 0.
+    unsigned char colorMask[] = {true, true, true, true}, depthMask = true, stencilMask = true;
+    unsigned char isScissorEnabled = false;
+    unsigned char isDitherEnabled = false;
+    unsigned long clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
+    m_context->getBooleanv(GraphicsContext3D::COLOR_WRITEMASK, colorMask);
+    m_context->colorMask(true, true, true, true);
+    if (attributes.depth) {
+        m_context->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
+        m_context->depthMask(true);
+        clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+    }
+    if (attributes.stencil) {
+        m_context->getBooleanv(GraphicsContext3D::STENCIL_WRITEMASK, &stencilMask);
+        m_context->stencilMask(true);
+        clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+    }
+    isScissorEnabled = m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST);
+    m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+    isDitherEnabled = m_context->isEnabled(GraphicsContext3D::DITHER);
+    m_context->disable(GraphicsContext3D::DITHER);
+
+    m_context->clear(clearMask);
+
+    m_context->colorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
+    if (attributes.depth)
+        m_context->depthMask(depthMask);
+    if (attributes.stencil)
+        m_context->stencilMask(stencilMask);
+    if (isScissorEnabled)
+        m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+    else
+        m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+    if (isDitherEnabled)
+        m_context->enable(GraphicsContext3D::DITHER);
+    else
+        m_context->disable(GraphicsContext3D::DITHER);
+}
+
+void DrawingBuffer::commit(long x, long y, long width, long height)
+{
+    if (!m_context)
+        return;
+        
+    if (width < 0)
+        width = m_size.width();
+    if (height < 0)
+        height = m_size.height();
+        
+    m_context->makeContextCurrent();
+    
+    if (m_multisampleFBO) {
+        m_context->bindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_multisampleFBO);
+        m_context->bindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, m_fbo);
+        m_context->getExtensions()->blitFramebuffer(x, y, width, height, x, y, width, height, GraphicsContext3D::COLOR_BUFFER_BIT, GraphicsContext3D::LINEAR);
+    }
+    
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+}
+
+void DrawingBuffer::bind()
+{
+    if (!m_context)
+        return;
+        
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
     m_context->viewport(0, 0, m_size.width(), m_size.height());
 }
 
diff --git a/WebCore/platform/graphics/gpu/DrawingBuffer.h b/WebCore/platform/graphics/gpu/DrawingBuffer.h
index 75c7f99..61d95a1 100644
--- a/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -48,6 +48,9 @@ namespace WebCore {
 struct DrawingBufferInternal;
 #endif
 
+// Maximum number of samples we want to use in multisampling buffers
+const int maximumDesiredNumberOfSamples = 8;
+
 // Manages a rendering target (framebuffer + attachment) for a canvas.  Can publish its rendering
 // results to a PlatformLayer for compositing.
 class DrawingBuffer : public RefCounted<DrawingBuffer> {
@@ -64,13 +67,18 @@ public:
     // to prevent invalid accesses to the resources.
     void clear();
     
+    // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound
+    void commit(long x = 0, long y = 0, long width = -1, long height = -1);
+    
+    bool multisample() const { return m_context && m_context->getContextAttributes().antialias && m_multisampleExtensionSupported; }
+    
+    Platform3DObject platformColorBuffer() const;
+
 #if USE(ACCELERATED_COMPOSITING)
     PlatformLayer* platformLayer();
     void publishToPlatformLayer();
 #endif
 
-    unsigned getRenderingResultsAsTexture();
-
 #if PLATFORM(CHROMIUM)
     class WillPublishCallback : public Noncopyable {
     public:
@@ -88,11 +96,24 @@ private:
     static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&);
     
     DrawingBuffer(GraphicsContext3D*, const IntSize&);
+    
+    // Platform specific function called after reset() so each platform can do extra work if needed
+    void didReset();
+    
+    void clearBuffers();
 
     RefPtr<GraphicsContext3D> m_context;
     IntSize m_size;
+    bool m_multisampleExtensionSupported;
     Platform3DObject m_fbo;
+    Platform3DObject m_colorBuffer;
+    Platform3DObject m_depthStencilBuffer;
 
+    // For multisampling
+    Platform3DObject m_multisampleFBO;
+    Platform3DObject m_multisampleColorBuffer;
+    Platform3DObject m_multisampleDepthStencilBuffer;
+    
 #if PLATFORM(CHROMIUM)
     OwnPtr<WillPublishCallback> m_callback;
     OwnPtr<DrawingBufferInternal> m_internal;
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index a230384..7c819ce 100644
--- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -54,6 +54,9 @@ PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow*
 {
     GraphicsContext3D::Attributes attr;
     attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
+    attr.depth = false;
+    attr.antialias = false; // FIXME: we eventually want aa, but it's not well tested yet, so leave it off for now.
+    
     RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
     if (!context)
         return 0;
diff --git a/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm b/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
index 7a8c501..89dcb9c 100644
--- a/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
+++ b/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
@@ -29,6 +29,7 @@
 
 #include "DrawingBuffer.h"
 
+#include "Extensions3D.h"
 #include "WebGLLayer.h"
 
 #import "BlockExceptions.h"
@@ -39,6 +40,11 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size)
     : m_context(context)
     , m_size(size)
     , m_fbo(context->createFramebuffer())
+    , m_colorBuffer(0)
+    , m_depthStencilBuffer(0)
+    , m_multisampleFBO(0)
+    , m_multisampleColorBuffer(0)
+    , m_multisampleDepthStencilBuffer(0)
 {
     ASSERT(m_fbo);
     if (!m_fbo) {
@@ -53,6 +59,40 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size)
         [m_platformLayer.get() setName:@"DrawingBuffer Layer"];
 #endif    
     END_BLOCK_OBJC_EXCEPTIONS
+
+    // create a texture to render into
+    m_colorBuffer = context->createTexture();
+    context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
+    context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+    context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+    context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+    context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+    context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+    
+    // Create the FBO
+    m_fbo = context->createFramebuffer();
+    ASSERT(m_fbo);
+    if (!m_fbo) {
+        clear();
+        return;
+    }
+        
+    const GraphicsContext3D::Attributes& attributes = context->getContextAttributes();
+    
+    // Create the stencil and depth buffer if needed
+    if (!multisample() && (attributes.stencil || attributes.depth))
+        m_depthStencilBuffer = context->createRenderbuffer();
+
+    // create a multisample FBO
+    if (multisample()) {
+        m_multisampleFBO = context->createFramebuffer();
+        context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+        m_multisampleColorBuffer = context->createRenderbuffer();
+        if (attributes.stencil || attributes.depth)
+            m_multisampleDepthStencilBuffer = context->createRenderbuffer();
+    }
+    
+    reset(size);
 }
 
 DrawingBuffer::~DrawingBuffer()
@@ -60,24 +100,19 @@ DrawingBuffer::~DrawingBuffer()
     clear();
 }
 
-void DrawingBuffer::reset(const IntSize& newSize)
+void DrawingBuffer::didReset()
 {
-    if (!m_context)
-        return;
-        
-    if (m_size == newSize)
-        return;
-    m_size = newSize;
-
-    m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_size.width(), m_size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
 }
 
-#if USE(ACCELERATED_COMPOSITING)
 PlatformLayer* DrawingBuffer::platformLayer()
 {
     return m_platformLayer.get();
 }
-#endif
+
+Platform3DObject DrawingBuffer::platformColorBuffer() const
+{
+    return m_colorBuffer;
+}
 
 }
 
diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
index 8c62e9d..d9e081d 100644
--- a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
+++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -69,6 +69,14 @@ bool Extensions3DOpenGL::supports(const String& name)
             m_availableExtensions.add(availableExtensions[i]);
         m_initializedAvailableExtensions = true;
     }
+    
+    // GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample are "fake". They are implemented using other
+    // extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample
+    if (name == "GL_ANGLE_framebuffer_blit")
+        return m_availableExtensions.contains("GL_EXT_framebuffer_blit");
+    if (name == "GL_ANGLE_framebuffer_multisample")
+        return m_availableExtensions.contains("GL_EXT_framebuffer_multisample");
+        
     return m_availableExtensions.contains(name);
 }
 
@@ -77,6 +85,16 @@ int Extensions3DOpenGL::getGraphicsResetStatusARB()
     return GraphicsContext3D::NO_ERROR;
 }
 
+void Extensions3DOpenGL::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter)
+{
+    ::glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height)
+{
+    ::glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
index 1b333b2..0fbe022 100644
--- a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
+++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
@@ -41,6 +41,8 @@ public:
     // Extensions3D methods.
     virtual bool supports(const String&);
     virtual int getGraphicsResetStatusARB();
+    virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter);
+    virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height);    
 
 private:
     // This class only needs to be instantiated by GraphicsContext3D implementations.
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index f7cc5a6..0db96cf 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -111,7 +111,7 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
     if (m_data.m_platformContext.useGPU() && context->platformContext()->useGPU()) {
         if (context->platformContext()->canAccelerate()) {
             DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer();
-            unsigned sourceTexture = sourceDrawingBuffer->getRenderingResultsAsTexture();
+            unsigned sourceTexture = static_cast<unsigned>(sourceDrawingBuffer->platformColorBuffer());
             FloatRect destRectFlipped(destRect);
             destRectFlipped.setY(destRect.y() + destRect.height());
             destRectFlipped.setHeight(-destRect.height());

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list