JDK-8127382 : drawTexture edge condition enforcement behavior is not well defined for all subimage cases
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: fx2.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2012-01-30
  • Updated: 2015-06-17
  • Resolved: 2012-06-05
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 7
7u6Fixed
Related Reports
Relates :  
Relates :  
Description
Currently drawTexture enforces edge conditions on the outermost 1/2 pixel of a subimage.  This makes sense when thinking of subimages that are an integer number of pixels, but since we allow subimage coordinates that are arbitrary floating point values we might end up with the case that it is called on a subimage area that is less than 1 pixel across and so the edge conditions will not only completely take over the operation, but the area that is half a pixel in from the sides will be a negative size.
Comments
Via bug RT-19962 we decided to remove the edge condition enforcement behavior from ImageView Viewports and simply have them behave like texture mapping. The test case attached to this issue was key to evaluating that decision. The change was implemented with the changeset that fixed RT-19962: changeset: 16212:fb9375368023 date: Tue Jun 05 10:04:22 2012 -0700 summary: Fix RT-19962: Floating point Viewports implement confusing behavior.
05-06-2012

Attaching a new version of the test case SubimagePlayground3.zip This version shows 2 zoomed ImageView viewports side by side. As you move the mouse the viewports scroll around inside the images and they look like 2 unrelated views into similar images. If you press the mouse button, then a different technique is used (not relying on the FX Viewport behavior) where they appear to both be part of one very large view into the image (but, in fact, they are 2 separate views that stitch seamlessly together). If the "edge condition enforcement behavior" is neutralized in the prism ImageView code then the default behavior will also be a seamlessly stitched pair of images (and pressing the mouse button may switch the internal mechanism being used, but both mechanisms will look identical). Since the alternate behavior (with the mouse button pressed or the Prism ImageView edge conditions neutralized) looks much more useful, we will proceed with establishing that implementation as the definitive behavior...
05-06-2012

Added a new version of the Subimage test where you can press the mouse in the FX version and it will switch to a view that uses regular scaling and clipping to demonstrate what a simpler "texture mapping" interpretation would look like. You can see that on 2.1 the only change that happens when you press and release the mouse is that the edges clean up. On Presidio, the actual zoom size of the image changes (due to the bad mapping of the outermost "half a pixel size" that was mentioned in an earlier comment). The HTML5 version of the example remains the same in both zipped projects...
29-02-2012

The attached SubimagePlayground project demonstrates the differing behavior between Presidio and the new code in 2.1. It also contains a test written in HTML5 Canvas language. In both tests you simply move the mouse around within the bounds of the test and you should see the viewport scroll across the image and show a magnified view of some "subimage" of the checkerboard test image. The HTML5 Canvas behavior for subimages seems to be to treat the floating point subimage coordinates as if they were texture coordinates for a 3D texture mapping process. In other words, there are no artificial edge conditions imposed on those coordinates to "pretend as if the subimage were isolated from the original image" like we "fixed" in 2.1. If you run the FX version of the example on Presidio you see that it appears to behave as it does in the HTML5 canvas demo in that there are no strange anomalies along the edge as you drag the mouse around to animate the viewport. In actuality, it does try to do an edge condition, but it maps the 0.5 edge of pixels of the source region to the 0.5 edge of pixels of the destination region, which is not very visible, and it then renders the rest of the subimage area (inset by 0.5 pixels all around) to the rest of the magnifier area. In essence, it is blowing up a 3x3 section of the source image (representing 1.5 x 1.5 checkerboard squares) into the view. If you run the FX version on the recent 2.1 builds then you will see that the edges behave differently. It is trying to map the 4x4 viewport view (representing 2x2 full checkerboard squares) into the entire region, but clamping the samples on the outermost 0.5 pixels of that view. The total affected area here will be the outermost 1/8 of the view (half a pixel of a 4 pixel view). As you move the mouse around it looks a little bit like a kaleidoscope at the edges where they clamp. The big gain in 2.1 was to fix the bad scaling of the clamping area so that the 2.1 version now does show the correct "fitment" of a view of a 4x4 region of the source, it just loses detail on the outermost 1/8 of that correct scaling. The Presidio code lost a whole pixel of the source region and ended up scaling a 3x3 region into the entire view (with a tiny unnoticeable half pixel anomaly all around that would take careful eyes and a screen magnifier to even measure). My general recommendation from this test would be to recommend that we change the 2.1 code yet again to simply do a more "texture mapping" like operation where we do not attempt to clamp the outermost 1/2 pixels of the source region unless they are on the actual edge of the image (where there are no samples to blend towards). This would match the behavior of HTML5 canvas implementations where floating point subimages are specified. There is one caveat to that recommendation - if the developer is using the viewport to cut out frames of an animation that are stored side by side in a larger image, or if they have an image that needs to be "9-sliced" to provide visuals for the corners, edges, and content area of a control - then we might introduce an anomaly if the edges at which they are slicing had contrasting pixels on either side of the slice. That condition is likely to be rare since a 9-slice image would likely have the various slices look like they belong abutted against each other and so would have a smooth transition across the sliced region, and in the case of the animation, it is likely that the animation would have a consistent border around the animation frames so that the left side of one frame would match the right side of the previous frame, etc. and so the blending with the pixels on the other side of the viewport slice would likely be a NOP in both of those cases anyway.
29-02-2012

Notable cases that are not well defined by the language in the spec (notably the description of ImageView.viewport): - What does it mean to specify floating point values to choose which pixels are included? - Depending on the answer to the first question, is that condition implementable for corner cases like when the width or height of the subimage are less than a pixel?
01-02-2012

Issues discovered while fixing RT-19208.
31-01-2012