On Tue, 6 Jun 2023 16:07:53 GMT, Alexey Ivanov <[email protected]> wrote:

> **Problem description**
> 
> If you grab the thumb of the scroll bar of `ScrollPane` and drag it slowly 
> and continuously up and down, you'll notice the UI stops rendering correctly: 
> the child component of the scroll pane will render on the left of the frame 
> itself, the inside of the scroll pane will be filled with the background 
> color of its child component.
> 
> **Root cause**
> 
> AWT calls the 
> [`::SetScrollInfo`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setscrollinfo)
>  function on EDT when AWT processes scroll bar tracking events. This Windows 
> API is not thread-safe, calling this function on an incorrect thread leads to 
> leaking GDI objects.
> 
> When the process reaches the limit on the number of GDI objects, it cannot 
> create new GDI objects, which results in rendering issues.
> 
> **Fix**
> 
> To resolve the problem, I modified the code so that `::SetScrollInfo` and 
> [`::GetScrollInfo`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getscrollinfo)
>  are always called on the toolkit thread, all AWT components are created on 
> the toolkit thread.
> 
> An automatic test is provided. The test scrolls the vertical scroll bar up 
> and down. Then the test takes a screenshot. When the bug is reproduced, the 
> robot cannot create new GDI objects to capture the screenshot and it throws 
> `OutOfMemoryError`.

src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp line 704:

> 702:     gos->orient = orient;
> 703: 
> 704:     return 
> static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().InvokeFunction(

So this needs to block until the toolkit thread can process this and return, 
but since its
directly called from Java (ie we are in a JNI method) I think this is likely 
fine.

src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp line 745:

> 743:     ssps->y = y;
> 744: 
> 745:     
> AwtToolkit::GetInstance().InvokeFunctionLater(AwtScrollPane::_SetScrollPos, 
> ssps);

Whereas in the _GetOffset case above, you clearly need to wait until the result 
is returned - I guess
you didn't see a need to block here ? Or the case below ?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/14338#discussion_r1220105799
PR Review Comment: https://git.openjdk.org/jdk/pull/14338#discussion_r1220107433

Reply via email to