bugGNU Octave - Bugs: bug #52260, Axes appear upside down with Qt5

 
 

bug #52260: Axes appear upside down with Qt5

Submitter:  Markus Mützel <mmuetzel>
Submitted:  Sat 21 Oct 2017 06:33:33 PM UTC
   
 
Category:  Plotting with OpenGL Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Works For Me Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 01 Nov 2017 02:51:19 PM UTC, comment #18: 

For future reference and for anyone who might experience similar issues: I updated to the recently released VMWare Workstation 14 Player (was running version 12.5 before). With that new version, I no longer see the upside down axes and grid. So it definitely was a VMWare issue.

Markus Mützel <mmuetzel>
Group administrator
Sun 29 Oct 2017 01:17:27 AM UTC, comment #17: 

This seems to be a VMware's problem, not Octave's.

Rik <rik5>
Group administrator
Sat 28 Oct 2017 08:57:53 PM UTC, comment #16: 

@Dan: Sorry for taking so long. The output running the example from comment #10 with your patch is the same both with hardware and software rendering:

VW = 0 0 560 420
Mat1 = 0.015867 0.006088 0.010544 0.000000
Mat2 = 129.089779 0.000000 0.000000 0.000000


I tried some more and managed to track the error down to using stipples. With the following change I get the axes and grid at the correct position and orientation (with the default settings):

diff -r 857b553177a5 libinterp/corefcn/gl-render.cc
--- a/libinterp/corefcn/gl-render.cc        Wed Oct 25 23:22:59 2017 +0200
+++ b/libinterp/corefcn/gl-render.cc        Sat Oct 28 22:48:22 2017 +0200
@@ -862,7 +862,7 @@
 #if defined (HAVE_OPENGL)

     glColor4d (gridcolor(0), gridcolor(1), gridcolor(2), gridalpha);
