JDK-8160769 : [WebView] Unable to tile SVG image using css background property
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-07-04
  • Updated: 2016-09-12
  • Resolved: 2016-07-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u112Fixed 9Fixed
Related Reports
Relates :  
Description
.bg {
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red' /></svg>");
  width: 500px;
  height: 200px;
}

Above style is not showing anything on the screen. But adding no-repeat to the background property works.
Comments
changeset: b3d3c425f919 date: Sun Jul 24 13:40:25 2016 +0100 Reviewed-by: kcr, ghb, mbilla URL: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/b3d3c425f919
24-07-2016

[~arajkumar] I missed this error last time.. Please check.. There is a whitespace error in WCBufferedContext.java at // tiled SVG images and it doesn't hold complex layers. Making this
24-07-2016

Thanks Murali. Fixed it.
24-07-2016

+1
23-07-2016

This looks like a much safer (and less intrusive fix). It doesn't seem that there will be any leak possible from not doing dispose, so I see no downside in this. +1
22-07-2016

http://cr.openjdk.java.net/~arajkumar/8160769/webrev.01 The new changeset skips dispose functionality for BufferedImage Graphics Context. WCGraphicsContext.dispose() cleans the "state" and "layers" associated with the context. BufferedImage graphics context is only used for canvas and SVG tiled drawing, which doesn't create more Layers, so we can skip dispose for all WCBufferedContext instances.
22-07-2016

Right now I'm trying to defer the WCGraphicsPrismContext destruction if there is any pending RenderQueue commands. (As mentioned by Kevin in comment #5)
21-07-2016

Also BufferImage::nativeImageForCurrentFrame (BufferImageJava.cpp) calls "m_rq->flushBuffer()", but it is not working because it is not synchronous.
21-07-2016

Thanks Kevin. >> 1. Is ImageBufferJava used for anything other than as a temporary buffer? It is also used for HTML canvas rendering. >> 2. Are there any cases where the destructor could be called where platformContext() or rq() could be NULL? platformContext is owned by GraphicsContext which is owned by ImageBufferDataJava. There is no method to set/reset the member. So it wont be NULL. >> 3. Is the destructor always called on the Event thread? Yes. ImageBufferJava objects are accessible only from WebKit main thread, which is JavaFX event thread. >> 4. How much testing have you done to ensure no regressions? On what platforms? I have done basic testing. Will do more testing with canvas and SVG. >> 5. Have you considered an alternative solution of holding a reference to the temporary image and deferring its destruction until the (async) rendering is complete? Actually we are not destroying the temporary image, we are deleting the GraphicsContext associated with the ImageBuffer. But the ImageBuffer is still alive from the Java Context because it is been referenced by the drawing command. I will try skipping GraphicsContext dispose.
21-07-2016

This approach should work for this specific case, and my limited testing shows that it does, but is in general blocking until the rendering is done can be dangerous. It could lead to deadlock if we ever call fwkFlushAndWait with the render lock held. It might not be an issue, but it does make the fix a bit more risky. I have a couple of questions: 1. Is ImageBufferJava used for anything other than as a temporary buffer? 2. Are there any cases where the destructor could be called where platformContext() or rq() could be NULL? 3. Is the destructor always called on the Event thread? 4. How much testing have you done to ensure no regressions? On what platforms? 5. Have you considered an alternative solution of holding a reference to the temporary image and deferring its destruction until the (async) rendering is complete?
20-07-2016

looks fine... +1
14-07-2016

>>In case if SVG image is large enough and invokeOnRenderThreadAndWait just waits for rendering to complete in render thread (with help of CountLatch). In the mean time, if i load another url, will i get Interrupted exception? How could you load another URL when event thread is waiting for SVG rendering to happen? It is not possible. >>How about using createLatch.await(TIMEOUT, TimeUnit.MILLISECONDS) as not to make render thread just waiting to complete the render job? Our intention is to wait until the SVG content rasterized into given buffer, we can't wait for some arbitrary time, which may break the expectation based on the content size.
14-07-2016

In case if SVG image is large enough and invokeOnRenderThreadAndWait just waits for rendering to complete in render thread (with help of CountLatch). In the mean time, if i load another url, will i get Interrupted exception? How about using createLatch.await(TIMEOUT, TimeUnit.MILLISECONDS) as not to make render thread just waiting to complete the render job?
14-07-2016

Looks good to me.
13-07-2016

Analysis: For tiled SVG image drawing, WebCore creates a temporary Graphics buffer(ImageBufferJava)[1] and renders SVG contents into it. Once the SVG is rendered in the temporary graphics buffer, WebCore will call Image::drawPattern to tile it on the WebPage's back buffer. As soon as drawing is completed, temporary graphics buffer will be destroyed. FX WebView's GraphicsContext APIs are asynchronous in nature(rendered in FX render thread using RenderQueue), so temporary graphics buffer would have been destroyed even before rendering the SVG content into it. At later point of time, when Image::drawPattern is executed in render thread, it will be accessing a GraphicsContext of an destroyed object. Solution: Before destroying an Native ImageBuffer, flush all its render queue commands synchronously, So that it's content will be rendered as expected. [1] http://trac.webkit.org/browser/trunk/Source/WebCore/svg/graphics/SVGImage.cpp?rev=187486#L202
13-07-2016

http://cr.openjdk.java.net/~arajkumar/8160769/webrev.00/
13-07-2016