Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (768)
Games in Android Showcase (230)
games submitted by our members
Games in WIP (854)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Extreme slowdown  (Read 3169 times)
0 Members and 1 Guest are viewing this topic.
Offline numknuf

Senior Newbie




bompi


« Posted 2006-10-12 23:27:32 »

I have a Swing application with a GLCanvas. In this canvas I render some simple geometry using a raycasting shader.
This shader is slow so the output is limited to around 2 fps, with no CPU usage. The output speed is no problem,
but the slowdown of the Swing part of my application is not acceptable.

I believe this is because OpenGL is blocking in the EvenDispatch. Are there any workarounds or solutions?
I've tried all the command line options available in the Threading class, but none of them seems to work.
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #1 - Posted 2006-10-13 04:39:21 »

What platform and graphics card are you using?

In general JOGL performs all of its work on the event dispatch thread due to multithreading-related stability issues on all platforms. If you are on the Windows platform you should be able to get some more parallelism out of your app by specifying -Dopengl.1thread=false on the command line. This won't help on X11 platforms by default because due to how and when GLX tokens are sent with various vendors' OpenGL drivers there is some locking which needs to occur which will prevent the event dispatch thread from processing events when your Animator calls GLCanvas.display(). You can try disabling this behavior with -Djogl.GLContext.optimize on the command line but you're on your own at that point. There are known issues with using this flag and ATI's proprietary Linux drivers.

If you know that your GUI isn't changing (components being added/removed at random times), you can also control the threading behavior of your application manually using the GLContext and GLDrawable APIs explicitly. The caveat about the X11 locking behavior still applies in this case, but you may be able to make the OpenGL context once on one thread and leave it current for the lifetime of the application, which may simplify things for you.
Offline numknuf

Senior Newbie




bompi


« Reply #2 - Posted 2006-10-13 07:19:33 »

Currently I'm using Windows with NVidia and ATI. And I expect to use Linux soon as well,
but if I can get it to work on Windows I'm happy. I tried setting the flags you mentioned and they
didn't seem to have any effect. I don't add or remove GUI components at random,
but I do some Graphics painting in another component.

I don't think I understood the part about "making the context in one thread and leave it current...".
It sounds like what I want: start a rendering thread that just works independently of Swing.
But I'm not sure of how to do that, or what the limitations of that is.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline numknuf

Senior Newbie




bompi


« Reply #3 - Posted 2006-10-13 19:10:08 »

Since the general speed of my application is so low anyway I thought I maybe use a PBuffer instead, so I did this:

1  
2  
GLPbuffer glPbuffer = GLDrawableFactory.getFactory().createGLPbuffer(glCapabilities, null, width, height, null);
glPbuffer.addGLEventListener(this);


and created a custom Animator that just did glPbuffer.display() but the speed increase was minimal.
Shouldn't this way avoid the AWT pipeline? 

Part of the problem is that it is not just the GUI of my application that is slow, the whole OS is slow.
Offline numknuf

Senior Newbie




bompi


« Reply #4 - Posted 2006-10-13 23:01:55 »

I've created an example to illustrate the performance hit on the OS even though the application isn't using any CPU resources.

Please try it yourself and tell me if you get the same results or if I'm doing something wrong.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
import com.sun.opengl.util.GLUT;

import javax.media.opengl.*;
import static javax.media.opengl.GL.*;
import javax.media.opengl.glu.GLU;
import javax.swing.*;
import java.awt.*;

/**
 * Example to illustrate the choppyness of the OS while the application is not using CPU resources.
 */

public class SlowDownTest implements GLEventListener {
    private String[] vertexShader = new String[]{
            "varying vec3 normal;\n" +
                    "void main() {\n" +
                    "   normal = normalize(gl_Normal);\n" +
                    "   gl_Position = ftransform();\n" +
                    "}"};
    private String[] fragmentShader = new String[]{
            "varying vec3 normal;\n" +
                    "void main (void) {\n" +
                    "   vec3 N = normalize(normal);\n" +
                    "   vec4 final_color = vec4(0, 0, 0, 0);\n" +
                    "   float f = 0.0;\n" +
                    "   for(int i = 0; i < 220; i++) {\n" +
                    "       for(int j = 0; j < 150; j++) {\n" +
                    "          f = f + float(i) / float(j + 1);\n" +                  
                    "       }\n" +
                    "   }\n" +
                    "   for(int i = 0; i < 220; i++) {\n" +
                    "       for(int j = 0; j < 150; j++) {\n" +
                    "          final_color.rgb = N.xyz * 0.5 + 0.5;\n" +
                    "          final_color.a = 1.0 * f;\n" +
                    "       }\n" +
                    "   }\n" +
                    "   gl_FragColor = final_color;\n" +
                    "}"};
    private int width = 500;
    private int height = 400;
    private GLCanvas glCanvas;

    private float stepSize = (float) (Math.PI / 16);
    private float rot = 0;
    private int program;

    public SlowDownTest() {
        GLCapabilities glCapabilities = new GLCapabilities();
        glCanvas = new GLCanvas(glCapabilities);

        Dimension size = new Dimension(width, height);
        glCanvas.setSize(size);
        glCanvas.setPreferredSize(size);
        glCanvas.setMinimumSize(size);
        glCanvas.addGLEventListener(this);

        JFrame frame = new JFrame("Slowdown Shader Test");
        frame.getContentPane().add(glCanvas);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        CustomAnimator animator = new CustomAnimator();
        animator.start();
    }

