summaryrefslogtreecommitdiffstats
path: root/WebCore/html/canvas
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /WebCore/html/canvas
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'WebCore/html/canvas')
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.cpp51
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.h60
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.cpp70
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.h7
-rw-r--r--WebCore/html/canvas/WebGLBuffer.cpp3
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.cpp52
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.h12
-rw-r--r--WebCore/html/canvas/WebGLObject.cpp6
-rw-r--r--WebCore/html/canvas/WebGLObject.h12
-rw-r--r--WebCore/html/canvas/WebGLProgram.cpp13
-rw-r--r--WebCore/html/canvas/WebGLRenderbuffer.cpp3
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp85
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.h3
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.idl3
-rw-r--r--WebCore/html/canvas/WebGLShader.cpp3
-rw-r--r--WebCore/html/canvas/WebGLTexture.cpp4
16 files changed, 232 insertions, 155 deletions
diff --git a/WebCore/html/canvas/CanvasRenderingContext.cpp b/WebCore/html/canvas/CanvasRenderingContext.cpp
index e019332..c814c66 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -25,7 +25,14 @@
#include "config.h"
#include "CanvasRenderingContext.h"
+
+#include "CachedImage.h"
+#include "CanvasPattern.h"
#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "KURL.h"
+#include "SecurityOrigin.h"
namespace WebCore {
@@ -44,4 +51,48 @@ void CanvasRenderingContext::deref()
m_canvas->deref();
}
+void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)
+{
+ if (canvas()->originClean() && pattern && !pattern->originClean())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)
+{
+ if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)
+{
+ if (!image || !canvas()->originClean())
+ return;
+
+ CachedImage* cachedImage = image->cachedImage();
+ checkOrigin(cachedImage->response().url());
+
+ if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)
+{
+#if ENABLE(VIDEO)
+ checkOrigin(KURL(KURL(), video->currentSrc()));
+ if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin())
+ canvas()->setOriginTainted();
+#endif
+}
+
+void CanvasRenderingContext::checkOrigin(const KURL& url)
+{
+ if (!canvas()->originClean() || m_cleanOrigins.contains(url.string()))
+ return;
+
+ if (canvas()->securityOrigin().taintsCanvas(url))
+ canvas()->setOriginTainted();
+ else
+ m_cleanOrigins.add(url.string());
+}
+
} // namespace WebCore
diff --git a/WebCore/html/canvas/CanvasRenderingContext.h b/WebCore/html/canvas/CanvasRenderingContext.h
index 8499b47..a25e8a1 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/WebCore/html/canvas/CanvasRenderingContext.h
@@ -28,38 +28,52 @@
#include "GraphicsLayer.h"
+#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
namespace WebCore {
- class WebGLObject;
- class HTMLCanvasElement;
+class CanvasPattern;
+class HTMLCanvasElement;
+class HTMLImageElement;
+class HTMLVideoElement;
+class KURL;
+class WebGLObject;
- class CanvasRenderingContext : public Noncopyable {
- public:
- CanvasRenderingContext(HTMLCanvasElement*);
- virtual ~CanvasRenderingContext() { }
-
- // Ref and deref the m_canvas
- void ref();
- void deref();
-
- HTMLCanvasElement* canvas() const { return m_canvas; }
-
- virtual bool is2d() const { return false; }
- virtual bool is3d() const { return false; }
- virtual bool isAccelerated() const { return false; }
-
- virtual void paintRenderingResultsToCanvas() {}
- virtual bool paintsIntoCanvasBuffer() const { return true; }
+class CanvasRenderingContext : public Noncopyable {
+public:
+ CanvasRenderingContext(HTMLCanvasElement*);
+ virtual ~CanvasRenderingContext() { }
+
+ // Ref and deref the m_canvas
+ void ref();
+ void deref();
+
+ HTMLCanvasElement* canvas() const { return m_canvas; }
+
+ virtual bool is2d() const { return false; }
+ virtual bool is3d() const { return false; }
+ virtual bool isAccelerated() const { return false; }
+
+ virtual void paintRenderingResultsToCanvas() {}
+ virtual bool paintsIntoCanvasBuffer() const { return true; }
#if USE(ACCELERATED_COMPOSITING)
- virtual PlatformLayer* platformLayer() const { return 0; }
+ virtual PlatformLayer* platformLayer() const { return 0; }
#endif
- private:
- HTMLCanvasElement* m_canvas;
- };
+protected:
+ void checkOrigin(const CanvasPattern*);
+ void checkOrigin(const HTMLCanvasElement*);
+ void checkOrigin(const HTMLImageElement*);
+ void checkOrigin(const HTMLVideoElement*);
+ void checkOrigin(const KURL&);
+
+private:
+ HTMLCanvasElement* m_canvas;
+ HashSet<String> m_cleanOrigins;
+};
} // namespace WebCore
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 0fb7ed5..161a891 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -249,12 +249,7 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> style)
if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style))
return;
- if (canvas()->originClean()) {
- if (CanvasPattern* pattern = style->canvasPattern()) {
- if (!pattern->originClean())
- canvas()->setOriginTainted();
- }
- }
+ checkOrigin(style->canvasPattern());
state().m_strokeStyle = style;
GraphicsContext* c = drawingContext();
@@ -277,12 +272,7 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> style)
if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style))
return;
- if (canvas()->originClean()) {
- if (CanvasPattern* pattern = style->canvasPattern()) {
- if (!pattern->originClean())
- canvas()->setOriginTainted();
- }
- }
+ checkOrigin(style->canvasPattern());
state().m_fillStyle = style;
GraphicsContext* c = drawingContext();
@@ -1121,25 +1111,6 @@ static inline FloatRect normalizeRect(const FloatRect& rect)
max(rect.height(), -rect.height()));
}
-void CanvasRenderingContext2D::checkOrigin(const KURL& url)
-{
- if (m_cleanOrigins.contains(url.string()))
- return;
-
- if (canvas()->securityOrigin().taintsCanvas(url))
- canvas()->setOriginTainted();
- else
- m_cleanOrigins.add(url.string());
-}
-
-void CanvasRenderingContext2D::checkOrigin(const String& url)
-{
- if (m_cleanOrigins.contains(url))
- return;
-
- checkOrigin(KURL(KURL(), url));
-}
-
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec)
{
if (!image) {
@@ -1186,18 +1157,21 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
|| !isfinite(srcRect.x()) || !isfinite(srcRect.y()) || !isfinite(srcRect.width()) || !isfinite(srcRect.height()))
return;
+ if (!dstRect.width() || !dstRect.height())
+ return;
+
if (!image->complete())
return;
+ FloatRect normalizedSrcRect = normalizeRect(srcRect);
+ FloatRect normalizedDstRect = normalizeRect(dstRect);
+
FloatRect imageRect = FloatRect(FloatPoint(), size(image));
- if (!imageRect.contains(normalizeRect(srcRect)) || !srcRect.width() || !srcRect.height()) {
+ if (!imageRect.contains(normalizedSrcRect) || !srcRect.width() || !srcRect.height()) {
ec = INDEX_SIZE_ERR;
return;
}
- if (!dstRect.width() || !dstRect.height())
- return;
-
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -1208,14 +1182,10 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
if (!cachedImage)
return;
- if (canvas()->originClean())
- checkOrigin(cachedImage->response().url());
-
- if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ checkOrigin(image);
- FloatRect sourceRect = c->roundToDevicePixels(srcRect);
- FloatRect destRect = c->roundToDevicePixels(dstRect);
+ FloatRect sourceRect = c->roundToDevicePixels(normalizedSrcRect);
+ FloatRect destRect = c->roundToDevicePixels(normalizedDstRect);
c->drawImage(cachedImage->image(), DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
didDraw(destRect);
}
@@ -1285,8 +1255,7 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
if (!buffer)
return;
- if (!sourceCanvas->originClean())
- canvas()->setOriginTainted();
+ checkOrigin(sourceCanvas);
#if ENABLE(ACCELERATED_2D_CANVAS)
// If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
@@ -1360,11 +1329,7 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
if (!state().m_invertibleCTM)
return;
- if (canvas()->originClean())
- checkOrigin(video->currentSrc());
-
- if (canvas()->originClean() && !video->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ checkOrigin(video);
FloatRect sourceRect = c->roundToDevicePixels(srcRect);
FloatRect destRect = c->roundToDevicePixels(dstRect);
@@ -1393,11 +1358,7 @@ void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
if (!cachedImage)
return;
- if (canvas()->originClean())
- checkOrigin(cachedImage->response().url());
-
- if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ checkOrigin(image);
GraphicsContext* c = drawingContext();
if (!c)
@@ -1689,6 +1650,7 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
RefPtr<RenderStyle> newStyle = RenderStyle::create();
if (RenderStyle* computedStyle = canvas()->computedStyle())
newStyle->setFontDescription(computedStyle->fontDescription());
+ newStyle->font().update(newStyle->font().fontSelector());
// Now map the font property into the style.
CSSStyleSelector* styleSelector = canvas()->styleSelector();
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.h b/WebCore/html/canvas/CanvasRenderingContext2D.h
index 91b6549..2c88a31 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -36,7 +36,6 @@
#include "PlatformString.h"
#include <wtf/Vector.h>
-#include <wtf/text/StringHash.h>
#if PLATFORM(CG)
#include <ApplicationServices/ApplicationServices.h>
@@ -57,7 +56,6 @@ class HTMLCanvasElement;
class HTMLImageElement;
class HTMLVideoElement;
class ImageData;
-class KURL;
class TextMetrics;
#if ENABLE(ACCELERATED_2D_CANVAS)
@@ -289,11 +287,6 @@ private:
void prepareGradientForDashboard(CanvasGradient* gradient) const;
- HashSet<String> m_cleanOrigins;
-
- void checkOrigin(const KURL&);
- void checkOrigin(const String&);
-
Vector<State, 1> m_stateStack;
bool m_usesCSSCompatibilityParseMode;
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp
index d43868d..99d9cad 100644
--- a/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/WebCore/html/canvas/WebGLBuffer.cpp
@@ -52,7 +52,8 @@ WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
void WebGLBuffer::deleteObjectImpl(Platform3DObject object)
{
- context()->graphicsContext3D()->deleteBuffer(object);
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteBuffer(object);
}
bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, unsigned byteOffset, unsigned byteLength)
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 6291705..a709341 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -40,10 +40,6 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx
WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
: WebGLObject(ctx)
- , m_colorAttachment(0)
- , m_depthAttachment(0)
- , m_stencilAttachment(0)
- , m_depthStencilAttachment(0)
{
setObject(context()->graphicsContext3D()->createFramebuffer());
}
@@ -73,6 +69,23 @@ void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* atta
initializeRenderbuffers();
}
+void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
+{
+ if (!object())
+ return;
+ if (attachment == m_colorAttachment.get())
+ m_colorAttachment = 0;
+ else if (attachment == m_depthAttachment.get())
+ m_depthAttachment = 0;
+ else if (attachment == m_stencilAttachment.get())
+ m_stencilAttachment = 0;
+ else if (attachment == m_depthStencilAttachment.get())
+ m_depthStencilAttachment = 0;
+ else
+ return;
+ initializeRenderbuffers();
+}
+
void WebGLFramebuffer::onBind()
{
initializeRenderbuffers();
@@ -83,8 +96,8 @@ void WebGLFramebuffer::onAttachedObjectChange(WebGLObject* object)
// Currently object == 0 is not considered, but this might change if the
// lifespan of WebGLObject changes.
if (object
- && (object == m_colorAttachment || object == m_depthAttachment
- || object == m_stencilAttachment || object == m_depthStencilAttachment))
+ && (object == m_colorAttachment.get() || object == m_depthAttachment.get()
+ || object == m_stencilAttachment.get() || object == m_depthStencilAttachment.get()))
initializeRenderbuffers();
}
@@ -92,7 +105,7 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
{
if (object() && m_colorAttachment && m_colorAttachment->object()) {
if (m_colorAttachment->isRenderbuffer()) {
- unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment))->getInternalFormat();
+ unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
switch (format) {
case GraphicsContext3D::RGBA4:
case GraphicsContext3D::RGB5_A1:
@@ -101,14 +114,19 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
return GraphicsContext3D::RGB;
}
} else if (m_colorAttachment->isTexture())
- return (reinterpret_cast<WebGLTexture*>(m_colorAttachment))->getInternalFormat(0);
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(0);
}
return 0;
}
void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
{
- context()->graphicsContext3D()->deleteFramebuffer(object);
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteFramebuffer(object);
+ m_colorAttachment = 0;
+ m_depthAttachment = 0;
+ m_stencilAttachment = 0;
+ m_depthStencilAttachment = 0;
}
bool WebGLFramebuffer::isUninitialized(WebGLObject* attachedObject)
@@ -131,19 +149,19 @@ void WebGLFramebuffer::initializeRenderbuffers()
return;
bool initColor = false, initDepth = false, initStencil = false;
unsigned long mask = 0;
- if (isUninitialized(m_colorAttachment)) {
+ if (isUninitialized(m_colorAttachment.get())) {
initColor = true;
mask |= GraphicsContext3D::COLOR_BUFFER_BIT;
}
- if (isUninitialized(m_depthAttachment)) {
+ if (isUninitialized(m_depthAttachment.get())) {
initDepth = true;
mask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
}
- if (isUninitialized(m_stencilAttachment)) {
+ if (isUninitialized(m_stencilAttachment.get())) {
initStencil = true;
mask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
}
- if (isUninitialized(m_depthStencilAttachment)) {
+ if (isUninitialized(m_depthStencilAttachment.get())) {
initDepth = true;
initStencil = true;
mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
@@ -209,14 +227,14 @@ void WebGLFramebuffer::initializeRenderbuffers()
g3d->disable(GraphicsContext3D::DITHER);
if (initColor)
- setInitialized(m_colorAttachment);
+ setInitialized(m_colorAttachment.get());
if (initDepth && initStencil && m_depthStencilAttachment)
- setInitialized(m_depthStencilAttachment);
+ setInitialized(m_depthStencilAttachment.get());
else {
if (initDepth)
- setInitialized(m_depthAttachment);
+ setInitialized(m_depthAttachment.get());
if (initStencil)
- setInitialized(m_stencilAttachment);
+ setInitialized(m_stencilAttachment.get());
}
}
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index ac945dd..1892694 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -44,6 +44,8 @@ public:
bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
void setAttachment(unsigned long, WebGLObject*);
+ // If an object is attached to the framebuffer, remove it.
+ void removeAttachment(WebGLObject*);
// This function is called right after a framebuffer is bound.
// Because renderbuffers and textures attached to the framebuffer might
@@ -71,12 +73,10 @@ private:
void setInitialized(WebGLObject*);
void initializeRenderbuffers();
- // These objects are kept alive by the global table in
- // WebGLRenderingContext.
- WebGLObject* m_colorAttachment;
- WebGLObject* m_depthAttachment;
- WebGLObject* m_stencilAttachment;
- WebGLObject* m_depthStencilAttachment;
+ RefPtr<WebGLObject> m_colorAttachment;
+ RefPtr<WebGLObject> m_depthAttachment;
+ RefPtr<WebGLObject> m_stencilAttachment;
+ RefPtr<WebGLObject> m_depthStencilAttachment;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLObject.cpp b/WebCore/html/canvas/WebGLObject.cpp
index 5fd5534..8aa4663 100644
--- a/WebCore/html/canvas/WebGLObject.cpp
+++ b/WebCore/html/canvas/WebGLObject.cpp
@@ -49,10 +49,8 @@ WebGLObject::~WebGLObject()
void WebGLObject::setObject(Platform3DObject object)
{
- if (object == m_object)
- return;
-
- deleteObject();
+ // object==0 && m_deleted==false indicating an uninitialized state;
+ ASSERT(!m_object && !m_deleted);
m_object = object;
}
diff --git a/WebCore/html/canvas/WebGLObject.h b/WebCore/html/canvas/WebGLObject.h
index 18d4cf9..82b8079 100644
--- a/WebCore/html/canvas/WebGLObject.h
+++ b/WebCore/html/canvas/WebGLObject.h
@@ -40,7 +40,6 @@ public:
virtual ~WebGLObject();
Platform3DObject object() const { return m_object; }
- void setObject(Platform3DObject);
void deleteObject();
void detachContext()
@@ -64,13 +63,22 @@ public:
if (m_attachmentCount)
--m_attachmentCount;
if (!m_attachmentCount && m_deleted)
- m_object = 0;
+ deleteObject();
}
unsigned getAttachmentCount() { return m_attachmentCount; }
protected:
WebGLObject(WebGLRenderingContext*);
+
+ // setObject should be only called once right after creating a WebGLObject.
+ void setObject(Platform3DObject);
+
+ // deleteObjectImpl() may be called multiple times for the same object;
+ // isDeleted() needs to be tested in implementations when deciding whether
+ // to delete the OpenGL resource.
virtual void deleteObjectImpl(Platform3DObject) = 0;
+ bool isDeleted() { return m_deleted; }
+ void setDeteled() { m_deleted = true; }
private:
Platform3DObject m_object;
diff --git a/WebCore/html/canvas/WebGLProgram.cpp b/WebCore/html/canvas/WebGLProgram.cpp
index 8cf3c42..0853b67 100644
--- a/WebCore/html/canvas/WebGLProgram.cpp
+++ b/WebCore/html/canvas/WebGLProgram.cpp
@@ -47,12 +47,17 @@ WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
{
- context()->graphicsContext3D()->deleteProgram(obj);
- if (!object()) {
- if (m_vertexShader)
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteProgram(obj);
+ if (!getAttachmentCount()) {
+ if (m_vertexShader) {
m_vertexShader->onDetached();
- if (m_fragmentShader)
+ m_vertexShader = 0;
+ }
+ if (m_fragmentShader) {
m_fragmentShader->onDetached();
+ m_fragmentShader = 0;
+ }
}
}
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp
index 7bc2eec..4772873 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -48,7 +48,8 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object)
{
- context()->graphicsContext3D()->deleteRenderbuffer(object);
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteRenderbuffer(object);
}
}
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 68a6954..d1bb0cd 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -635,7 +635,11 @@ void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
{
if (!framebuffer)
return;
-
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = 0;
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ }
framebuffer->deleteObject();
}
@@ -656,10 +660,11 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
{
if (!renderbuffer)
return;
-
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = 0;
renderbuffer->deleteObject();
if (m_framebufferBinding)
- m_framebufferBinding->onAttachedObjectChange(renderbuffer);
+ m_framebufferBinding->removeAttachment(renderbuffer);
}
void WebGLRenderingContext::deleteShader(WebGLShader* shader)
@@ -677,7 +682,7 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
texture->deleteObject();
if (m_framebufferBinding)
- m_framebufferBinding->onAttachedObjectChange(texture);
+ m_framebufferBinding->removeAttachment(texture);
}
void WebGLRenderingContext::depthFunc(unsigned long func)
@@ -775,30 +780,31 @@ bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, l
// index, skips the expensive per-draw-call iteration in
// validateIndexArrayPrecise.
+ if (!m_boundElementArrayBuffer)
+ return false;
+
+ unsigned numElements = m_boundElementArrayBuffer->byteLength();
+ // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+ if (!numElements)
+ return false;
+ const ArrayBuffer* buffer = m_boundElementArrayBuffer->elementArrayBuffer();
+ ASSERT(buffer);
+
long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type);
if (maxIndex < 0) {
// Compute the maximum index in the entire buffer for the given type of index.
switch (type) {
case GraphicsContext3D::UNSIGNED_BYTE: {
- unsigned numElements = m_boundElementArrayBuffer->byteLength();
- if (!numElements)
- maxIndex = 0;
- else {
- const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
- for (unsigned i = 0; i < numElements; i++)
- maxIndex = max(maxIndex, static_cast<long>(p[i]));
- }
+ const unsigned char* p = static_cast<const unsigned char*>(buffer->data());
+ for (unsigned i = 0; i < numElements; i++)
+ maxIndex = max(maxIndex, static_cast<long>(p[i]));
break;
}
case GraphicsContext3D::UNSIGNED_SHORT: {
- unsigned numElements = m_boundElementArrayBuffer->byteLength() / sizeof(unsigned short);
- if (!numElements)
- maxIndex = 0;
- else {
- const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
- for (unsigned i = 0; i < numElements; i++)
- maxIndex = max(maxIndex, static_cast<long>(p[i]));
- }
+ numElements /= sizeof(unsigned short);
+ const unsigned short* p = static_cast<const unsigned short*>(buffer->data());
+ for (unsigned i = 0; i < numElements; i++)
+ maxIndex = max(maxIndex, static_cast<long>(p[i]));
break;
}
default:
@@ -824,6 +830,14 @@ bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsig
if (!m_boundElementArrayBuffer)
return false;
+ if (!count) {
+ numElementsRequired = 0;
+ return true;
+ }
+
+ if (!m_boundElementArrayBuffer->elementArrayBuffer())
+ return false;
+
unsigned long uoffset = static_cast<unsigned long>(offset);
unsigned long n = count;
@@ -968,6 +982,8 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
+ if (!count)
+ return;
if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
@@ -1379,6 +1395,8 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
return getLongParameter(pname);
case GraphicsContext3D::RENDERBUFFER_BINDING:
return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GraphicsContext3D::RENDERER:
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
case GraphicsContext3D::SAMPLE_BUFFERS:
return getLongParameter(pname);
case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
@@ -1391,6 +1409,8 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
return getWebGLIntArrayParameter(pname);
case GraphicsContext3D::SCISSOR_TEST:
return getBooleanParameter(pname);
+ case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
+ return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
case GraphicsContext3D::STENCIL_BACK_FAIL:
return getUnsignedLongParameter(pname);
case GraphicsContext3D::STENCIL_BACK_FUNC:
@@ -1438,6 +1458,10 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
return WebGLGetInfo(m_unpackFlipY);
case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ case GraphicsContext3D::VENDOR:
+ return WebGLGetInfo("Webkit (" + m_context->getString(GraphicsContext3D::VENDOR) + ")");
+ case GraphicsContext3D::VERSION:
+ return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
case GraphicsContext3D::VIEWPORT:
return getWebGLIntArrayParameter(pname);
default:
@@ -1563,12 +1587,6 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode
return m_context->getShaderSource(objectOrZero(shader));
}
-String WebGLRenderingContext::getString(unsigned long name)
-{
- WebGLStateRestorer(this, false);
- return m_context->getString(name);
-}
-
WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
@@ -1922,8 +1940,12 @@ void WebGLRenderingContext::polygonOffset(double factor, double units)
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels)
+void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode& ec)
{
+ if (!canvas()->originClean()) {
+ ec = SECURITY_ERR;
+ return;
+ }
// Validate input parameters.
unsigned long componentsPerPixel, bytesPerComponent;
if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
@@ -2165,6 +2187,7 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
+ checkOrigin(image);
texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -2177,7 +2200,7 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
-
+ checkOrigin(canvas);
texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -2194,6 +2217,7 @@ PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* vid
m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
return 0;
}
+ checkOrigin(video);
IntRect destRect(0, 0, size.width(), size.height());
// FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
video->paintCurrentFrameInContext(buf->context(), destRect);
@@ -2326,6 +2350,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
+ checkOrigin(image);
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -2338,7 +2363,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
-
+ checkOrigin(canvas);
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -2703,7 +2728,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
m_currentProgram->onDetached();
m_currentProgram = program;
m_context->useProgram(objectOrZero(program));
- if (program)
+ if (program && program->object())
program->onAttached();
}
cleanupAfterGraphicsCall(false);
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index d812c69..f507054 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -163,7 +163,6 @@ public:
// void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
String getShaderSource(WebGLShader*, ExceptionCode&);
- String getString(unsigned long name);
WebGLGetInfo getTexParameter(unsigned long target, unsigned long pname, ExceptionCode&);
@@ -187,7 +186,7 @@ public:
void linkProgram(WebGLProgram*, ExceptionCode&);
void pixelStorei(unsigned long pname, long param);
void polygonOffset(double factor, double units);
- void readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels);
+ void readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode&);
void releaseShaderCompiler();
void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height);
void sampleCoverage(double value, bool invert);
diff --git a/WebCore/html/canvas/WebGLRenderingContext.idl b/WebCore/html/canvas/WebGLRenderingContext.idl
index 7a63752..f76646d 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -563,7 +563,6 @@ module html {
// void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
[StrictTypeChecking] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
- [StrictTypeChecking] DOMString getString(in unsigned long name);
// any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getTexParameter();
@@ -591,7 +590,7 @@ module html {
[StrictTypeChecking] void pixelStorei(in unsigned long pname, in long param);
[StrictTypeChecking] void polygonOffset(in double factor, in double units);
- [StrictTypeChecking] void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels);
+ [StrictTypeChecking] void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises(DOMException);
[StrictTypeChecking] void releaseShaderCompiler();
[StrictTypeChecking] void renderbufferStorage(in unsigned long target, in unsigned long internalformat, in unsigned long width, in unsigned long height);
diff --git a/WebCore/html/canvas/WebGLShader.cpp b/WebCore/html/canvas/WebGLShader.cpp
index 4f8bf68..1ccaad8 100644
--- a/WebCore/html/canvas/WebGLShader.cpp
+++ b/WebCore/html/canvas/WebGLShader.cpp
@@ -47,7 +47,8 @@ WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GraphicsContext3D::WebGLEnu
void WebGLShader::deleteObjectImpl(Platform3DObject object)
{
- context()->graphicsContext3D()->deleteShader(object);
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteShader(object);
}
}
diff --git a/WebCore/html/canvas/WebGLTexture.cpp b/WebCore/html/canvas/WebGLTexture.cpp
index 7fc84ad..c2b1c10 100644
--- a/WebCore/html/canvas/WebGLTexture.cpp
+++ b/WebCore/html/canvas/WebGLTexture.cpp
@@ -29,6 +29,7 @@
#include "WebGLTexture.h"
+#include "WebGLFramebuffer.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -201,7 +202,8 @@ bool WebGLTexture::needToUseBlackTexture() const
void WebGLTexture::deleteObjectImpl(Platform3DObject object)
{
- context()->graphicsContext3D()->deleteTexture(object);
+ if (!isDeleted())
+ context()->graphicsContext3D()->deleteTexture(object);
}
int WebGLTexture::mapTargetToIndex(unsigned long target)