-    set_linestyle (gridstyle, true, linewidth);
+    set_linestyle (gridstyle, false, linewidth);
     glBegin (GL_LINES);
     for (int i = 0; i < ticks.numel (); i++)
       {
@@ -1271,7 +1271,7 @@

     // Axes box

-    set_linestyle ("-", true, linewidth);
+    set_linestyle ("-", false, linewidth);

     glBegin (GL_LINES);


However, when I trigger using stipples for example with "set (gca, "gridlinestyle", '--')", the grid draws upside down again.
Does that mean the driver has an error?

I also see the following message every time I resize the figure:

context mismatch in svga_sampler_view_destroy


Mike seems to be right and VMWare's video driver is probably mesa-based. At least, I could find that message in the mesa sources. Right next to it, there is the following comment [1]:

         /* The SVGA3D device will generate an error (and on Linux, cause
          * us to abort) if we try to destroy a shader resource view from
          * a context other than the one it was created with.  Skip the
          * SVGA3D_vgpu10_DestroyShaderResourceView() and leak the sampler
          * view for now.  This should only sometimes happen when a shared
          * texture is deleted.
          */


So there still might be something wrong in our code?

[1] https://github.com/imirkin/mesa/blob/master/src/gallium/drivers/svga/svga_pipe_sampler.c

Markus Mützel <mmuetzel>
Group administrator
Thu 26 Oct 2017 08:55:25 PM UTC, comment #15: 

This bug was observed in a VMWare virtual machine, not AMD or Nvidia, see comment #7. The VMWare guest video driver is Mesa-based I believe.

See also comment #8, turning off accelerated graphics in the VMWare machine settings also restored the correct rendering. This setting probably forces a Mesa software driver to be used.

Mike Miller <mtmiller>
Group Member
Tue 24 Oct 2017 04:52:40 PM UTC, comment #14: 

I don't know, but if changing LIBGL_ALWAYS_SOFTWARE has an effect, it implies that the underlying libraries and drivers are listening.  In this case, the hardware mentioned was AMD, not Nvidia.  Maybe their driver pays attention to this variable.

Rik <rik5>
Group administrator
Tue 24 Oct 2017 04:42:50 PM UTC, comment #13: 

Doesn't LIBGL_ALWAYS_SOFTWARE only apply if you are using a Mesa-based implementation?  I might be mistaken, but I don't think the nvidia libGL does anything with that environment variable. 

John W. Eaton <jwe>
Group administrator
Tue 24 Oct 2017 04:16:10 PM UTC, comment #12: 

By all means, try Dan's patch and see if there is something more to discover.  But, the simplest conclusion is that there is something wrong with the HW-accelerated implementation of OpenGL that you have.  In that case, the easiest workaround is to rely on software rendering of OpenGL which tends to be more accurate, but slower.

See this comment which I wrote for bug #52266 which is another HW/SW problem

-------------------
I don't think it would be bad to set LIBGL_ALWAYS_SOFTWARE=1 permanently. You would be choosing software over hardware rendering on a permanent basis. The advantage is that the software-rendering engine is implementing the OpenGL specification more accurately than the hardware-rendering engine. The disadvantage would be performance. For most Octave plots, that shouldn't be a big deal, but if you have an application, maybe gaming or possibly CAD, that needs to draw a lot of polygons then it might be a problem. Of course, you could always arrange to either set LIBGL_ALWAYS_SOFTWARE only before running Octave. Or you could go the other way and unset the environment variable before running your graphics-intensive software.

Rik <rik5>
Group administrator
Tue 24 Oct 2017 07:04:58 AM UTC, comment #11: 

Forgot the patch...

(file #42246)

Dan Sebald <sebald>
Mon 23 Oct 2017 08:44:51 PM UTC, comment #10: 

I'm attaching a diff file that adds a few lines to print out information to stderr.  Here's what it looks like for me:


 h_axes3 = subplot (2, 2, 4);
  h_surf2 = surf (h_axes3, peaks, "LineStyle", "none");
  view (3);
  title ("Surface without lighting");

VW = 0 0 560 420
Mat1 = 1.000000 0.000000 0.000000 0.000000
Mat2 = 180.997043 0.000000 0.000000 0.000000


and I'm curious what is shown for your system (when in the mode that plots axes upside down).  To apply, try something like

patch -p1 < dump_opengl_transform_info-djs2017oct23.diff

I guess what I'm most curious about is what VW looks like and whether yours indicates 0 420 in the first two locations as opposed to 0 0.  The value back from


    glGetIntegerv (GL_VIEWPORT, vw);


is supposed to be the lower left corner.  A 0 420 would then mean that the coordinate system has 0,0 at the top left.

Notice in this line of code:


    glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);


only vw[2] and vw[3] get used.  I don't see anywhere that vw[0] and vw[1] are used.  Hence, I'm wondering if there is an inherent assumption in the Octave code that the coordinate system is bottom left 0,0.

I can't explain why ticks and annotation come out correctly if the orthographic projection is wrong.

Dan Sebald <sebald>
Mon 23 Oct 2017 06:33:03 PM UTC, comment #9: 

Good investigation.  Yeah, hypothesis 3 is out.

As to the vmware driver being the source, I'd have to guess, maybe, but probably no.  I was imagining you had some special driver for your card and it might have a bug, but that would have to be for some fly-by-night driver, wouldn't you think?  I mean, if vmware is a popular driver and gets exposure to lots of different cards and so on, such an obvious mistake as the window coordinate orientation would certainly get immediate attention.

Plus, don't we want people to use 3D acceleration if it is available?  Is 3D acceleration using hardware features?  Or is it just another type of software library extension?

Dan Sebald <sebald>
Mon 23 Oct 2017 06:21:38 PM UTC, comment #8: 

Disabling "Accelerate 3D graphics" in the VM settings also solves the issue. That might be equivalent to starting Octave with "LIBGL_ALWAYS_SOFTWARE=1 ./run-octave"?
So is it valid to conclude that this is an issue with the vmware graphics driver?

Markus Mützel <mmuetzel>
Group administrator
Mon 23 Oct 2017 05:53:40 PM UTC, comment #7: 

@Dan: Sorry for taking so long.
When I select the "Rotate" button and drag one of the upper subplots, the corresponding lower axes rotate synchronously. They do not snap in place but keep being drawn upside down. The same happens when I rotate the lower subplots: The upside down axes drawn behind the corresponding upper subplot rotate with the objects that are correctly drawn in the lower subplots.
I think that rules out option 3, does it?

I do not need to use subplots to get the upside down axes. A single axes object in a figure also draws upside down (but obviously more in the "correct place").

Could this be because I am running Ubuntu in a VM?
I see the following for "lshw -c video":

  *-display
       description: VGA compatible controller
       product: SVGA II Adapter
       vendor: VMware
       physical id: f
       bus info: pci@0000:00:0f.0
       version: 00
       width: 32 bits
       clock: 33MHz
       capabilities: vga_controller bus_master cap_list rom
       configuration: driver=vmwgfx latency=64
       resources: irq:16 ioport:1070(size=16) memory:e8000000-efffffff memory:fe000000-fe7fffff memory:c0000-dffff


I also tried to find differences between "draw_axes_boxes" and "draw_axes_planes" because the planes are appearing in the correct orientation and the boxes are not. Swapping the order in which they are drawn doesn't make a difference.
I also tried drawing one line at the edge of one of the planes in "draw_axes_planes" by adding the following lines at the end of that function:

    double black[3] = {0, 0, 0};
    glColor3dv (black);
    set_linestyle ("-");
    glBegin (GL_LINES);
    glVertex3d (xPlaneN, yPlaneN, zPlane);
    glVertex3d (xPlane, yPlaneN, zPlane);
    glEnd ();


That line appeared in the correct place. So something might be going wrong on my system when assigning ypTickN or zpTick. Will investigate further.

Markus Mützel <mmuetzel>
Group administrator
Sun 22 Oct 2017 11:02:17 PM UTC, comment #6: 

I'm writing some notes here for reference.

OpenGL can control the orientation of the coordinate system with what's called "model view".  There is a function in Octave called  setup_opengl_transformation() in gl-render.cc:


  void
  opengl_renderer::setup_opengl_transformation (const axes::properties& props)
  {
#if defined (HAVE_OPENGL)

    // setup OpenGL transformation

    Matrix x_zlim = props.get_transform_zlim ();

    xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2;
    xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2;

    Matrix x_mat1 = props.get_opengl_matrix_1 ();
    Matrix x_mat2 = props.get_opengl_matrix_2 ();

#if defined (HAVE_FRAMEWORK_OPENGL)
    GLint vw[4];
#else
    int vw[4];
#endif

    glGetIntegerv (GL_VIEWPORT, vw);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    glScaled (1, 1, -1);
    glMultMatrixd (x_mat1.data ());
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
    glMultMatrixd (x_mat2.data ());
    glMatrixMode (GL_MODELVIEW);

    glClear (GL_DEPTH_BUFFER_BIT);

    // store axes transformation data

    xform = props.get_transform ();

#else

    octave_unused_parameter (props);

    // This shouldn't happen because construction of opengl_renderer
    // objects is supposed to be impossible if OpenGL is not available.

    panic_impossible ();

#endif
  }


which deals with model view.  There are lots of commands there, but it's notable that props is passed into the routine.

The above routine is called by


  void
  opengl_renderer::draw_axes (const axes::properties& props)
  {


which also has props as an input.  The draw_axes() is called by some routine in gl2ps-print.cc (irrelevant).  It's also accessed via:


    const base_properties& props = go.get_properties ();

    if (! toolkit)
      toolkit = props.get_toolkit ();

    if (go.isa ("figure"))
      draw_figure (dynamic_cast<const figure::properties&> (props));
    else if (go.isa ("axes"))
      draw_axes (dynamic_cast<const axes::properties&> (props));


So props comes from the axes.

Going back a bit, the props info that seems pertinent is

props.get_transform_zlim ();
Matrix x_mat1 = props.get_opengl_matrix_1 ();
Matrix x_mat2 = props.get_opengl_matrix_2 ();

The matrix 1 and 2 in question are interior to axes::properties and are defined as the following in the routine update_camera():


  // Note: these matrices are a slight modified version of the regular matrices,
  // more suited for OpenGL rendering (x_gl_mat1 => light => x_gl_mat2)
  x_gl_mat1 = x_view;
  scale (x_gl_mat1, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
         zd/(zlimits(1)-zlimits(0)));
  translate (x_gl_mat1, -xo, -yo, -zo);
  x_gl_mat2 = x_viewport * x_projection;


OK, so this "light" demo does at least seem to be dependent on some specific OpenGL transformations.  Some ideas:

1) The bug-reporter's OpenGL driver has a bug.
2) Somehow x_gl_mat1 and x_gl_mat2 are incorrect, such as mixing up the view (x_gl_mat1) with the light source (x_gl_mat2).
3) Perhaps axes::properties::update_camera() is not being called prior to drawing the axes but is called prior to drawing the tick marks and annotation.  In such a scenario the x_gl_mat1 and 2 are initialized as Matrix().  Is that all zeros?  Perhaps in most cases an all-zero transformation matrix is treated like a unity-scale lower-left axis, but in the bug-reporter's case it is unity-scale upper-left.

