[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
senorblanco at chromium.org
senorblanco at chromium.org
Sun Feb 20 23:25:55 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit 1b1b979f973e19cb0be3cf11d2ec4c476a112e4e
Author: senorblanco at chromium.org <senorblanco at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Jan 20 13:48:56 2011 +0000
2011-01-19 Stephen White <senorblanco at chromium.org>
[Re-land of r76159 with a compile fix for the Chromium linux shlib
build.]
Reviewed by James Robinson.
Implement accelerated path drawing and clipping for the Canvas2D GPU
path.
https://bugs.webkit.org/show_bug.cgi?id=52627
This is done with a simple curve interpolator and the GLU tesselator,
which is good enough for a 3-5X speedup on
http://ie.microsoft.com/testdrive/Performance/Galactic/Default.html.
Covered by canvas/philip/2d.path.clip.basic.html, and many, many more.
All tests canvas/philip and fast/canvas paths pass with no
regressions, although two have minor pixel differences which require
rebaselining.
* WebCore.gyp/WebCore.gyp:
Add internal_glu include path to chromium build.
* WebCore.gypi:
Add internal_glu files to chromium build.
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::reset):
(WebCore::CanvasRenderingContext2D::platformLayer):
Make CanvasRenderingContext2D more robust against failure to create
a DrawingBuffer.
* platform/graphics/chromium/DrawingBufferChromium.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):
As in DrawingBufferMac.cpp, call reset() from the constructor.
Also initialize size to (-1, -1), so reset() doesn't early-out.
Add initializers for depthBuffer and stencilBuffer, and remove
multisampleDepthStencilBuffer.
* platform/graphics/chromium/GLES2Canvas.cpp:
Remove some unused #includes.
(WebCore::GLES2Canvas::State::State):
Add clipping state, and implement save/restore via the copy constructor.
(WebCore::operator*):
(WebCore::Quadratic::Quadratic):
(WebCore::Quadratic::fromBezier):
(WebCore::Quadratic::evaluate):
Quadratic Bezier curve class.
(WebCore::Cubic::Cubic):
(WebCore::Cubic::fromBezier):
(WebCore::Cubic::evaluate):
Cubic Bezier curve class.
(WebCore::GLES2Canvas::clearRect):
Add clipping support to clearRect().
(WebCore::GLES2Canvas::fillPath):
Implement fillPath().
(WebCore::GLES2Canvas::fillRect):
Add clipping support to fillRect().
(WebCore::GLES2Canvas::clipPath):
Implement clipPath().
(WebCore::GLES2Canvas::clipOut):
Stub out clipOut() (not called by Canvas 2D).
(WebCore::GLES2Canvas::restore):
When restoring, draw any remaining clipping paths to the stencil buffer.
(WebCore::GLES2Canvas::drawTexturedRect):
Add clipping support.
(WebCore::interpolateQuadratic):
(WebCore::interpolateCubic):
Simple curve interpolation, using the Cubic and Quadratic classes.
(WebCore::PolygonData::PolygonData):
A struct to hold the tesselation data for callbacks.
(WebCore::beginData):
(WebCore::edgeFlagData):
(WebCore::vertexData):
(WebCore::endData):
(WebCore::combineData):
internal_glu tesselation callbacks.
(WebCore::GLES2Canvas::createVertexBufferFromPath):
Build an interpolated, tesselated vertex buffer and element array buffer from a given path, suitable for filling.
(WebCore::GLES2Canvas::beginStencilDraw):
Enable stencilling, and disable draws to the color buffer.
(WebCore::GLES2Canvas::applyClipping):
If clipping is enabled, set the appropriate GL state.
* platform/graphics/chromium/GLES2Canvas.h:
Document the flavours of drawTexturedRect() a bit, so I don't get confused.
* platform/graphics/gpu/DrawingBuffer.cpp:
(WebCore::DrawingBuffer::clear):
(WebCore::DrawingBuffer::createSecondaryBuffers):
(WebCore::DrawingBuffer::resizeDepthStencil):
(WebCore::DrawingBuffer::reset):
* platform/graphics/gpu/DrawingBuffer.h:
Unify m_multisampleDepthStencilBuffer with m_depthStencilBuffer.
Implement separate depth and stencil buffers for when
OES_packed_depth_stencil is not available. Refactor creation of
multisampled and non-multisampled depth and stencil buffers into
resizeDepthStencil().
* platform/graphics/gpu/SharedGraphicsContext3D.cpp:
(WebCore::SharedGraphicsContext3D::create):
Turn on stencil, turn off depth, turn off antialiasing (for now).
(WebCore::SharedGraphicsContext3D::enableStencil):
* platform/graphics/gpu/SharedGraphicsContext3D.h:
Implement stencil enable/disable.
* platform/graphics/gpu/mac/DrawingBufferMac.mm:
(WebCore::DrawingBuffer::DrawingBuffer):
Remove m_multisampleDepthStencilBuffer. Set the size to (-1, -1)
on creation, so reset() doesn't early-out. Initialize m_depthBuffer
and m_stencilBuffer.
* platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContext::canvasClip):
(WebCore::GraphicsContext::clipOut):
(WebCore::GraphicsContext::clipPath):
(WebCore::GraphicsContext::fillPath):
Put in GPU hooks for path clipping, and path drawing.
* platform/graphics/skia/PlatformContextSkia.cpp:
(WebCore::PlatformContextSkia::canAccelerate):
Don't check for clipping paths in canAccelerate() (since we can
now accelerate them).
(WebCore::PlatformContextSkia::uploadSoftwareToHardware):
Don't do clipping when uploading software draws to hardware.
* thirdparty/glu/README.webkit:
* thirdparty/glu/gluos.h:
#undef MIN and MAX, to fix warnings-as-errors in Chrome/Mac build.
* thirdparty/glu/libtess/geom.c:
* thirdparty/glu/libtess/priorityq.c:
* thirdparty/glu/libtess/render.c:
Use do{}while(0) instead of if(1)else construct in macro.
* thirdparty/glu/libtess/sweep.c:
(IsWindingInside):
(DoneEdgeDict):
Fix some warnings treated as errors for the Linux Release build.
2011-01-19 Stephen White <senorblanco at chromium.org>
Reviewed by James Robinson.
Add two to-be-rebaselined tests for the GPU path.
* platform/chromium-gpu/test_expectations.txt:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76235 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index a523b6f..eb9ab32 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,11 @@
+2011-01-19 Stephen White <senorblanco at chromium.org>
+
+ Reviewed by James Robinson.
+
+ Add two to-be-rebaselined tests for the GPU path.
+
+ * platform/chromium-gpu/test_expectations.txt:
+
2011-01-20 Pavel Feldman <pfeldman at chromium.org>
Not reviewed: rebaselined inspector tests.
diff --git a/LayoutTests/platform/chromium-gpu/test_expectations.txt b/LayoutTests/platform/chromium-gpu/test_expectations.txt
index e8d6a39..31c3d36 100644
--- a/LayoutTests/platform/chromium-gpu/test_expectations.txt
+++ b/LayoutTests/platform/chromium-gpu/test_expectations.txt
@@ -388,3 +388,7 @@ BUGWK51989 WIN LINUX : fast/canvas/canvas-fillRect-gradient-shadow.html = TEXT
// Started failing after r75648 on everything except Snow Leopard
BUGWK52341 : fast/canvas/canvas-large-dimensions.html = TEXT
+
+// These will need to rebaselined after the new path drawing lands.
+BUG_SENORBLANCO WIN LINUX : fast/canvas/canvas-composite.html = IMAGE
+BUG_SENORBLANCO WIN LINUX : fast/canvas/canvas-transform-skewed.html = IMAGE
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index c817ce5..b38ceb8 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,131 @@
+2011-01-19 Stephen White <senorblanco at chromium.org>
+
+ [Re-land of r76159 with a compile fix for the Chromium linux shlib
+ build.]
+
+ Reviewed by James Robinson.
+
+ Implement accelerated path drawing and clipping for the Canvas2D GPU
+ path.
+ https://bugs.webkit.org/show_bug.cgi?id=52627
+
+ This is done with a simple curve interpolator and the GLU tesselator,
+ which is good enough for a 3-5X speedup on
+ http://ie.microsoft.com/testdrive/Performance/Galactic/Default.html.
+
+ Covered by canvas/philip/2d.path.clip.basic.html, and many, many more.
+ All tests canvas/philip and fast/canvas paths pass with no
+ regressions, although two have minor pixel differences which require
+ rebaselining.
+
+ * WebCore.gyp/WebCore.gyp:
+ Add internal_glu include path to chromium build.
+ * WebCore.gypi:
+ Add internal_glu files to chromium build.
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::reset):
+ (WebCore::CanvasRenderingContext2D::platformLayer):
+ Make CanvasRenderingContext2D more robust against failure to create
+ a DrawingBuffer.
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::DrawingBuffer):
+ As in DrawingBufferMac.cpp, call reset() from the constructor.
+ Also initialize size to (-1, -1), so reset() doesn't early-out.
+ Add initializers for depthBuffer and stencilBuffer, and remove
+ multisampleDepthStencilBuffer.
+ * platform/graphics/chromium/GLES2Canvas.cpp:
+ Remove some unused #includes.
+ (WebCore::GLES2Canvas::State::State):
+ Add clipping state, and implement save/restore via the copy constructor.
+ (WebCore::operator*):
+ (WebCore::Quadratic::Quadratic):
+ (WebCore::Quadratic::fromBezier):
+ (WebCore::Quadratic::evaluate):
+ Quadratic Bezier curve class.
+ (WebCore::Cubic::Cubic):
+ (WebCore::Cubic::fromBezier):
+ (WebCore::Cubic::evaluate):
+ Cubic Bezier curve class.
+ (WebCore::GLES2Canvas::clearRect):
+ Add clipping support to clearRect().
+ (WebCore::GLES2Canvas::fillPath):
+ Implement fillPath().
+ (WebCore::GLES2Canvas::fillRect):
+ Add clipping support to fillRect().
+ (WebCore::GLES2Canvas::clipPath):
+ Implement clipPath().
+ (WebCore::GLES2Canvas::clipOut):
+ Stub out clipOut() (not called by Canvas 2D).
+ (WebCore::GLES2Canvas::restore):
+ When restoring, draw any remaining clipping paths to the stencil buffer.
+ (WebCore::GLES2Canvas::drawTexturedRect):
+ Add clipping support.
+ (WebCore::interpolateQuadratic):
+ (WebCore::interpolateCubic):
+ Simple curve interpolation, using the Cubic and Quadratic classes.
+ (WebCore::PolygonData::PolygonData):
+ A struct to hold the tesselation data for callbacks.
+ (WebCore::beginData):
+ (WebCore::edgeFlagData):
+ (WebCore::vertexData):
+ (WebCore::endData):
+ (WebCore::combineData):
+ internal_glu tesselation callbacks.
+ (WebCore::GLES2Canvas::createVertexBufferFromPath):
+ Build an interpolated, tesselated vertex buffer and element array buffer from a given path, suitable for filling.
+ (WebCore::GLES2Canvas::beginStencilDraw):
+ Enable stencilling, and disable draws to the color buffer.
+ (WebCore::GLES2Canvas::applyClipping):
+ If clipping is enabled, set the appropriate GL state.
+ * platform/graphics/chromium/GLES2Canvas.h:
+ Document the flavours of drawTexturedRect() a bit, so I don't get confused.
+ * platform/graphics/gpu/DrawingBuffer.cpp:
+ (WebCore::DrawingBuffer::clear):
+ (WebCore::DrawingBuffer::createSecondaryBuffers):
+ (WebCore::DrawingBuffer::resizeDepthStencil):
+ (WebCore::DrawingBuffer::reset):
+ * platform/graphics/gpu/DrawingBuffer.h:
+ Unify m_multisampleDepthStencilBuffer with m_depthStencilBuffer.
+ Implement separate depth and stencil buffers for when
+ OES_packed_depth_stencil is not available. Refactor creation of
+ multisampled and non-multisampled depth and stencil buffers into
+ resizeDepthStencil().
+ * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
+ (WebCore::SharedGraphicsContext3D::create):
+ Turn on stencil, turn off depth, turn off antialiasing (for now).
+ (WebCore::SharedGraphicsContext3D::enableStencil):
+ * platform/graphics/gpu/SharedGraphicsContext3D.h:
+ Implement stencil enable/disable.
+ * platform/graphics/gpu/mac/DrawingBufferMac.mm:
+ (WebCore::DrawingBuffer::DrawingBuffer):
+ Remove m_multisampleDepthStencilBuffer. Set the size to (-1, -1)
+ on creation, so reset() doesn't early-out. Initialize m_depthBuffer
+ and m_stencilBuffer.
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::canvasClip):
+ (WebCore::GraphicsContext::clipOut):
+ (WebCore::GraphicsContext::clipPath):
+ (WebCore::GraphicsContext::fillPath):
+ Put in GPU hooks for path clipping, and path drawing.
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::canAccelerate):
+ Don't check for clipping paths in canAccelerate() (since we can
+ now accelerate them).
+ (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
+ Don't do clipping when uploading software draws to hardware.
+ * thirdparty/glu/README.webkit:
+ * thirdparty/glu/gluos.h:
+ #undef MIN and MAX, to fix warnings-as-errors in Chrome/Mac build.
+ * thirdparty/glu/libtess/geom.c:
+ * thirdparty/glu/libtess/priorityq.c:
+ * thirdparty/glu/libtess/render.c:
+ Use do{}while(0) instead of if(1)else construct in macro.
+ * thirdparty/glu/libtess/sweep.c:
+ (IsWindingInside):
+ (DoneEdgeDict):
+ Fix some warnings treated as errors for the Linux Release build.
+
+
2011-01-20 Pavel Feldman <pfeldman at chromium.org>
Web Inspector: move releaseObjectGroup to the new Runtime agent.
diff --git a/Source/WebCore/WebCore.gyp/WebCore.gyp b/Source/WebCore/WebCore.gyp/WebCore.gyp
index 34066f7..738960d 100644
--- a/Source/WebCore/WebCore.gyp/WebCore.gyp
+++ b/Source/WebCore/WebCore.gyp/WebCore.gyp
@@ -185,6 +185,7 @@
'../svg/graphics',
'../svg/graphics/filters',
'../svg/properties',
+ '../thirdparty/glu',
'../webaudio',
'../websockets',
'../workers',
@@ -1117,6 +1118,8 @@
# Use LinkHashChromium.cpp instead
['exclude', 'platform/LinkHash\\.cpp$'],
+
+ ['include', 'thirdparty/glu/libtess/'],
],
'conditions': [
['OS=="linux" or OS=="freebsd"', {
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index 2b275ed..7fb3fbd 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -4439,6 +4439,29 @@
'svg/SVGZoomAndPan.h',
'svg/SVGZoomEvent.cpp',
'svg/SVGZoomEvent.h',
+ 'thirdparty/glu/libtess/dict.h',
+ 'thirdparty/glu/libtess/dict-list.h',
+ 'thirdparty/glu/libtess/geom.h',
+ 'thirdparty/glu/libtess/memalloc.h',
+ 'thirdparty/glu/libtess/mesh.h',
+ 'thirdparty/glu/libtess/normal.h',
+ 'thirdparty/glu/libtess/priorityq-heap.h',
+ 'thirdparty/glu/libtess/priorityq-sort.h',
+ 'thirdparty/glu/libtess/priorityq.h',
+ 'thirdparty/glu/libtess/render.h',
+ 'thirdparty/glu/libtess/sweep.h',
+ 'thirdparty/glu/libtess/tess.h',
+ 'thirdparty/glu/libtess/tessmono.h',
+ 'thirdparty/glu/libtess/dict.c',
+ 'thirdparty/glu/libtess/geom.c',
+ 'thirdparty/glu/libtess/memalloc.c',
+ 'thirdparty/glu/libtess/mesh.c',
+ 'thirdparty/glu/libtess/normal.c',
+ 'thirdparty/glu/libtess/priorityq.c',
+ 'thirdparty/glu/libtess/render.c',
+ 'thirdparty/glu/libtess/sweep.c',
+ 'thirdparty/glu/libtess/tess.c',
+ 'thirdparty/glu/libtess/tessmono.c',
'webaudio/AudioBasicProcessorNode.cpp',
'webaudio/AudioBasicProcessorNode.h',
'webaudio/AudioBuffer.h',
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index d9acb77..e029128 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -171,7 +171,7 @@ void CanvasRenderingContext2D::reset()
m_path.clear();
#if ENABLE(ACCELERATED_2D_CANVAS)
if (GraphicsContext* c = drawingContext()) {
- if (m_context3D) {
+ if (m_context3D && m_drawingBuffer) {
m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
}
@@ -1896,7 +1896,7 @@ void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
PlatformLayer* CanvasRenderingContext2D::platformLayer() const
{
- return m_drawingBuffer->platformLayer();
+ return m_drawingBuffer ? m_drawingBuffer->platformLayer() : 0;
}
#endif
diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index 569dff4..2d4ca41 100644
--- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -72,15 +72,16 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported)
: m_context(context)
- , m_size(size)
+ , m_size(-1, -1)
, m_multisampleExtensionSupported(multisampleExtensionSupported)
, m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported)
, m_fbo(0)
, m_colorBuffer(0)
, m_depthStencilBuffer(0)
+ , m_depthBuffer(0)
+ , m_stencilBuffer(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")) {
@@ -91,6 +92,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
m_colorBuffer = generateColorTexture(context, size);
createSecondaryBuffers();
+ reset(size);
}
DrawingBuffer::~DrawingBuffer()
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index ae017de..4393f97 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -34,12 +34,16 @@
#include "DrawingBuffer.h"
#include "FloatRect.h"
+#include "FloatSize.h"
#include "GraphicsContext3D.h"
+#include "internal_glu.h"
#include "IntRect.h"
+#include "Path.h"
#include "PlatformString.h"
#include "SharedGraphicsContext3D.h"
-#include "SolidFillShader.h"
-#include "TexShader.h"
+#if PLATFORM(SKIA)
+#include "SkPath.h"
+#endif
#include "Texture.h"
#define _USE_MATH_DEFINES
@@ -50,17 +54,99 @@
namespace WebCore {
+// Number of line segments used to approximate bezier curves.
+const int pathTesselation = 30;
+typedef void (GLAPIENTRY *TESSCB)();
+typedef WTF::Vector<float> FloatVector;
+typedef WTF::Vector<double> DoubleVector;
+
struct GLES2Canvas::State {
State()
: m_fillColor(0, 0, 0, 255)
, m_alpha(1.0f)
, m_compositeOp(CompositeSourceOver)
+ , m_clippingEnabled(false)
+ {
+ }
+ State(const State& other)
+ : m_fillColor(other.m_fillColor)
+ , m_alpha(other.m_alpha)
+ , m_compositeOp(other.m_compositeOp)
+ , m_ctm(other.m_ctm)
+ , m_clippingPaths() // Don't copy; clipping paths are tracked per-state.
+ , m_clippingEnabled(other.m_clippingEnabled)
{
}
Color m_fillColor;
float m_alpha;
CompositeOperator m_compositeOp;
AffineTransform m_ctm;
+ WTF::Vector<Path> m_clippingPaths;
+ bool m_clippingEnabled;
+};
+
+static inline FloatPoint operator*(const FloatPoint& f, float scale)
+{
+ return FloatPoint(f.x() * scale, f.y() * scale);
+}
+
+static inline FloatPoint operator*(float scale, const FloatPoint& f)
+{
+ return FloatPoint(f.x() * scale, f.y() * scale);
+}
+
+static inline FloatSize operator*(const FloatSize& f, float scale)
+{
+ return FloatSize(f.width() * scale, f.height() * scale);
+}
+
+static inline FloatSize operator*(float scale, const FloatSize& f)
+{
+ return FloatSize(f.width() * scale, f.height() * scale);
+}
+
+class Quadratic {
+ public:
+ Quadratic(FloatPoint a, FloatPoint b, FloatPoint c) :
+ m_a(a), m_b(b), m_c(c)
+ {
+ }
+ static Quadratic fromBezier(FloatPoint p0, FloatPoint p1, FloatPoint p2)
+ {
+ FloatSize p1s(p1.x(), p1.y());
+ FloatSize p2s(p2.x(), p2.y());
+ FloatPoint b = -2.0f * p0 + 2.0f * p1s;
+ FloatPoint c = p0 - 2.0f * p1s + p2s;
+ return Quadratic(p0, b, c);
+ }
+ inline FloatPoint evaluate(float t)
+ {
+ return m_a + t * (m_b + t * m_c);
+ }
+ FloatPoint m_a, m_b, m_c, m_d;
+};
+
+class Cubic {
+ public:
+ Cubic(FloatPoint a, FloatPoint b, FloatPoint c, FloatPoint d) :
+ m_a(a), m_b(b), m_c(c), m_d(d)
+ {
+ }
+ static Cubic fromBezier(FloatPoint p0, FloatPoint p1, FloatPoint p2, FloatPoint p3)
+ {
+ FloatSize p1s(p1.x(), p1.y());
+ FloatSize p2s(p2.x(), p2.y());
+ FloatSize p3s(p3.x(), p3.y());
+ FloatPoint b = -3.0f * p0 + 3.0f * p1s;
+ FloatPoint c = 3.0f * p0 - 6.0f * p1s + 3.0f * p2s;
+ FloatPoint d = -1.0f * p0 + 3.0f * p1s - 3.0f * p2s + p3s;
+ return Cubic(p0, b, c, d);
+ }
+ FloatPoint evaluate(float t)
+ {
+ return m_a + t * (m_b + t * (m_c + t * m_d));
+ }
+ FloatPoint m_a, m_b, m_c, m_d;
};
GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawingBuffer, const IntSize& size)
@@ -88,7 +174,7 @@ void GLES2Canvas::bindFramebuffer()
void GLES2Canvas::clearRect(const FloatRect& rect)
{
bindFramebuffer();
- if (m_state->m_ctm.isIdentity()) {
+ if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) {
m_context->scissor(rect);
m_context->enable(GraphicsContext3D::SCISSOR_TEST);
m_context->clearColor(Color(RGBA32(0)));
@@ -102,9 +188,17 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
}
}
+void GLES2Canvas::fillPath(const Path& path)
+{
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->m_clippingEnabled);
+ fillPath(path, m_state->m_fillColor);
+}
+
void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->m_clippingEnabled);
m_context->useQuadVertices();
AffineTransform matrix(m_flipMatrix);
@@ -153,6 +247,23 @@ void GLES2Canvas::concatCTM(const AffineTransform& affine)
m_state->m_ctm *= affine;
}
+void GLES2Canvas::clipPath(const Path& path)
+{
+ bindFramebuffer();
+ checkGLError("bindFramebuffer");
+ beginStencilDraw();
+ // Red is used so we can see it if it ends up in the color buffer.
+ Color red(255, 0, 0, 255);
+ fillPath(path, red);
+ m_state->m_clippingPaths.append(path);
+ m_state->m_clippingEnabled = true;
+}
+
+void GLES2Canvas::clipOut(const Path& path)
+{
+ ASSERT(!"clipOut is unsupported in GLES2Canvas.\n");
+}
+
void GLES2Canvas::save()
{
m_stateStack.append(State(m_stateStack.last()));
@@ -162,13 +273,30 @@ void GLES2Canvas::save()
void GLES2Canvas::restore()
{
ASSERT(!m_stateStack.isEmpty());
+ bool hadClippingPaths = !m_state->m_clippingPaths.isEmpty();
m_stateStack.removeLast();
m_state = &m_stateStack.last();
+ if (hadClippingPaths) {
+ m_context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
+ beginStencilDraw();
+ StateVector::const_iterator iter;
+ for (iter = m_stateStack.begin(); iter < m_stateStack.end(); ++iter) {
+ const State& state = *iter;
+ const Vector<Path>& clippingPaths = state.m_clippingPaths;
+ Vector<Path>::const_iterator pathIter;
+ for (pathIter = clippingPaths.begin(); pathIter < clippingPaths.end(); ++pathIter) {
+ // Red is used so we can see it if it ends up in the color buffer.
+ Color red(255, 0, 0, 255);
+ fillPath(*pathIter, red);
+ }
+ }
+ }
}
void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
m_context->applyCompositeOperator(compositeOp);
+ applyClipping(false);
m_context->useQuadVertices();
m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
@@ -180,13 +308,14 @@ void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize& textureSize,
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
- drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp);
+ drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp, m_state->m_clippingEnabled);
}
-void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp)
+void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp, bool clip)
{
m_context->applyCompositeOperator(compositeOp);
+ applyClipping(clip);
const TilingData& tiles = texture->tiles();
IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
@@ -251,6 +380,214 @@ Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
return m_context->getTexture(ptr);
}
+#if PLATFORM(SKIA)
+// This is actually cross-platform code, but since its only caller is inside a
+// PLATFORM(SKIA), it will cause a warning-as-error on Chrome/Mac.
+static void interpolateQuadratic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
+{
+ float tIncrement = 1.0f / pathTesselation, t = tIncrement;
+ Quadratic c = Quadratic::fromBezier(p0, p1, p2);
+ for (int i = 0; i < pathTesselation; ++i, t += tIncrement) {
+ FloatPoint p = c.evaluate(t);
+ vertices->append(p.x());
+ vertices->append(p.y());
+ vertices->append(1.0);
+ }
+}
+
+static void interpolateCubic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3)
+{
+ float tIncrement = 1.0f / pathTesselation, t = tIncrement;
+ Cubic c = Cubic::fromBezier(p0, p1, p2, p3);
+ for (int i = 0; i < pathTesselation; ++i, t += tIncrement) {
+ FloatPoint p = c.evaluate(t);
+ vertices->append(p.x());
+ vertices->append(p.y());
+ vertices->append(1.0);
+ }
+}
+#endif
+
+struct PolygonData {
+ PolygonData(FloatVector* vertices, WTF::Vector<short>* indices)
+ : m_vertices(vertices)
+ , m_indices(indices)
+ {
+ }
+ FloatVector* m_vertices;
+ WTF::Vector<short>* m_indices;
+};
+
+static void beginData(GLenum type, void* data)
+{
+ ASSERT(type == GL_TRIANGLES);
+}
+
+static void edgeFlagData(GLboolean flag, void* data)
+{
+}
+
+static void vertexData(void* vertexData, void* data)
+{
+ static_cast<PolygonData*>(data)->m_indices->append(reinterpret_cast<long>(vertexData));
+}
+
+static void endData(void* data)
+{
+}
+
+static void combineData(GLdouble coords[3], void* vertexData[4],
+ GLfloat weight[4], void **outData, void* data)
+{
+ PolygonData* polygonData = static_cast<PolygonData*>(data);
+ int index = polygonData->m_vertices->size() / 3;
+ polygonData->m_vertices->append(static_cast<float>(coords[0]));
+ polygonData->m_vertices->append(static_cast<float>(coords[1]));
+ polygonData->m_vertices->append(1.0f);
+ *outData = reinterpret_cast<void*>(index);
+}
+
+typedef void (*TESSCB)();
+
+void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsigned* vertexBuffer, unsigned* indexBuffer)
+{
+ *vertexBuffer = m_context->graphicsContext3D()->createBuffer();
+ checkGLError("createVertexBufferFromPath, createBuffer");
+ *indexBuffer = m_context->graphicsContext3D()->createBuffer();
+ checkGLError("createVertexBufferFromPath, createBuffer");
+ DoubleVector inVertices;
+ WTF::Vector<size_t> contours;
+#if PLATFORM(SKIA)
+ const SkPath* skPath = path.platformPath();
+ SkPoint pts[4];
+ SkPath::Iter iter(*skPath, true);
+ SkPath::Verb verb;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ inVertices.append(pts[0].fX);
+ inVertices.append(pts[0].fY);
+ inVertices.append(1.0);
+ break;
+ case SkPath::kLine_Verb:
+ inVertices.append(pts[1].fX);
+ inVertices.append(pts[1].fY);
+ inVertices.append(1.0);
+ break;
+ case SkPath::kQuad_Verb:
+ interpolateQuadratic(&inVertices, pts[0], pts[1], pts[2]);
+ break;
+ case SkPath::kCubic_Verb:
+ interpolateCubic(&inVertices, pts[0], pts[1], pts[2], pts[3]);
+ break;
+ case SkPath::kClose_Verb:
+ contours.append(inVertices.size() / 3);
+ break;
+ case SkPath::kDone_Verb:
+ break;
+ }
+ }
+#else
+ ASSERT(!"Path extraction not implemented on this platform.");
+#endif
+
+ GLUtesselator* tess = internal_gluNewTess();
+ internal_gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
+ internal_gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (TESSCB) &beginData);
+ internal_gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (TESSCB) &vertexData);
+ internal_gluTessCallback(tess, GLU_TESS_END_DATA, (TESSCB) &endData);
+ internal_gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, (TESSCB) &edgeFlagData);
+ internal_gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineData);
+ WTF::Vector<short> indices;
+ FloatVector vertices;
+ vertices.reserveInitialCapacity(inVertices.size());
+ PolygonData data(&vertices, &indices);
+ internal_gluTessBeginPolygon(tess, &data);
+ WTF::Vector<size_t>::const_iterator contour;
+ size_t i = 0;
+ for (contour = contours.begin(); contour != contours.end(); ++contour) {
+ internal_gluTessBeginContour(tess);
+ for (; i < *contour; ++i) {
+ vertices.append(inVertices[i * 3]);
+ vertices.append(inVertices[i * 3 + 1]);
+ vertices.append(1.0f);
+ internal_gluTessVertex(tess, &inVertices[i * 3], reinterpret_cast<void*>(i));
+ }
+ internal_gluTessEndContour(tess);
+ }
+ internal_gluTessEndPolygon(tess);
+ internal_gluDeleteTess(tess);
+
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, *vertexBuffer);
+ checkGLError("createVertexBufferFromPath, bindBuffer ARRAY_BUFFER");
+ m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GraphicsContext3D::STREAM_DRAW);
+ checkGLError("createVertexBufferFromPath, bufferData ARRAY_BUFFER");
+
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, *indexBuffer);
+ checkGLError("createVertexBufferFromPath, bindBuffer ELEMENT_ARRAY_BUFFER");
+ m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(short), indices.data(), GraphicsContext3D::STREAM_DRAW);
+ checkGLError("createVertexBufferFromPath, bufferData ELEMENT_ARRAY_BUFFER");
+ *count = indices.size();
+}
+
+void GLES2Canvas::fillPath(const Path& path, const Color& color)
+{
+ int count;
+ unsigned vertexBuffer, indexBuffer;
+ createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
+ checkGLError("bindBuffer");
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
+ checkGLError("bindBuffer");
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
+
+ m_context->useFillSolidProgram(matrix, color);
+ checkGLError("useFillSolidProgram");
+
+ m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
+ checkGLError("drawArrays");
+
+ m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
+ checkGLError("deleteBuffer");
+
+ m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
+ checkGLError("deleteBuffer");
+}
+
+void GLES2Canvas::beginStencilDraw()
+{
+ // Turn on stencil test.
+ m_context->enableStencil(true);
+ checkGLError("enable STENCIL_TEST");
+
+ // Stencil test never passes, so colorbuffer is not drawn.
+ m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::NEVER, 1, 1);
+ checkGLError("stencilFunc");
+
+ // All writes incremement the stencil buffer.
+ m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::INCR,
+ GraphicsContext3D::INCR,
+ GraphicsContext3D::INCR);
+ checkGLError("stencilOp");
+}
+
+void GLES2Canvas::applyClipping(bool enable)
+{
+ m_context->enableStencil(enable);
+ if (enable) {
+ // Enable drawing only where stencil is non-zero.
+ m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::EQUAL, m_state->m_clippingPaths.size() % 256, 1);
+ checkGLError("stencilFunc");
+ // Keep all stencil values the same.
+ m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::KEEP,
+ GraphicsContext3D::KEEP,
+ GraphicsContext3D::KEEP);
+ checkGLError("stencilOp");
+ }
+}
+
void GLES2Canvas::checkGLError(const char* header)
{
#ifndef NDEBUG
@@ -283,4 +620,3 @@ void GLES2Canvas::checkGLError(const char* header)
}
}
-
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 6fc1a0e..f38c364 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -48,6 +48,7 @@ class Color;
class DrawingBuffer;
class FloatRect;
class GraphicsContext3D;
+class Path;
class SharedGraphicsContext3D;
class GLES2Canvas : public Noncopyable {
@@ -55,6 +56,7 @@ public:
GLES2Canvas(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
~GLES2Canvas();
+ void fillPath(const Path&);
void fillRect(const FloatRect&, const Color&, ColorSpace);
void fillRect(const FloatRect&);
void clearRect(const FloatRect&);
@@ -65,6 +67,8 @@ public:
void rotate(float angleInRadians);
void scale(const FloatSize&);
void concatCTM(const AffineTransform&);
+ void clipPath(const Path&);
+ void clipOut(const Path&);
void save();
void restore();
@@ -72,9 +76,13 @@ public:
// non-standard functions
// These are not standard GraphicsContext functions, and should be pushed
// down into a PlatformContextGLES2 at some point.
+
+ // This version is called by the canvas->canvas draws.
void drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
- void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator);
+ // This version is called by BitmapImage::draw().
void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
+ // This version is called by the above, and by the software->hardware uploads.
+ void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator, bool clip);
Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height);
Texture* getTexture(NativeImagePtr);
@@ -88,6 +96,10 @@ private:
void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void applyCompositeOperator(CompositeOperator);
+ void createVertexBufferFromPath(const Path&, int* count, unsigned* vertexBuffer, unsigned* indexBuffer);
+ void fillPath(const Path&, const Color&);
+ void beginStencilDraw();
+ void applyClipping(bool enable);
void checkGLError(const char* header);
IntSize m_size;
@@ -96,7 +108,8 @@ private:
DrawingBuffer* m_drawingBuffer;
struct State;
- WTF::Vector<State> m_stateStack;
+ typedef WTF::Vector<State> StateVector;
+ StateVector m_stateStack;
State* m_state;
AffineTransform m_flipMatrix;
};
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index c283068..dae83a2 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -67,16 +67,21 @@ void DrawingBuffer::clear()
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_depthBuffer) {
+ m_context->deleteRenderbuffer(m_depthBuffer);
+ m_depthBuffer = 0;
+ }
+
+ if (m_stencilBuffer) {
+ m_context->deleteRenderbuffer(m_stencilBuffer);
+ m_stencilBuffer = 0;
+ }
+
if (m_multisampleFBO) {
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
m_context->deleteFramebuffer(m_multisampleFBO);
@@ -92,22 +97,52 @@ void DrawingBuffer::clear()
void DrawingBuffer::createSecondaryBuffers()
{
- const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
-
- // Create the stencil and depth buffer if needed
- if (!multisample() && (attributes.stencil || attributes.depth))
- m_depthStencilBuffer = m_context->createRenderbuffer();
-
// create a multisample FBO
if (multisample()) {
m_multisampleFBO = m_context->createFramebuffer();
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
m_multisampleColorBuffer = m_context->createRenderbuffer();
- if (attributes.stencil || attributes.depth)
- m_multisampleDepthStencilBuffer = m_context->createRenderbuffer();
}
}
+void DrawingBuffer::resizeDepthStencil(int sampleCount)
+{
+ const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
+ if (attributes.depth && attributes.stencil && m_packedDepthStencilExtensionSupported) {
+ if (!m_depthStencilBuffer)
+ m_depthStencilBuffer = m_context->createRenderbuffer();
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+ if (multisample())
+ m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, Extensions3D::DEPTH24_STENCIL8, m_size.width(), m_size.height());
+ else
+ m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, Extensions3D::DEPTH24_STENCIL8, m_size.width(), m_size.height());
+ m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+ m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer);
+ } else {
+ if (attributes.depth) {
+ if (!m_depthBuffer)
+ m_depthBuffer = m_context->createRenderbuffer();
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+ if (multisample())
+ m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::DEPTH_COMPONENT16, m_size.width(), m_size.height());
+ else
+ m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, m_size.width(), m_size.height());
+ m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+ }
+ if (attributes.stencil) {
+ if (!m_stencilBuffer)
+ m_stencilBuffer = m_context->createRenderbuffer();
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_stencilBuffer);
+ if (multisample())
+ m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::STENCIL_INDEX8, m_size.width(), m_size.height());
+ else
+ m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, m_size.width(), m_size.height());
+ m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_stencilBuffer);
+ }
+ }
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+}
+
void DrawingBuffer::reset(const IntSize& newSize)
{
if (m_size == newSize)
@@ -120,7 +155,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
m_context->makeContextCurrent();
const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
- unsigned long internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
+ unsigned long internalColorFormat, colorFormat;
if (attributes.alpha) {
internalColorFormat = GraphicsContext3D::RGBA;
colorFormat = GraphicsContext3D::RGBA;
@@ -128,17 +163,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
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.
- // FIXME: If packed depth/stencil is not supported, we should
- // create separate renderbuffers for depth and stencil.
- if (attributes.stencil && attributes.depth && m_packedDepthStencilExtensionSupported)
- internalDepthStencilFormat = Extensions3D::DEPTH24_STENCIL8;
- else
- internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT16;
- }
// resize multisample FBO
if (multisample()) {
@@ -152,15 +177,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
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);
+ resizeDepthStencil(sampleCount);
if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
// Cleanup
clear();
@@ -175,15 +192,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE);
m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 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);
- }
+ resizeDepthStencil(0);
if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
// Cleanup
clear();
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
index e0e0ee1..9da5c9a 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -67,6 +67,8 @@ public:
// Create the depth/stencil and multisample buffers, if needed.
void createSecondaryBuffers();
+ void resizeDepthStencil(int sampleCount);
+
// 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);
@@ -106,13 +108,18 @@ private:
bool m_packedDepthStencilExtensionSupported;
Platform3DObject m_fbo;
Platform3DObject m_colorBuffer;
+
+ // This is used when we have OES_packed_depth_stencil.
Platform3DObject m_depthStencilBuffer;
+ // These are used when we don't.
+ Platform3DObject m_depthBuffer;
+ Platform3DObject m_stencilBuffer;
+
// 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/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index 9d1298f..9c59077 100644
--- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -51,6 +51,9 @@ namespace WebCore {
PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* hostWindow)
{
GraphicsContext3D::Attributes attr;
+ attr.depth = false;
+ attr.stencil = true;
+ attr.antialias = false;
attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
if (!context)
@@ -293,6 +296,14 @@ void SharedGraphicsContext3D::applyCompositeOperator(CompositeOperator op)
}
}
+void SharedGraphicsContext3D::enableStencil(bool enable)
+{
+ if (enable)
+ m_context->enable(GraphicsContext3D::STENCIL_TEST);
+ else
+ m_context->disable(GraphicsContext3D::STENCIL_TEST);
+}
+
void SharedGraphicsContext3D::useQuadVertices()
{
if (!m_quadVertices) {
diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
index ea1810d..1e032d7 100644
--- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
@@ -90,6 +90,7 @@ public:
// Shared logic for canvas 2d
void applyCompositeOperator(CompositeOperator);
+ void enableStencil(bool enable);
void useQuadVertices();
void useFillSolidProgram(const AffineTransform&, const Color&);
diff --git a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
index 601454e..e6dfdb8 100644
--- a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
+++ b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
@@ -41,15 +41,16 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported)
: m_context(context)
- , m_size(size)
+ , m_size(-1, -1)
, m_multisampleExtensionSupported(multisampleExtensionSupported)
, m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported)
, m_fbo(context->createFramebuffer())
, m_colorBuffer(0)
, m_depthStencilBuffer(0)
+ , m_depthBuffer(0)
+ , m_stencilBuffer(0)
, m_multisampleFBO(0)
, m_multisampleColorBuffer(0)
- , m_multisampleDepthStencilBuffer(0)
{
ASSERT(m_fbo);
if (!m_fbo) {
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 51e2477..1a7112b 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -386,6 +386,9 @@ void GraphicsContext::canvasClip(const Path& path)
if (paintingDisabled())
return;
+ if (platformContext()->useGPU())
+ platformContext()->gpuCanvas()->clipPath(path);
+
const SkPath& p = *path.platformPath();
if (!isPathSkiaSafe(getCTM(), p))
return;
@@ -410,6 +413,9 @@ void GraphicsContext::clipOut(const Path& p)
if (paintingDisabled())
return;
+ if (platformContext()->useGPU())
+ platformContext()->gpuCanvas()->clipOut(p);
+
const SkPath& path = *p.platformPath();
if (!isPathSkiaSafe(getCTM(), path))
return;
@@ -422,6 +428,9 @@ void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
if (paintingDisabled())
return;
+ if (platformContext()->useGPU())
+ platformContext()->gpuCanvas()->clipPath(pathToClip);
+
// FIXME: Be smarter about this.
beginPath();
addPath(pathToClip);
@@ -733,6 +742,12 @@ void GraphicsContext::fillPath(const Path& pathToFill)
beginPath();
addPath(pathToFill);
+ if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
+ platformContext()->prepareForHardwareDraw();
+ platformContext()->gpuCanvas()->fillPath(pathToFill);
+ return;
+ }
+
SkPath path = platformContext()->currentPathInLocalCoordinates();
if (!isPathSkiaSafe(getCTM(), path))
return;
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index d3c0e00..d852e9b 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -702,8 +702,7 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
bool PlatformContextSkia::canAccelerate() const
{
return !m_state->m_fillShader // Can't accelerate with a fill gradient or pattern.
- && !m_state->m_looper // Can't accelerate with a shadow.
- && !m_state->m_canvasClipApplied; // Can't accelerate with a clip to path applied.
+ && !m_state->m_looper; // Can't accelerate with a shadow.
}
bool PlatformContextSkia::canvasClipApplied() const
@@ -848,7 +847,7 @@ void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
m_uploadTexture->updateSubRect(bitmap.getPixels(), m_softwareDirtyRect);
AffineTransform identity;
- gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, ColorSpaceDeviceRGB, op);
+ gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, ColorSpaceDeviceRGB, op, false);
// Clear out the region of the software canvas we just uploaded.
m_canvas->save();
m_canvas->resetMatrix();
diff --git a/Source/WebCore/thirdparty/glu/README.webkit b/Source/WebCore/thirdparty/glu/README.webkit
index 3fcac84..57c4772 100644
--- a/Source/WebCore/thirdparty/glu/README.webkit
+++ b/Source/WebCore/thirdparty/glu/README.webkit
@@ -31,3 +31,12 @@ The following changes were made in order to incorporate this code:
of the unused Normalize function.
- In priorityq-heap.c, an #include of <limits.h> was added.
+
+ - In sweep.c, IsWindingInside() was given a return value to silence a
+ warning-as-error in release builds.
+
+ - In sweep.c, DoneEdgeDict()'s fixedEdges was wrapped in #indef NDEBUG, to
+ silence a warning-as-error in release builds.
+
+ - In priorityq.c, render.c, and others: the construct "if(1)...else" was
+ replaced with "do{...}while(1)" to silence a warning-as-error in Mac builds.
diff --git a/Source/WebCore/thirdparty/glu/gluos.h b/Source/WebCore/thirdparty/glu/gluos.h
index 600dc0b..6380cb2 100644
--- a/Source/WebCore/thirdparty/glu/gluos.h
+++ b/Source/WebCore/thirdparty/glu/gluos.h
@@ -42,4 +42,7 @@ typedef unsigned int GLenum;
typedef float GLfloat;
typedef void GLvoid;
+#undef MIN
+#undef MAX
+
#endif // GLUOS_H_
diff --git a/Source/WebCore/thirdparty/glu/libtess/geom.c b/Source/WebCore/thirdparty/glu/libtess/geom.c
index 2db2699..ce578dd 100644
--- a/Source/WebCore/thirdparty/glu/libtess/geom.c
+++ b/Source/WebCore/thirdparty/glu/libtess/geom.c
@@ -205,7 +205,7 @@ printf("*********************%d\n",RandomInterpolate);
#endif
-#define Swap(a,b) if (1) { GLUvertex *t = a; a = b; b = t; } else
+#define Swap(a,b) do { GLUvertex *t = a; a = b; b = t; } while(0)
void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
GLUvertex *o2, GLUvertex *d2,
diff --git a/Source/WebCore/thirdparty/glu/libtess/priorityq.c b/Source/WebCore/thirdparty/glu/libtess/priorityq.c
index 4b0bea1..6614db0 100644
--- a/Source/WebCore/thirdparty/glu/libtess/priorityq.c
+++ b/Source/WebCore/thirdparty/glu/libtess/priorityq.c
@@ -92,7 +92,7 @@ void pqDeletePriorityQ( PriorityQ *pq )
#define LT(x,y) (! LEQ(y,x))
#define GT(x,y) (! LEQ(x,y))
-#define Swap(a,b) if(1){PQkey *tmp = *a; *a = *b; *b = tmp;}else
+#define Swap(a,b) do{PQkey *tmp = *a; *a = *b; *b = tmp;}while(0)
/* really __gl_pqSortInit */
int pqInit( PriorityQ *pq )
diff --git a/Source/WebCore/thirdparty/glu/libtess/render.c b/Source/WebCore/thirdparty/glu/libtess/render.c
index 0e944a2..79386e8 100644
--- a/Source/WebCore/thirdparty/glu/libtess/render.c
+++ b/Source/WebCore/thirdparty/glu/libtess/render.c
@@ -150,11 +150,11 @@ static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
#define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
-#define FreeTrail(t) if( 1 ) { \
+#define FreeTrail(t) do { \
while( (t) != NULL ) { \
(t)->marked = FALSE; t = (t)->trail; \
} \
- } else /* absorb trailing semicolon */
+ } while(0) /* absorb trailing semicolon */
diff --git a/Source/WebCore/thirdparty/glu/libtess/sweep.c b/Source/WebCore/thirdparty/glu/libtess/sweep.c
index e85757c..233b2da 100644
--- a/Source/WebCore/thirdparty/glu/libtess/sweep.c
+++ b/Source/WebCore/thirdparty/glu/libtess/sweep.c
@@ -253,6 +253,7 @@ static GLboolean IsWindingInside( GLUtesselator *tess, int n )
/*LINTED*/
assert( FALSE );
/*NOTREACHED*/
+ return 0;
}
@@ -1173,7 +1174,9 @@ static void InitEdgeDict( GLUtesselator *tess )
static void DoneEdgeDict( GLUtesselator *tess )
{
ActiveRegion *reg;
+#ifndef NDEBUG
int fixedEdges = 0;
+#endif
/* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
while( (reg = (ActiveRegion *)dictKey( dictMin( tess->dict ))) != NULL ) {
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list