knute
Posts: 397
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas
Contact: Website

OpenGL and Java?

Sat Feb 09, 2019 6:31 pm

Anybody know how or if it is even possible to get Java to use the OpenGL pipeline? I'm running current up to date raspbian with the OpenGL desktop driver enabled. Java is latest openjdk version 8.

Code: Select all

pi@raspberrypi3B-1:~ $ java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13)
OpenJDK Client VM (build 25.181-b13, mixed mode)
When I run a program and enable the OpenGL pipeline it says that it is enabled but doesn't draw anything on the screen and gives a long error message:

Code: Select all

pi@raspberrypi3B-1:~/bin $ java -Dsun.java2d.opengl=True DrawFast
libGL error: MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
OpenGL pipeline enabled for default config on screen 0
Failed to register allocate:
BLOCK 0:
  0 S   0       frag_w t0
  1 S   1       fmul t1, v0, t0
  2 S   2 E   1 vary_add_c t2, t1
  2 S   3       fmul t3, v1, t0
  3 S   4 E   3 vary_add_c t4, t3
  3 S   5       fmul t5, v2, t0
  4 S   6 E   5 vary_add_c t6, t5
  4 S   7       fmul t7, v3, t0
  5 S   8 E   7 vary_add_c t8, t7
  5 S   9       fmul t9, v4, t0
  6 S  10 E   9 vary_add_c t10, t9
  6 S  47       fmul t47, t10, u0
  7 S  50       rot_mul t50, t47, 0x0000003e (0.000000)
  8 S  52 E  50 fsub t52, t50, t47
  8 S  49       rot_mul t49, t47, 0x00000032 (0.000000)
  9 S  53 E  47, E  49 fsub t53, t47, t49
  8             and.sf null, elem0, 1
  8 S  34       rot_mul t34, t10, 0x0000003f (0.000000)
  9 S  36 E  34 fsub t36, t34, t10
  9 S  33       rot_mul t33, t10, 0x00000031 (0.000000)
 10 S  37 E  33 fsub t37, t10, t33
 10 S  38 E  37 mov t38, t37
 10       E  36 mov.zs t38, t36
  9 S  11       fmul t11, v5, t0
 10 S  12 E  11 vary_add_c t12, t11
 10 S  48       fmul t48, t12, u1
 11 S  57       rot_mul t57, t48, 0x0000003e (0.000000)
 12 S  59 E  57 fsub t59, t57, t48
 12 S  56       rot_mul t56, t48, 0x00000032 (0.000000)
 13 S  60 E  48, E  56 fsub t60, t48, t56
 12 S  41       rot_mul t41, t12, 0x0000003f (0.000000)
 13 S  43 E  41 fsub t43, t41, t12
 13 S  40       rot_mul t40, t12, 0x00000031 (0.000000)
 14 S  44 E  40 fsub t44, t12, t40
 14 S  45 E  44 mov t45, t44
 14       E  43 mov.zs t45, t43
 13 S  17       fmul t17, v8, t0
 14 S  18 E  17 vary_add_c t18, t17
 14 S 101       fmul t101, t18, u2
 15 S 104       rot_mul t104, t101, 0x0000003e (0.000000)
 16 S 106 E 104 fsub t106, t104, t101
 16 S 103       rot_mul t103, t101, 0x00000032 (0.000000)
 17 S 107 E 101, E 103 fsub t107, t101, t103
 16 S  54 E  53 mov t54, t53
 16             and.sf null, elem0, 2
 16       E  52 mov.zs t54, t52
 15 S  61 E  60 mov t61, t60
 15       E  59 mov.zs t61, t59
 14 S  19 E   0 fmul t19, v9, t0
 14 S  20 E  19 vary_add_c t20, t19
 14 S 102       fmul t102, t20, u3
 15 S 111       rot_mul t111, t102, 0x0000003e (0.000000)
 16 S 113 E 111 fsub t113, t111, t102
 16 S 110       rot_mul t110, t102, 0x00000032 (0.000000)
 17 S 114 E 102, E 110 fsub t114, t102, t110
 16 S  88       rot_mul t88, t18, 0x0000003f (0.000000)
 17 S  90 E  88 fsub t90, t88, t18
 17 S  87       rot_mul t87, t18, 0x00000031 (0.000000)
 18 S  91 E  87 fsub t91, t18, t87
 18 S  92 E  91 mov t92, t91
 18             and.sf null, elem0, 1
 18       E  90 mov.zs t92, t90
 17 S  95       rot_mul t95, t20, 0x0000003f (0.000000)
 18 S  97 E  95 fsub t97, t95, t20
 18 S  94       rot_mul t94, t20, 0x00000031 (0.000000)
 19 S  98 E  94 fsub t98, t20, t94
 19 S  99 E  98 mov t99, t98
 19       E  97 mov.zs t99, t97
 18 S  63       fadd t63, t38, t54
 19 S  65 E  63 fmul t65, t63, 0.500000
 19 S  67 E  10, E  65 fsub t67, t10, t65
 18 S  64       fadd t64, t45, t61
 19 S  66 E  64 fmul t66, t64, 0.500000
 19 S  68 E  12, E  66 fsub t68, t12, t66
 18 S 115 E 114 mov t115, t114
 18             and.sf null, elem0, 2
 18       E 113 mov.zs t115, t113
 17 S 108 E 107 mov t108, t107
 17       E 106 mov.zs t108, t106
 16 S  70 E  45 fadd t70, t68, t45
 16 S  74       fadd t74, t68, t61
 17 S  78 E  61 fadd t78, t70, t61
 17 S  72       fmin t72, t68, t70
 18 S  82 E  68, E  70 fmax t82, t68, t70
 17 S  69 E  38 fadd t69, t67, t38
 17 S  73       fadd t73, t67, t54
 18 S  77 E  54 fadd t77, t69, t54
 18 S  71       fmin t71, t67, t69
 19 S  81 E  67, E  69 fmax t81, t67, t69
 18 S  83 E  81 fmax t83, t81, t73
 18 S  75 E  71, E  73 fmin t75, t71, t73
 17 S  84 E  82 fmax t84, t82, t74
 17 S  76 E  72, E  74 fmin t76, t72, t74
 16 S 117       fadd t117, t92, t108
 17 S 119 E 117 fmul t119, t117, 0.500000
 17 S 121 E  18, E 119 fsub t121, t18, t119
 16 S 118       fadd t118, t99, t115
 17 S 120 E 118 fmul t120, t118, 0.500000
 17 S 122 E  20, E 120 fsub t122, t20, t120
 16 S  80 E  76 fmin t80, t76, t78
 16 S  86 E  78, E  84 fmax t86, t84, t78
 15 S  79 E  75 fmin t79, t75, t77
 15 S  85 E  77, E  83 fmax t85, t83, t77
 14 S 161       fsub t161, t85, t79
 15 S 160       fsub t160, t86, t80
 16 S 162 E 160, E 161 fmul t162, t160, t161
 15 S 124 E  99 fadd t124, t122, t99
 15 S 128       fadd t128, t122, t115
 16 S 132 E 115 fadd t132, t124, t115
 16 S 126       fmin t126, t122, t124
 17 S 136 E 122, E 124 fmax t136, t122, t124
 16 S 123 E  92 fadd t123, t121, t92
 16 S 127       fadd t127, t121, t108
 17 S 131 E 108 fadd t131, t123, t108
 17 S 125       fmin t125, t121, t123
 18 S 135 E 121, E 123 fmax t135, t121, t123
 17 S 137 E 135 fmax t137, t135, t127
 17 S 129 E 125, E 127 fmin t129, t125, t127
 16 S 138 E 136 fmax t138, t136, t128
 16 S 130 E 126, E 128 fmin t130, t126, t128
 15 S 145 E  85 fmax t145, t85, 0
 15 S 141 E  79 fmax t141, t79, 0
 15 S 142 E 141 fmin t142, t141, 1.000000
 15 S 146 E 145 fmin t146, t145, 1.000000
 15 S 158 E 142, E 146 fsub t158, t146, t142
 14 S 147 E  86 fmax t147, t86, 0
 14 S 143 E  80 fmax t143, t80, 0
 14 S 144 E 143 fmin t144, t143, 1.000000
 14 S 148 E 147 fmin t148, t147, 1.000000
 14 S 157 E 144, E 148 fsub t157, t148, t144
 13 S 159 E 157, E 158 fmul t159, t157, t158
 12 S 134 E 130 fmin t134, t130, t132
 12 S 140 E 132, E 138 fmax t140, t138, t132
 11 S 133 E 129 fmin t133, t129, t131
 11 S 139 E 131, E 137 fmax t139, t137, t131
 10 S 172       fsub t172, t139, t133
 11 S 171       fsub t171, t140, t134
 12 S 173 E 171, E 172 fmul t173, t171, t172
 11 S 153 E 139 fmax t153, t139, 0
 11 S 149 E 133 fmax t149, t133, 0
 11 S 150 E 149 fmin t150, t149, 1.000000
 11 S 154 E 153 fmin t154, t153, 1.000000
 11 S 169 E 150, E 154 fsub t169, t154, t150
 10 S 155 E 140 fmax t155, t140, 0
 10 S 151 E 134 fmax t151, t134, 0
 10 S 152 E 151 fmin t152, t151, 1.000000
 10 S 163       rcp t163, t162
 11 S 156 E 155 fmin t156, t155, 1.000000
 11 S 168 E 152, E 156 fsub t168, t156, t152
 10 S 170 E 168, E 169 fmul t170, t168, t169
  9 S 164 E 162 fmul t164, t162, t163
  9 S 174       rcp t174, t173
 10 S 165 E 164 fsub t165, 2.000000, t164
 10 S 166 E 163, E 165 fmul t166, t163, t165
  9 S 167 E 159, E 166 fmul t167, t159, t166
  8 S 175 E 173 fmul t175, t173, t174
  8 S 176 E 175 fsub t176, 2.000000, t175
  8 S 177 E 174, E 176 fmul t177, t174, t176
  7 S 178 E 170, E 177 fmul t178, t170, t177
  6 S 179 E 167, E 178 fsub t179, t167, t178
  5 S 190 E   2 fmul t190.8a, t2, t179
  5       E   4 fmul t190.8b, t4, t179
  4       E   6 fmul t190.8c, t6, t179
  3 S 183 E   8, E 179 fmul t183, t8, t179
  2             mmov t190.8d, t183
  2 S 193 E 183 mmov t193.8888, t183
  2 S 194 E 193 not t194, t193
  2 S 184       tlb_color_read t184
  3 S 195 E 194 v8muld t195, t184, t194
  3 S 196 E 190, E 195 v8adds t196, t190, t195
  2 S 198 E 184 and t198, t184, u4 (0xff000000 / -170141183460469231731687303715884105728.000000)
  2 S 197 E 196 and t197, t196, u5 (0x00ffffff / 0.000000)
  2       E 197, E 198 or tlb_c, t197, t198
