diff options
author | dino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-10-18 20:53:06 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-29 20:07:59 +0100 |
commit | 6f8e14c26b58761241a5b3a8429f15a809afa649 (patch) | |
tree | fc1dad3c82c390c1c4d8cf20f6f4b5faeeb1b0f2 | |
parent | 2b5c3473b324973e69ad739f594c46aae5fbbf51 (diff) | |
download | qtwebkit-6f8e14c26b58761241a5b3a8429f15a809afa649.tar.gz |
Unable to upload <img src="foo.svg"> as WebGL texture
https://bugs.webkit.org/show_bug.cgi?id=123035
Reviewed by Tim Horton.
Source/WebCore:
If the HTMLImageElement passed to texture2D is an SVG
image, paint it first into a bitmap buffer and upload that.
Note that the SVG image still needs to have an intrinsic
or explicit size - see how the test case must set width and
height.
I also renamed the cache of ImageBuffers since it is
no longer only being used for video frames.
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::WebGLRenderingContext): Rename m_videoCache to m_generatedImageCache.
(WebCore::WebGLRenderingContext::drawImageIntoBuffer): New method that creates an ImageBuffer
of the appropriate size and renders into that.
(WebCore::WebGLRenderingContext::texImage2D): If we see an SVG image, render it first.
(WebCore::WebGLRenderingContext::videoFrameToImage): Renamed m_generatedImageCache.
(WebCore::WebGLRenderingContext::texSubImage2D): If we see an SVG image, render it first.
* html/canvas/WebGLRenderingContext.h: Renaming.
Change-Id: I601eff1f3a8c11fe2a62f8b5a8a914d6eadfead4
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157647 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
-rw-r--r-- | Source/WebCore/html/canvas/WebGLRenderingContext.cpp | 36 | ||||
-rw-r--r-- | Source/WebCore/html/canvas/WebGLRenderingContext.h | 4 |
2 files changed, 33 insertions, 7 deletions
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index 8ff091bc9..0742f894c 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -456,7 +456,7 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent) , m_restoreAllowed(false) , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext) - , m_videoCache(4) + , m_generatedImageCache(4) , m_contextLost(false) , m_contextLostMode(SyntheticLostContext) , m_attributes(attributes) @@ -3808,17 +3808,37 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); } +PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height, int deviceScaleFactor) +{ + IntSize size(width, height); + size.scale(deviceScaleFactor); + ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); + if (!buf) { + synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory"); + return 0; + } + + IntRect srcRect(IntPoint(), image->size()); + IntRect destRect(IntPoint(), size); + buf->context()->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect); + return buf->copyImage(ImageBuffer::fastCopyImageMode()); +} + void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec) { ec = 0; if (isContextLost() || !validateHTMLImageElement("texImage2D", image, ec)) return; - Image* imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); + + RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); + if (imageForRender->isSVGImage()) + imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor()); + if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0)) return; - texImage2DImpl(target, level, internalformat, format, type, imageForRender, GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); + texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, @@ -3855,7 +3875,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, ExceptionCode&) { IntSize size(video->videoWidth(), video->videoHeight()); - ImageBuffer* buf = m_videoCache.imageBuffer(size); + ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); if (!buf) { synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory"); return 0; @@ -4060,11 +4080,15 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din ec = 0; if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, ec)) return; - Image* imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); + + RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); + if (imageForRender->isSVGImage()) + imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor()); + if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset)) return; - texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender, GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); + texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h index 78ba07198..34073ed83 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.h +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h @@ -384,6 +384,8 @@ public: // Adds a compressed texture format. void addCompressedTextureFormat(GC3Denum); + PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, int deviceScaleFactor); + #if ENABLE(VIDEO) PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&); #endif @@ -471,7 +473,7 @@ public: OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers; int m_capacity; }; - LRUImageBufferCache m_videoCache; + LRUImageBufferCache m_generatedImageCache; GC3Dint m_maxTextureSize; GC3Dint m_maxCubeMapTextureSize; |