Noting what happens when the Qt light demo plots are rotated will be helpful.  It could be an indication that view/light matrices are not valid for only the initial plot.

Dan Sebald <sebald>
Sun 22 Oct 2017 06:55:56 AM UTC, comment #5: 

Things look normal here with Qt toolkit. 

So, the tick marks and tick annotation appear in the proper location but the lines for the axes and grid are reflected about the height dimension of the window?  It sure looks that way.  The lines for the top subplots are hidden behind the axes surfaces of the bottom subplots, but there are definitely some snippets of the line still visible to indicate the axes lines are present.

Fascinating.  At first I was wondering how could this be possible.  But now that I think about it, it's not so mystifying.  In imaging and window layout it isn't uncommon for the "y" axis of the two dimensional window (not the projection) to have 0,0 in the upper left corner as opposed to the typical Cartesian coordinate system.  So, my guess is that's what is at play here.  Either there is a bug in your driver that is assuming a default of 0,0 in the upper-left corner when it shouldn't, or Octave isn't somehow initializing the coordinate system and by chance all of our drivers assume 0,0 in the lower-left corner.  But again, the tick marks and annotation are in the correct spots--so it could be that not until far into the middle of the OpenGL commands to create the plot that some action causes the coordinate system to change to 0,0 in the lower-left corner.