Running glxgears works fine but it also gives the first part of the error message:

Code: Select all

pi@raspberrypi3B-1:~/bin $ glxgears
libGL error: MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
Running synchronized to the vertical refresh.  The framerate should be
approximately the same as the monitor refresh rate.
305 frames in 5.0 seconds = 60.934 FPS
Thanks!

User avatar
rpiMike
Posts: 721
Joined: Fri Aug 10, 2012 12:38 pm
Location: Cumbria, UK

Re: OpenGL and Java?

Sat Feb 09, 2019 6:57 pm

Might be helpful to include your java code.

knute
Posts: 397
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas
Contact: Website

Re: OpenGL and Java?

Mon Feb 11, 2019 12:04 am

rpiMike wrote:
Sat Feb 09, 2019 6:57 pm
Might be helpful to include your java code.
Code shouldn't make any difference but here is what I usually use to test whether the OpenGL pipeline is actually working.

Code: Select all

import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;

/**
 * Demonstrates a method to do fast and smooth drawing for animation.
 *
 * The component drawing is done on the Event Dispatch Thread by wrapping the
 * call to JComponent#paintImmediately in EventQueue#invokeAndWait.  This
 * technique is very smooth but not nearly as fast as using a VolatileImage
 * or a BufferStrategy to do the drawing with.
 * <p>
 * Try commenting out the EventQueue#invokeAndWait and replacing it with the
 * Component#repaint method.  Component#repaint schedules repainting on the
 * Event Dispatch Thread but will also allow write combining.  At some point
 * as the display rate is increased the drawing will start to jerk or shake as
 * the Component#repaint method discards some of the earlier drawing calls for
 * the most recent one.
 * <p>
 * There are two timing gate methods, smoothGate and lowResourceGate.
 * Both are used to control the drawing rate by adding a delay to the
 * animation thread.  Try running this example with and without a timing gate.
 * <p>
 * The smoothGate method loops as fast as the processor will allow until the
 * time delay for the desired frame rate has elapsed.  On a modern computer
 * with many processors and cores there is still adequate processor power
 * available to run other programs even if one of the cores is saturated.
 * <p>
 * The lowResourceGate method loops around a Thread#sleep call and as a
 * result uses considerably less processor power than the smoothGate method.
 * The trade off is that the lowResourceGate method is not a consistent as
 * the smoothGate method and requires some tweaking to get the frame rates
 * accurate.  This is caused by the unpredictability of Thread#sleep.
 *
 * @author  Knute Johnson
 *
 * @see DrawVolatile
 * @see DrawStrategy
 */
