New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8274939: Incorrect size of the pixel storage is used by the robot on macOS #5864
Conversation
👋 Welcome back serb! A progress list of the required criteria for merging this PR into |
Webrevs
|
Whilst more in keeping with the code that grabs an area It's not easy to know if this really makes things better in any practical way. |
As I mentioned in that bug, the scaleUI option does not affect the macOS API we use, and if the option solves the tests failures mean that we still have some other bugs somewhere. |
Does anybody have some comments or suggestions? I would like to fix this before adding more changes to the robot code. |
@mrserb This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
Any volunteers? |
It seems CheckCommonColors still fails intermittently even with this fix in macos aarch64 along with others CheckCommonColors fails with this log |
They could fail because of cursor location, or some other bug in our code or in the macOS. It will be good to debug it on that system where it fail. |
@mrserb This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
Any volunteers? |
Any volunteers to look at this buffer overrun? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think increasing the buffer according to the scale is correct as the scale
× scale
image where scale != 1
can't fit into the buffer of size 1.
It may not fix other bugs or test failures; buffer overrun is not a good thing and it's fixed.
@mrserb This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 99 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
I wonder if a similar problem exist on Windows and Linux. The |
I noted I was intending to run tests with this patch applied .. I think I did that but of course I've lost them now. I'll try again. |
Why doesn't this need updating too ? Seems like it must be OK else we'd have massive over-runs .. @OverRide |
Looking at what happens in native it seems like it should be possible to add a check that the |
My testing looks good - but waiting on answers to the other questions |
On Linux and Windows we pass the size of the area to the system in the device space, so we store an image of the size we just allocated. The macOS is different we pass the coordinates in the users space -> when we pass 1x1 we may get 4x4 on the HiDPI screen, this is what the current fix changed.
We do not need to change other getRGBPixels() method because its coordinates already converted to the pixels(device space), we do this in the shared code. Note that the method which changed by this fix however use the "1" as a width and height in the users space - this is a bug.
The logic we use is this: |
I get that getPixelColor() / getRGBPixel() takes only a coordinate but when looking at CRobotPeer it is far from obvious why there is this inconsistency. If we can't make the shared code consistent - maybe add a scale parameter ? Then at least we should have some comments. X11: Windows : And in native what I was suggesting was a safeguard that would have detected this problem - which I still think would be a good idea. BTW "usually this is 1x1 pixel on lowdpi and 4x4 on hidpi screen, actually macOS may return any size" When might it return "any size" ? |
Since the coordinates are in the device space, and we pass this coordinates to the OS as is, and the OS returns the images of the requested size we do not need to use a scale there. Unlike macOS where we should have coordinates in the user space and device space at the same time. So instead of the second coordinates we pass the scale and calculate others coordinate.
Per the specification of the method we use: kCGWindowImageBestResolution. So when we request the area in the user space, that method may return low/hi/something in between/ image, then we convert/scale that image to fit the array we allocated. |
|
I can add some check but which one? In the native we should use the bounds we passed from java side, the problem is that we pass "1 * scale" = 'scale", but allocate the array as "new int[1]" so this is an issue on that java side in the changed method. |
JNIEXPORT void JNICALL void *jPixelData = (*env)->GetPrimitiveArrayCritical(env, pixels, 0); CGContextRef jPicContextRef = CGBitmapContextCreate( And then the apple docs at https://developer.apple.com/documentation/coregraphics/1455939-cgbitmapcontextcreate/ say
and picWidth * sizeof(jint), is bytes per row. |
If the scale is 2 then we will need 4 ints overall, but only 2 ints per row, since we will have 2 rows.
We can for sure, I can update the fix. |
FWIW there's a related problem on Linux where the size of the captured area is scaled down in the native code, which in case of capturing just one pixel might end up being 0 for scales 300%+. I just filed JDK-8280861 for that and the issue with coordinates scaling on Linux. |
It looks similar to what is done on macOS where two types of coordinates are needed: the user's space to pass to the GTK and the device space to create storage for the pixels. Be careful to not desync them as we did on macOS here. |
You are absolutely right! in case of linux we have the same bug when gtk is used. =( |
I have added an additional check for the parameters of the native method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, missed this update.
/integrate |
Going to push as commit eff5daf.
Your commit was automatically rebased without conflicts. |
In JDK 9 the native code for the robot class was reworked to get an access to the HiDPI quality screenshots. So we allocate the data storage for the HiDPI quality and then request the best quality from the macOS.
It works fine if the user request the screenshot of some area, since we properly scale this area. Unfortunately it does not work well if the user request only one pixel, in this case we allocate the array of one element and does not multiply the size by the scale, so if the system scale is 2 then the macOS returns the 2x2 pixels, which does not fit properly to the array of one element. This can be checked by the Xcheck:jni option which produce fatal error in this case.
Solution is to allocate the storage of the proper size 1 * scale * 1 * scale
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/5864/head:pull/5864
$ git checkout pull/5864
Update a local copy of the PR:
$ git checkout pull/5864
$ git pull https://git.openjdk.java.net/jdk pull/5864/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 5864
View PR using the GUI difftool:
$ git pr show -t 5864
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/5864.diff