Could you please do the following and report back what you see?  After generating the Qt plot, there should be a "Rotate" button with a circular arrow in the menu of the plot.  Click on there and then attempt to mouse-press-then-drag and rotate the 3D plot.  Are the axes lines for that plot corrected by that action?  Or do they still continue to draw upside down?  You might try the other menu buttons such as "Axes" and "Grid".

You might have to spend some time delving into the active driver on your system, hardware card, etc.

Dan Sebald <sebald>
Sun 22 Oct 2017 01:41:45 AM UTC, comment #4: 

Or it could be hardware dependent.
I do not see axis inversion on
Qt5-5.7.1 (Fedora 26) nor on Qt5-5.9.2 (Fedora 27beta).
Hardware are slightly different though both have
entry-level AMD graphics card.

On Fedora 26 demo light 1  does not show axes on
"Patch with lightning" plot, though there are tick marks.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sat 21 Oct 2017 08:56:34 PM UTC, comment #3: 

Just checked and I have


#define HAVE_QOPENGLWIDGET 1


in my config.h as well.

I'm going to mark bug as "Works for Me", but it would be good to get a few more confirmations.  It may be that something is wrong with the 5.9.1 Qt library.

Rik <rik5>
Group administrator
Sat 21 Oct 2017 08:43:07 PM UTC, comment #2: 

I am using Qt5 version 5.9.1.
In bug #51442, Mike told me that I am using QtOpenGLWidget because HAVE_QOPENGLWIDGET is defined to 1 in my config.h. (I should have added a reference to that bug report here.)

In case this is important: All figures where rendering black for me with Qt5 until somewhen before hg id 8e034cb195f1. It was probably fixed with 59cdf06c940e. But I didn't bisect to a specific changeset yet. Can do if that helps.

Markus Mützel <mmuetzel>
Group administrator
Sat 21 Oct 2017 08:20:00 PM UTC, comment #1: 

Which version of Qt are you using?  I'm using 5.6.1 and


./run-octave -f
demo light 1


works fine.

How can I verify whether QtOpenGLWidget is getting used?

Rik <rik5>
Group administrator
Sat 21 Oct 2017 06:33:33 PM UTC, original submission:  

When compiling Octave with Qt5, the axes in figures appear upside down on-screen for me. Printed figures do not exhibit the error. See and file #42145 for the results I see for &quot;demo light 1&quot; on-screen and printed out.
This only occurs with "graphics_toolkit qt". No upside down axes with "graphics_toolkit fltk".
I also see no error when I am starting Octave with "LIBGL_ALWAYS_SOFTWARE=1 ./run-octave".

I am using Ubuntu 17.10 on an x11 session using QtOpenGLWidget.

Markus Mützel <mmuetzel>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mmuetzel (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-10-29 rik5 Open/ClosedOpen Closed
    2017-10-24 sebald Attached File- Added dump_opengl_transform_info-djs2017oct23.diff, #42246
    2017-10-21 rik5 Item GroupUnexpected Error or Warning Incorrect Result
        StatusNone Works For Me

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code