public class DrawFast extends JComponent implements Runnable {
    /** Display increment angle in radians */
    private static final double ANGLE_INCREMENT = 0.0005;

    /** Animation thread */
    private final Thread thread;

    /**
     * Animation thread control flag.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
     */
    private volatile boolean runFlag;

    /** Timer for rate display */
    private final java.util.Timer timer;

    /** TimerTask for rate display */
    private final java.util.TimerTask timerTask;

    /**
     * Current drawing angle in radians
     *
     * This variable is thread constrained to the animation thread.
     */
    private double radians;

    /**
     * Frame count for rate display.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
     */
    private volatile long frameCount;

    /**
     * Frame rate for rate display.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
     */
    private volatile double frameRate;

    /**
     * Constructs the component, sets its preferred size, creates the animation
     * thread, creates a Timer and TimerTask to update the frame rate display.
     */
    public DrawFast() {
        // give the component a starting size
        setPreferredSize(new Dimension(400,300));

        // create the animation thread
        thread = new Thread(this,"Animation Thread");

        // create the animation timer as daemon so we don't have to explicitly
        // stop it when the program ends
        timer = new java.util.Timer("Rate Display Timer",true);

        // updates the variable frameRate for the rate display
        timerTask = new java.util.TimerTask() {
            // time of last frame rate update
            long then = 0;
            // frame count of last frame rate update
            long lastCount = 0;

            @Override public void run() {
                long now = System.nanoTime();
                long frames = frameCount - lastCount;
                double duration = (now - then) / 1000000000.0;
                then = now;
                lastCount = frameCount;
                frameRate = frames / duration;
            }
        };
    }

