diff options
author | Kristian Monsen <kristianm@google.com> | 2010-09-30 15:42:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-10-07 10:59:29 +0100 |
commit | bec39347bb3bb5bf1187ccaf471d26247f28b585 (patch) | |
tree | 56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /WebCore/html/canvas | |
parent | 90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff) | |
download | external_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.cpp | 51 | ||||
-rw-r--r-- | WebCore/html/canvas/CanvasRenderingContext.h | 60 | ||||
-rw-r--r-- | WebCore/html/canvas/CanvasRenderingContext2D.cpp | 70 | ||||
-rw-r--r-- | WebCore/html/canvas/CanvasRenderingContext2D.h | 7 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLBuffer.cpp | 3 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLFramebuffer.cpp | 52 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLFramebuffer.h | 12 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLObject.cpp | 6 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLObject.h | 12 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLProgram.cpp | 13 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLRenderbuffer.cpp | 3 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLRenderingContext.cpp | 85 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLRenderingContext.h | 3 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLRenderingContext.idl | 3 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLShader.cpp | 3 | ||||
-rw-r--r-- | WebCore/html/canvas/WebGLTexture.cpp | 4 |
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) |