[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:45:42 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit c28c4960dcdb04111714a1720a7d59be3c827588
Author: cmarrin at apple.com <cmarrin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Nov 11 22:43:11 2010 +0000
2010-11-11 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.
This re-lands changes rolled out by http://trac.webkit.org/changeset/71839. It includes
the change from http://trac.webkit.org/changeset/71831 and additional changes to
DrawingBufferChromium.cpp which cause the broken canvas tests to pass.
* platform/graphics/Extensions3D.h:
* platform/graphics/chromium/DrawingBufferChromium.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):
(WebCore::DrawingBuffer::~DrawingBuffer):
(WebCore::DrawingBuffer::publishToPlatformLayer):
(WebCore::DrawingBuffer::didReset):
(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::didReset):
(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@71853 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6c4633e..7630781 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,47 @@
+2010-11-11 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.
+
+ This re-lands changes rolled out by http://trac.webkit.org/changeset/71839. It includes
+ the change from http://trac.webkit.org/changeset/71831 and additional changes to
+ DrawingBufferChromium.cpp which cause the broken canvas tests to pass.
+
+ * platform/graphics/Extensions3D.h:
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::DrawingBuffer):
+ (WebCore::DrawingBuffer::~DrawingBuffer):
+ (WebCore::DrawingBuffer::publishToPlatformLayer):
+ (WebCore::DrawingBuffer::didReset):
+ (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::didReset):
+ (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 David Hyatt <hyatt at apple.com>
Reviewed by Simon Fraser.
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..0395bc2 100644
--- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -71,6 +71,11 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size)
: m_context(context)
, m_size(size)
, m_fbo(0)
+ , m_colorBuffer(0)
+ , m_depthStencilBuffer(0)
+ , m_multisampleFBO(0)
+ , m_multisampleColorBuffer(0)
+ , m_multisampleDepthStencilBuffer(0)
, m_internal(new DrawingBufferInternal)
{
if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) {
@@ -79,7 +84,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size)
}
m_fbo = context->createFramebuffer();
context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- m_internal->offscreenColorTexture = generateColorTexture(context, size);
+ m_colorBuffer = generateColorTexture(context, size);
}
DrawingBuffer::~DrawingBuffer()
@@ -93,7 +98,7 @@ DrawingBuffer::~DrawingBuffer()
return;
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- m_context->deleteTexture(m_internal->offscreenColorTexture);
+ m_context->deleteTexture(m_colorBuffer);
clear();
}
@@ -113,23 +118,13 @@ void DrawingBuffer::publishToPlatformLayer()
// happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this
// would insert a fence into the child command stream that the compositor could wait for.
m_context->makeContextCurrent();
- static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture);
+ static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_colorBuffer, parentTexture);
m_context->flush();
}
#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,9 +140,9 @@ PlatformLayer* DrawingBuffer::platformLayer()
}
#endif
-unsigned DrawingBuffer::getRenderingResultsAsTexture()
+Platform3DObject DrawingBuffer::platformColorBuffer() const
{
- return m_internal->offscreenColorTexture;
+ return m_colorBuffer;
}
}
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..d812e28 100644
--- a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -34,11 +34,14 @@
#include "DrawingBuffer.h"
+#include "Extensions3D.h"
+
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 +49,193 @@ 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 multisample FBO
+ if (multisample()) {
+ int maxSampleCount;
+
+ m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSampleCount);
+ int sampleCount = std::min(8, 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 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;
+ }
+
+ 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);
+
+ m_context->flush();
+
+ didReset();
+}
+
+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..9f79889 100644
--- a/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -64,13 +64,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 +93,22 @@ 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();
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/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..a6fa5d9 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)
+{
+ ::glRenderbufferStorageMultisampleEXT(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