    /**
     * Starts the animation thread and the rate display timer
     */
    public void start() {
        runFlag = true;
        thread.start();
        timer.scheduleAtFixedRate(timerTask,0,1000);
    }

    /**
     * The animation thread adjusts animation values, and calls
     * JComponent#paintImmediately to draw the updated image.
     */
    public void run() {
        // the last time the gate was opened
        long then = 0;

        while (runFlag) {
            // adjust display values
            radians += ANGLE_INCREMENT;
            ++frameCount;

            // delay get to control frame rate
//            then = smoothGate(then,200);
//            then = lowResourceGate(then,200);

            // move the contained code to the Event Dispatch Thread and wait
            // for it to complete
            try {
                EventQueue.invokeAndWait(new Runnable() {
                    public void run() {
                        // draw the component now
                        paintImmediately(getBounds());
                    }
                });
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            } catch (InvocationTargetException ite) {
                ite.printStackTrace();
            }
            
            // try commenting out the EventQueue#invokeAndWait code above and
            // replacing it with Component#repaint.  See the class notes above
            // for a discussion of this topic.

//            repaint();
        }
    }

    /**
     * Stops the animation thread
     */
    public void stop() {
        runFlag = false;
    }

    /**
     * All drawing is done here.
     *
     * @param   g2D     the Graphics object
     */
    @Override public void paintComponent(Graphics g2D) {
        int w = getWidth();
        int h = getHeight();

        // the passed in Graphics is actually a Graphics2D
        Graphics2D g = (Graphics2D)g2D;

        // turn on anti-aliasiang to get smooth drawing edges and text
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
         RenderingHints.VALUE_ANTIALIAS_ON);

