Menu

#334 libd2d1 GetSize()

open
nobody
5
2015-08-14
2013-03-31
No

Direct 2D sample: http://msdn.microsoft.com/en-us/library/windows/desktop/ff819062\(v=vs.85).aspx
Compiles and runs with Visual Studio 2012.
Program compiles but fails to run (Received a SIGSEGV: Segmentation fault) with GCC mingw-w64
Fails at BeginPaint(HWND hWnd,LPPAINTSTRUCT lpPaint);
Compiled with:
gcc version 4.8.0 (GCC)
mingw-w64 - revision 5706
See attached makefile
code url: http://go.microsoft.com/fwlink/?LinkId=195524
Running windows8 pro

Discussion

  • Richard Ebel

    Richard Ebel - 2013-03-31

    makefile

     
  • Richard Ebel

    Richard Ebel - 2013-03-31

    header

     
  • Richard Ebel

    Richard Ebel - 2013-03-31

    code

     
  • Richard Ebel

    Richard Ebel - 2013-03-31
    • summary: libd2d1 BeginPaint --> libd2d1 GetSize()
     
  • Richard Ebel

    Richard Ebel - 2013-03-31

    Actually fails because GetSize() returns an invalid client area size {width = 5.28816768e-037, height = 0}

     
  • Jonathan Yong

    Jonathan Yong - 2013-03-31

    The LPPAINTSTRUCT in mingw-w64 is probably buggy, can you compare the struct sizes in MSVC?
    sizeof(*lpPaint);

     
  • Richard Ebel

    Richard Ebel - 2013-04-02

    LPPAINTSTRUCT is 8 bytes for both MSVC and Mingw64

     
  • Richard Ebel

    Richard Ebel - 2013-04-02

    PAINTSTRUCT is 72 bytes for both MSVC and Mingw64

     
  • Jonathan Yong

    Jonathan Yong - 2013-04-03

    Hi,

    How is the structure initialized? Can you also do a binary compare via memcmp?
    Lastly, do compare with offsetof for each known struct member in PAINTSTRUCT.

    The BeginPaint call itself should be exactly identical to MSVC.

    Failing that, can you post the code itself AND the link command used? I might shift the blame to the HWND part if the struct part was identical.

     
  • Richard Ebel

    Richard Ebel - 2013-04-03

    MSVC Paint Structure

     
  • Richard Ebel

    Richard Ebel - 2013-04-03

    Mingw64 Paint Structure

     
  • Richard Ebel

    Richard Ebel - 2013-04-03

    On Paint Debug Window

     
  • Richard Ebel

    Richard Ebel - 2013-04-03

    BeginPaint(m_hwnd, lpps); fills in the paint structure.

    pRenderTarget->BeginDraw(); fails with Mingw64.

    See attached files for the MSVC paint structure, the Mingw64 paint structure, and the Mingw64 Debug window.

     
  • Jonathan Yong

    Jonathan Yong - 2013-04-03

    I don't mean that you should check the values, I mean the offsets of the struct members.

    From mingw-w64, you cam make a program that simply prints:
    printf("%d\n",offsetof(PAINTSTRUCT,hdc);
    printf("%d\n",offsetof(PAINTSTRUCT,fErase);
    and so on, do the same for MSVC, they should be identical.

     
  • Jonathan Yong

    Jonathan Yong - 2013-04-03

    Likewise, you may need to check ID2D1Factory and related structs.

     
  • Richard Ebel

    Richard Ebel - 2013-04-04
     
  • Richard Ebel

    Richard Ebel - 2013-04-04

    Interface not initialized

     
  • Richard Ebel

    Richard Ebel - 2013-04-04

    printf("%d\n",offsetof(PAINTSTRUCT,hdc); = 0
    printf("%d\n",offsetof(PAINTSTRUCT,fErase); = 8
    The same for both MSVC and Mingw64
    I'm not sure about the offsets for ID2D1Factory and related structs.
    I have attached the debug output for MSVC and Mingw64 at the point where the interfaces are instantiated.
    see added files below

     
  • Jonathan Yong

    Jonathan Yong - 2013-04-05

    Can you test the offset for GetSize in ID2D1HwndRenderTarget too?
    All you can do now is to backtrack from the segfault and verify all the structures involved has the same alignment/offset.

    Sorry I couldn't reply earlier.

     
  • dkl

    dkl - 2015-08-14

    There is a gcc bug report about this:
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64384

     
    • Ruslan Garipov

      Ruslan Garipov - 2017-07-19

      callee_pop_aggregate_return (number) doesn't fix the issue for me.

      So, is there any solution exists for Direct2D's stdcall functions? Or the issue is unfixable for GCC?

       
      • dkl

        dkl - 2017-07-19

        It appears to be related to whether an aggregate is returned in registers or in memory, not related to who is responsible for popping the hidden pointer for an aggregate returned in memory, which is probably why the callee_pop_aggregate_return attribute doesn't help. Unfortunately I don't know a good work-around with gcc, but if there is one I'd like to know too.

        As noted in that gcc bug report, it looked to me like gcc uses an "incorrect" ABI, i.e. incompatible to Windows' d2d1.dll, for functions like GetSize(). However, the MS compiler itself was inconsistent between C and C++ programs calling GetSize() (C++ worked, C didn't), so it's somewhat unclear what the "correct" ABI is.

         
        • Ruslan Garipov

          Ruslan Garipov - 2017-07-19

          Kai Tietz gave me the following link as a possible workaround: MinGW binary crashes, but msvc6's one works fine in function when returning aggregate value.

          Actually, after I had got the cause of the issue in my own code comparing assembly outputs of GCC and Intel C++ compilers, I started to think about such solution by myself, but I have decided it's a crazy fix and started to google. But it turned out to be "acceptable".

           

Log in to post a comment.