    public void init(GLAutoDrawable glAutoDrawable) {
        GL gl = glAutoDrawable.getGL();

        gl.glClearColor(0, 0, 0, 1);
        gl.glEnable(GL_DEPTH_TEST);
        gl.glShadeModel(GL_SMOOTH);
        gl.glEnable(GL_NORMALIZE);
        gl.glFrontFace(GL_CCW);

        gl.glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
        gl.glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
        gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        createShaders(gl);
    }

    private void createShaders(GL gl) {
        System.out.println("Compiling Shaders.");
        int vertexShaderObject = gl.glCreateShader(GL_VERTEX_SHADER);
        int fragmentShaderObject = gl.glCreateShader(GL_FRAGMENT_SHADER);

        program = gl.glCreateProgram();

        gl.glShaderSource(vertexShaderObject, vertexShader.length, vertexShader, null);
        gl.glShaderSource(fragmentShaderObject, fragmentShader.length, fragmentShader, null);
        gl.glAttachShader(program, vertexShaderObject);
        gl.glAttachShader(program, fragmentShaderObject);

        gl.glCompileShader(vertexShaderObject);
        gl.glCompileShader(fragmentShaderObject);

        gl.glLinkProgram(program);
        System.out.println("Compiled!");
    }

    public void display(GLAutoDrawable glAutoDrawable) {
        GL gl = glAutoDrawable.getGL();
        gl.glClearColor(0, 0, 0, 1);

        gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        gl.glPushMatrix();

        gl.glTranslatef(0, 0, -3);
        gl.glRotatef(rot, 0, 1, 0);

        gl.glUseProgram(program);

        GLUT glut = new GLUT();
        glut.glutSolidTeapot(1);

        gl.glUseProgram(0);
        gl.glPopMatrix();

        rot += stepSize;
    }

    public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) {
        GL gl = glAutoDrawable.getGL();
        gl.glViewport(x, y, width, height);

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();

        GLU glu = new GLU();
        glu.gluPerspective(60, (float) width / height, 0.1f, 1000f);
        gl.glMatrixMode(GL.GL_MODELVIEW);
    }

    public void displayChanged(GLAutoDrawable glAutoDrawable, boolean b, boolean b1) {
    }

    public static void main(String[] args) {
        SlowDownTest test = new SlowDownTest();
    }

    public class CustomAnimator implements Runnable {
        private boolean running = true;
        private Thread thread = null;

        public CustomAnimator() {
            thread = new Thread(this);
        }

        public synchronized void start() {
            thread.start();
        }

        public synchronized void stop() {
            running = false;
            while (thread != null) {
                //Make sure run completes
                try {
                    wait();
                } catch (InterruptedException ie) {
                    //
                }
            }
        }

        public void run() {
            while (running) {
                if (glCanvas != null) {
                    glCanvas.display();
                } else {
                    running = false;
                }
                try {
                    Thread.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (CustomAnimator.this) {
                thread = null;
                CustomAnimator.this.notify();
            }
        }
    }
}


PS: Increase or decrease the number of iterations in the fragment shader to get the right effect.  Grin
Offline numknuf

Senior Newbie




bompi


« Reply #5 - Posted 2006-10-16 08:43:05 »

I've checked if the same problem occurs with a C++ program and to my surprise it did.
So it is not a JOGL problem but a driver/general OpenGL problem.
Offline CommanderKeith
« Reply #6 - Posted 2006-10-16 09:43:38 »

This is a threading problem, is that true?

So your slow operation is done on the EDT, which gums up the UI.

Why can't your slow OGL operation be rendered off the EDT in its own low-priority thread onto a separate buffer which is then copied to the screen by the EDT?

Keith
PS: I know nothing about J/OGL but a little about the EDT


Offline numknuf

Senior Newbie




bompi


« Reply #7 - Posted 2006-10-16 10:02:27 »

Actually my conclusion is that it won't matter if I do that since the whole computer is slowed down.
If you can try the example you will see that it is more than the UI that is slow.
Offline cylab

JGO Kernel


Medals: 185



« Reply #8 - Posted 2006-10-16 10:06:08 »

Are you sure the Shader is not executed by the CPU due to feature-emulation? This would explain the slowdonw of the whole system.

Mathias - I Know What [you] Did Last Summer!
Offline numknuf

Senior Newbie




bompi


« Reply #9 - Posted 2006-10-16 10:17:11 »

The GLSL on my ATI card says that both the Vertex and Fragment shader will run in hardware.
In addition there is almost no CPU usage during rendering.
The same type of test was done using C++ with the same results.

(I have an ATI x1600 and Nvidia Geforce 7900 GT so there shouldn't be any features missing.  Smiley )
Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (1340 views)
2018-06-10 19:43:48

EgonOlsen (1229 views)
2018-06-10 19:43:44

EgonOlsen (939 views)
2018-06-10 19:43:20

DesertCoockie (1380 views)
2018-05-13 18:23:11

nelsongames (1112 views)
2018-04-24 18:15:36

nelsongames (1374 views)
2018-04-24 18:14:32

ivj94 (2120 views)
2018-03-24 14:47:39

ivj94 (1269 views)
2018-03-24 14:46:31

ivj94 (2286 views)
2018-03-24 14:43:53

Solater (808 views)
2018-03-17 05:04:08
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!