        // fill the background with white
        g.setColor(Color.WHITE);
        g.fillRect(0,0,w,h);

        // draw the frame rate in the upper left corner of component
        g.setColor(Color.RED);
        g.drawString(String.format("%.0f fps",frameRate),5,15);

        // draw the rotating blue square
        g.setColor(Color.BLUE);
        g.rotate(radians,w/2,h/2);
        g.fillRect(w/2 - 100,h/2 - 100,200,200);
    }

    /**
     * Delay method to control the frame rate of the display.
     *
     * This method uses large amounts of processor resources but is very
     * smooth and will allow very fast frame rates to be used.
     *
     * @param   then    the time the gate was last entered, from the return
     *                  value of the previous call to this method
     * @param   fps     the desired frame rate in frames per second
     *
     * @return          the time the gate was exited, used as input to the next
     *                  call to this method
     */
    public long smoothGate(long then, long fps) {
        long now;
        while ((now = System.nanoTime()) - then < (1000000000L / fps))
            ;

        return now;
    }

    /**
     * Delay method to control the frame rate of the display.
     *
     * This method uses very little processor resources but is not very smooth
     * or very accurate in its timing.
     *
     * @param   then    the time the gate was last entered, from the return
     *                  value of the previous call to this method
     * @param   fps     the desired frame rate in frames per second
     *
     * @return          the time the gate was exited, used as input to the next
     *                  call to this method
     */
    public long lowResourceGate(long then, long fps) {
        long now;
        while ((now = System.nanoTime()) - then < (1000000000L / fps))
            try {
                Thread.sleep(0L,10000);
            } catch (InterruptedException ie) { }

        // tuned for 200 fps
        return now - 600000;
    }

    /**
     * Create the GUI and use a WindowListener to start and stop the animation
     * thread.
     *
     * @param   args    command line arguments (not used)
     */
    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                final DrawFast dF = new DrawFast();
                final JFrame frame = new JFrame("DrawFast");
                frame.addWindowListener(new WindowAdapter() {
                    // start the animation once the GUI is created
                    public void windowOpened(WindowEvent we) {
                        dF.start();
                    }
                    // stop the animation and dispose the GUI window
                    public void windowClosing(WindowEvent we) {
                        dF.stop();
                        frame.dispose();
                    }
                });
                frame.add(dF,BorderLayout.CENTER);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

knute
Posts: 397
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas
Contact: Website

Re: OpenGL and Java?

Sat Mar 02, 2019 11:59 pm

So I got it sort of working by using Alexi Shipilev's openjdk11, https://builds.shipilev.net/openjdk-jdk11/, for arm build and adding a command line switch from a Oracle document, https://docs.oracle.com/javase/8/docs/t ... ne004.html, and disabling the use of the GL_EXT_framebuffer_object extension. It still gives the:

Code: Select all

libGL error: MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
errors but so does glxgears. glxgears runs full screen at the vertical refresh rate. DrawVolatile will run at ~45 frames per second without the OpenGL pipeline and about ~100 frames per second with the OpenGL pipeline enabled and the FL_EXT_framebuffer_object extension disabled. With it enabled no drawing is done.

It would be really great to get this working in Raspbian as it would greatly improve the ability to create Java program animation.

So to test this, download Alexi Shipilev's openjdk11 for arm release version, compile the DrawVolatile.java program below, and run it with the following command line:

java -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false DrawVolatile

Setting the debug option: export J2D_TRACE_LEVEL=4 from the Oracle document gives the following output:

Code: Select all

