summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLCanvasElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLCanvasElement.cpp')
-rw-r--r--WebCore/html/HTMLCanvasElement.cpp65
1 files changed, 59 insertions, 6 deletions
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 203579b..e3fe329 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -30,6 +30,9 @@
#include "CanvasGradient.h"
#include "CanvasPattern.h"
#include "CanvasRenderingContext2D.h"
+#if ENABLE(3D_CANVAS)
+#include "CanvasRenderingContext3D.h"
+#endif
#include "CanvasStyle.h"
#include "Chrome.h"
#include "Document.h"
@@ -146,17 +149,45 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, ExceptionCode& ec)
CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type)
{
+ // A Canvas can either be "2D" or "3D" never both. If you request a 2D canvas and the existing
+ // context is already 2D, just return that. If the existing context is 3D, then destroy it
+ // before creating a new 2D context. Vice versa when requesting a 3D canvas. Requesting a
+ // context with any other type string will destroy any existing context.
+
+ // FIXME - The code depends on the context not going away once created, to prevent JS from
+ // seeing a dangling pointer. So for now we will disallow the context from being changed
+ // once it is created.
if (type == "2d") {
- if (!m_2DContext)
- m_2DContext.set(new CanvasRenderingContext2D(this));
- return m_2DContext.get();
+ if (m_context && !m_context->is2d())
+ return 0;
+ if (!m_context)
+ m_context = new CanvasRenderingContext2D(this);
+ return m_context.get();
+ }
+#if ENABLE(3D_CANVAS)
+ Settings* settings = document()->settings();
+ if (settings && settings->webGLEnabled()) {
+ if ((type == "webkit-3d") ||
+ (type == "GL")) {
+ if (m_context && !m_context->is3d())
+ return 0;
+ if (!m_context) {
+ m_context = new CanvasRenderingContext3D(this);
+
+ // Need to make sure a RenderLayer and compositing layer get created for the Canvas
+ setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+ return m_context.get();
+ }
}
+#endif
return 0;
}
void HTMLCanvasElement::willDraw(const FloatRect& rect)
{
- m_imageBuffer->clearImage();
+ if (m_imageBuffer)
+ m_imageBuffer->clearImage();
if (RenderBox* ro = renderBox()) {
FloatRect destRect = ro->contentBoxRect();
@@ -192,8 +223,8 @@ void HTMLCanvasElement::reset()
bool hadImageBuffer = m_createdImageBuffer;
m_createdImageBuffer = false;
m_imageBuffer.clear();
- if (m_2DContext)
- m_2DContext->reset();
+ if (m_context && m_context->is2d())
+ static_cast<CanvasRenderingContext2D*>(m_context.get())->reset();
if (RenderObject* renderer = this->renderer()) {
if (m_rendererIsCanvas) {
@@ -216,11 +247,26 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
if (context->paintingDisabled())
return;
+#if ENABLE(3D_CANVAS)
+ CanvasRenderingContext3D* context3D = NULL;
+ if (m_context && m_context->is3d()) {
+ context3D = static_cast<CanvasRenderingContext3D*>(m_context.get());
+ context3D->beginPaint();
+ }
+#endif
+
if (m_imageBuffer) {
Image* image = m_imageBuffer->image();
if (image)
context->drawImage(image, r);
}
+
+#if ENABLE(3D_CANVAS)
+ if (context3D != NULL) {
+ context3D->reshape(r.width(), r.height());
+ context3D->endPaint();
+ }
+#endif
}
IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
@@ -293,4 +339,11 @@ TransformationMatrix HTMLCanvasElement::baseTransform() const
return transform;
}
+#if ENABLE(3D_CANVAS)
+bool HTMLCanvasElement::is3D() const
+{
+ return m_context && m_context->is3d();
+}
+#endif
+
}