pi@raspberrypi3B-1:~/bin $ java11 -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false DrawVolatile
[I] GLXGC_FindBestVisual: scn=0
[I] GLXGC_InitGLX
[I] OGLFuncs_OpenLibrary
[I] OGLFuncs_InitPlatformFuncs
[I] OGLFuncs_InitBaseFuncs
[I] OGLFuncs_InitExtFuncs
[I] GLXGC_InitGLX: client GLX version=1.4
[I] GLXGC_InitFBConfig: scn=0 vis=0x0
libGL error: MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
[V]   candidate fbconfigs:
[V]     id=0x1a5 db=0 alpha=0 depth=24 stencil=0 valid=true
[V]     id=0x1db db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x210 db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x246 db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1ab db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1e1 db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x216 db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x24c db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1b4 db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1ea db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x21f db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x255 db=0 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1b7 db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1ed db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x222 db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x258 db=0 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1a7 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1a9 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1dd db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1df db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x212 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x214 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x248 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x24a db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1ad db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1af db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1e3 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1e5 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x218 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x21a db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x24e db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x250 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1b5 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1b6 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1eb db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1ec db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x220 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x221 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x256 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x257 db=1 alpha=0 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1b8 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1b9 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1ee db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1ef db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x223 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x224 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x259 db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x25a db=1 alpha=0 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x18c db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1c0 db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1f6 db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x22b db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x192 db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1c6 db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1fc db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x231 db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x199 db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1cf db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x204 db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x23a db=0 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x19c db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1d2 db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x207 db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x23d db=0 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x18e db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x190 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1c2 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1c4 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1f8 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1fa db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x22d db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x22f db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x21 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x77 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1c8 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1ca db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x22 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1ff db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x233 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x235 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x19a db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x19b db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1d0 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x1d1 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x205 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x206 db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x23b db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x23c db=1 alpha=8 depth=24 stencil=0 valid=false (large depth)
[V]     id=0x19d db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x19e db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1d3 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x1d4 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x208 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x209 db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x23e db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[V]     id=0x23f db=1 alpha=8 depth=24 stencil=8 valid=false (large depth)
[I] GLXGC_FindBestVisual: chose 0x1a5 as the best visual for screen 0
[I] GLXGraphicsConfig_getGLXConfigInfo
[I] GLXGC_InitFBConfig: scn=0 vis=0x1a5
[V]   candidate fbconfigs:
[V]     id=0x1a5 db=0 alpha=0 depth=24 stencil=0 valid=true
[I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_shader=true
[I] OGLContext_IsExtensionAvailable: GL_ARB_multitexture=true
[I] OGLContext_IsExtensionAvailable: GL_ARB_texture_non_power_of_two=true
[I] OGLContext_IsExtensionAvailable: GL_ARB_texture_rectangle=true
[I] OGLContext_IsExtensionAvailable: GL_EXT_framebuffer_object=true
[I] OGLContext_IsExtensionAvailable: GL_ARB_depth_texture=true
[I] OGLContext_IsFBObjectExtensionAvailable: disabled via flag
[I] OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported
[I] OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported
[I] OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported
[I] OGLContext_IsExtensionAvailable: GL_NV_fragment_program=false
[I] OGLContext_IsExtensionAvailable: GL_ARB_fragment_program=true
[I] OGLContext_IsExtensionAvailable: GL_NV_texture_barrier=false
[I] GLXGraphicsConfig_getGLXConfigInfo: OpenGL version=2.1 Mesa 13.0.6
OpenGL pipeline enabled for default config on screen 0
and the program works faster (20% to 50%) than it does without the OpenGL pipeline enabled.

The DrawVolatile.java program:

Code: Select all

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.lang.reflect.*;
import javax.swing.*;

/**
 * Demonstrates the use of a VolatileImage to do fast drawing for animation.
 *
 * Drawing a VolatileImage to a component can be done very quickly and this
 * will allow fairly fast frame rates.  Adequate animation can be had with
 * frame rates in the 50 to 100 frames per second range.
 * <p>
 * There are two timing gate methods, smoothGate and lowResourceGate.
 * Both are used to control the drawing rate by adding a delay to the
 * animation thread.  Try running this example with and without a timing gate.
 * <p>
 * The smoothGate method loops as fast as the processor will allow until the
 * time delay for the desired frame rate has elapsed.  On a modern computer
 * with many processors and cores there is still adequate processor power
 * available to run other programs even if one of the cores is saturated.
 * <p>
 * The lowResourceGate method loops around a Thread#sleep call and as a
 * result uses considerably less processor power than the smoothGate method.
 * The trade off is that the lowResourceGate method is not a consistent as
 * the smoothGate method and requires some tweaking to get the frame rates
 * accurate.  This is caused by the unpredictability of Thread#sleep.
 *
 * @author  Knute Johnson
 *
 * @see VolatileImage
 */
public class DrawVolatile extends JComponent implements Runnable {
    /** Display increment angle in radians */
    private static final double ANGLE_INCREMENT = 0.0005;

    /** Animation thread */
    private final Thread thread;

    /**
     * Animation thread control flag.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
    */
    private volatile boolean runFlag;

    /**
     * The target image.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
    */
    private volatile VolatileImage image;

    /** Timer for rate display */
    private final java.util.Timer timer;

    /** TimerTask for rate display */
    private final java.util.TimerTask timerTask;

    /**
     * Current drawing angle in radians.
     *
     * This variable is thread constrained to the animation thread.
    */
    private double radians;

    /**
     * Frame count for rate display.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
     */
    private volatile long frameCount;

    /**
     * Frame rate for rate display.
     *
     * This variable is volatile because it is written to by one thread and
     * read by another.
     */
    private volatile double frameRate;

    /**
     * Constructs the component, registers a ComponentListener to listen for
     * resize events so the VolatileImage can be resized as well, and creates
     * a TimerTask to update the frame rate display.
     */
    public DrawVolatile() {
        // turn off double buffering since we aren't using the swing painting
        // scheme
        setDoubleBuffered(false);
        // turn off OS initiated repaints since we are doing all the painting
        // ourselves
        setIgnoreRepaint(true);

        // give the component a starting size
        setPreferredSize(new Dimension(400,300));

        // this will adjust the image size as the size of the component changes
        addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent ce) {
                image = createVolatileImage(getWidth(),getHeight());
            }
        });

        // create the animation thread
        thread = new Thread(this,"Animation Thread");
    
        // create the animation timer as daemon so we don't have to explicitly
        // stop it when the program ends
        timer = new java.util.Timer("Rate Display Timer",true);

        // update the variable frameRate
        timerTask = new java.util.TimerTask() {
            // time of last frame rate update
            long then=0;
            // frame count of last frame rate update
            long lastCount=0;

            @Override public void run() {
                long now = System.nanoTime();
                long frames = frameCount - lastCount;
                double duration = (now - then) / 1000000000.0;
                then = now;
                lastCount = frameCount;
                frameRate = frames / duration;
            }
        };
    }

    /**
     * Starts the animation thread and the rate display timer
     */
    public void start() {
        runFlag = true;
        thread.start();
        timer.scheduleAtFixedRate(timerTask,0,1000);
    }

    /**
     * The animation thread adjusts animation values, renders the drawing to
     * the VolatileImage, and then draws it on the component.
     */
    @Override public void run() {
        // the last time the gate was opened
        long then = 0;

        // might as well
        thread.setPriority(Thread.MAX_PRIORITY);

        while (runFlag) {
            // adjust display values
            radians += ANGLE_INCREMENT;
            ++frameCount;

            // delay gate to control frame rate
//            then = smoothGate(then,200);
//            then = lowResourceGate(then,200);

            // render the image
            render();

            // draw the image on the component
            do {
                int status = image.validate(getGraphicsConfiguration());
                if (status == VolatileImage.IMAGE_RESTORED) {
                    render();
                } else if (status == VolatileImage.IMAGE_INCOMPATIBLE) {
                    image = createVolatileImage(getWidth(),getHeight());
                    render();
                }

                // get the component's graphics
                Graphics g = getGraphics();
                if (g != null) {
                    // draw imag on component
                    g.drawImage(image,0,0,null);
                    // must explicitly dispose
                    g.dispose();
                }
            } while (image.contentsLost()) ;
        }
    }

    /**
     * Stops the animation thread
     */
    public void stop() {
        runFlag = false;
    }

    /**
     * Render the drawing to the VolatileImage
     */
    public void render() {
        int w = getWidth();
        int h = getHeight();

        // get the Graphics2D of the VolatileImage
        Graphics2D g = image.createGraphics();

        // turn on anti-aliasing to get smooth drawing edges and text
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
         RenderingHints.VALUE_ANTIALIAS_ON);

        // fill the background with white
        g.setColor(Color.WHITE);
        g.fillRect(0,0,w,h);

        // draw the frame rate in the upper left corner of component
        g.setColor(Color.RED);
        g.drawString(String.format("%.0f fps",frameRate),5,15);

        // draw the rotating blue square
        g.setColor(Color.BLUE);
        g.rotate(radians,w/2,h/2);
        g.fillRect(w/2 - 100,h/2 - 100,200,200);

        // must explicitly dispose
        g.dispose();
    }

    /**
     * Delay method to control the frame rate of the display.
     *
     * This method uses large amounts of processor resources but is very
     * smooth and will allow very fast frame rates to be used.
     *
     * @param   then    the time the gate was last entered, from the return
     *                  value of the previous call to this method
     * @param   frameRate     the desired frame rate in frames per second
     *
     * @return          the time the gate was exited, used as input to the next
     *                  call to this method
     */
    public long smoothGate(long then, long frameRate) {
        long now;
        while ((now = System.nanoTime()) - then < (1000000000L / frameRate))
            ;

        return now;
    }

    /**
     * Delay method to control the frame rate of the display.
     *
     * This method uses very little processor resources but is not very smooth.
     *
     * @param   then    the time the gate was last entered, from the return
     *                  value of the previous call to this method
     * @param   frameRate     the desired frame rate in frames per second
     *
     * @return          the time the gate was exited, used as input to the next
     *                  call to this method
     */
    public long lowResourceGate(long then, long frameRate) {
        long now;
        while ((now = System.nanoTime()) - then < (1000000000L / frameRate))
            try {
                Thread.sleep(0L,10000);
            } catch (InterruptedException ie) { }

        return now - 500000;
    }

    /**
     * Create the GUI and use a WindowListener to start and stop the animation
     * thread.
     *
     * @param   args    command line arguments (not used)
     */
    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                final DrawVolatile dV = new DrawVolatile();
                final JFrame frame = new JFrame("DrawVolatile");
                frame.addWindowListener(new WindowAdapter() {
                    // start the animation once the GUI is created
                    public void windowOpened(WindowEvent we) {
                        dV.start();
                    }
                    // stop the animation and dispose the GUI window
                    public void windowClosing(WindowEvent we) {
                        dV.stop();
                        frame.dispose();
                    }
                });
                frame.add(dV,BorderLayout.CENTER);
                frame.pack();
                frame.setVisible(true);
            }
        });

    }
}
[code]

User avatar
Gavinmc42
Posts: 2749
Joined: Wed Aug 28, 2013 3:31 am

Re: OpenGL and Java?

Sun Mar 03, 2019 12:57 am

The OpenGL driver is getting updated soon to 19.
Some Pi's like Gentoo64 run 18.2+, Raspbian is 13.0.6?

I play with the Mesa3D examples in Gentoo64, newer driver and 64bit quad core.
Try your code on a Gentoo64 OS.
https://www.raspberrypi.org/forums/viewforum.php?f=54

The OpenGL driver emulates OpenGL by using OpenGLES and is not a full emulation?
Lots of bugs have been fixed with Mesa 19 but it won't end up in Raspbian till probably mid year.

I pretty much gave up on Java after Oracle dropped it, er made it open.
The JavaFX version 8 was pretty good on a quad core.
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges

RichardRussell
Posts: 232
Joined: Thu Jun 21, 2012 10:48 am

Re: OpenGL and Java?

Mon Mar 04, 2019 3:16 pm

knute wrote:
Sat Mar 02, 2019 11:59 pm
libGL error: MESA-LOADER: failed to retrieve device information
In my experience this warning is always produced when using OpenGL and the VC4 driver on Raspbian. As far as I can tell it has no impact on functionality, and can be safely ignored. As you say, glxgears reports it but nevertheless runs perfectly well.

Return to “Java”