Advertisement
codeanticode

Thread blocking issue - AWT

Oct 31st, 2012
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.97 KB | None | 0 0
  1. package p5.test_awt_applet;
  2.  
  3. import java.applet.Applet;
  4. import java.awt.BorderLayout;
  5. import java.awt.Color;
  6. import java.awt.DisplayMode;
  7. import java.awt.Frame;
  8. import java.awt.GraphicsDevice;
  9. import java.awt.GraphicsEnvironment;
  10. import java.awt.Insets;
  11. import java.awt.Rectangle;
  12. import java.awt.event.KeyEvent;
  13. import java.awt.event.KeyListener;
  14. import java.awt.event.MouseEvent;
  15. import java.awt.event.MouseMotionListener;
  16. import java.awt.event.WindowAdapter;
  17. import java.awt.event.WindowEvent;
  18. import java.util.Timer;
  19. import java.util.TimerTask;
  20.  
  21. import javax.media.opengl.*;
  22. import javax.media.opengl.awt.GLCanvas;
  23.  
  24. import com.jogamp.opengl.util.AnimatorBase;
  25.  
  26. // Sample program that relies on JOGL's mechanism to handle the OpenGL context  
  27. // and rendering loop when using an AWT canvas attached to an Applet.
  28. public class MiniPApplet extends Applet implements MouseMotionListener,
  29.                                                    KeyListener {
  30.   private static final long serialVersionUID = 1L;
  31.  
  32.   /////////////////////////////////////////////////////////////
  33.   //
  34.   // Test parameters  
  35.  
  36.   public int frameRate           = 120;
  37.   public int numSamples          = 4;
  38.  
  39.   public boolean fullScreen      = false;  
  40.   public boolean useAnimator     = true;
  41.   public boolean resizeableFrame = true;
  42.  
  43.   public boolean restartCanvas   = true;
  44.   public int restartTimeout      = 100; // in number of frames.
  45.  
  46.   public boolean printThreadInfo = false;
  47.   public boolean printEventInfo  = false;
  48.  
  49.   /////////////////////////////////////////////////////////////
  50.   //
  51.   // Internal variables
  52.  
  53.   int width;
  54.   int height;
  55.  
  56.   String OPENGL_VENDOR;  
  57.   String OPENGL_RENDERER;
  58.   String OPENGL_VERSION;    
  59.   String OPENGL_EXTENSIONS;
  60.  
  61.   int currentSamples = -1;
  62.  
  63.   private Frame frame;
  64.   private GLProfile profile;
  65.   private GLCapabilities capabilities;
  66.   private GLCanvas canvas;
  67.  
  68.   private SimpleListener listener;
  69.   private CustomAnimator animator;
  70.  
  71.   private long beforeTime;
  72.   private long overSleepTime;
  73.   private long frameRatePeriod = 1000000000L / frameRate;
  74.  
  75.   private boolean initialized = false;  
  76.  
  77.   private double theta = 0;
  78.   private double s = 0;
  79.   private double c = 0;  
  80.  
  81.   private long millisOffset;
  82.   private int fcount, lastm;
  83.   private float frate;
  84.   private int fint = 3;
  85.  
  86.   private boolean setFramerate = false;
  87.   private boolean restarted = false;
  88.  
  89.   private int frameCount = 0;
  90.  
  91.   void run() {
  92.     Thread loop = new Thread("Animation Thread") {
  93.       public void run() {        
  94.         frameCount = 0;
  95.         while (true) {
  96.           if (!initialized) {
  97.             setup();            
  98.           }
  99.          
  100.           if (restartCanvas && restartTimeout == frameCount) {
  101.             restart();
  102.           }
  103.          
  104.           if (useAnimator) {
  105.             animator.requestRender();
  106.           } else {
  107.             canvas.display();            
  108.           }
  109.          
  110.           clock();
  111.          
  112.           frameCount++;
  113.         }
  114.       }
  115.     };
  116.     loop.start();        
  117.   }
  118.  
  119.   void setup() {
  120.     if (printThreadInfo) System.out.println("Current thread at setup(): " + Thread.currentThread());
  121.    
  122.     millisOffset = System.currentTimeMillis();    
  123.  
  124.     // Frame setup ----------------------------------------------------------
  125.    
  126.     width = 300;
  127.     height = 300;    
  128.     MiniPApplet applet = this;
  129.     Rectangle fullScreenRect = null;
  130.    
  131.     GraphicsEnvironment environment =
  132.       GraphicsEnvironment.getLocalGraphicsEnvironment();
  133.     GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
  134.     frame = new Frame(displayDevice.getDefaultConfiguration());
  135.    
  136.     frame.setTitle("MiniPApplet");
  137.     if (fullScreen) {
  138.       frame.setUndecorated(true);
  139.       frame.setBackground(Color.GRAY);
  140.       DisplayMode mode = displayDevice.getDisplayMode();
  141.       fullScreenRect = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());
  142.       frame.setBounds(fullScreenRect);
  143.       frame.setVisible(true);
  144.     }
  145.     frame.setLayout(null);
  146.     frame.add(applet);
  147.     if (fullScreen) {
  148.       frame.invalidate();
  149.     } else {
  150.       frame.pack();
  151.     }
  152.     frame.setResizable(resizeableFrame);
  153.    
  154.     if (fullScreen) {
  155.       // After the pack(), the screen bounds are gonna be 0s
  156.       frame.setBounds(fullScreenRect);
  157.       applet.setBounds((fullScreenRect.width - applet.width) / 2,
  158.                        (fullScreenRect.height - applet.height) / 2,
  159.                        applet.width, applet.height);
  160.     } else {
  161.       Insets insets = frame.getInsets();
  162.  
  163.       int windowW = applet.width + insets.left + insets.right;
  164.       int windowH = applet.height + insets.top + insets.bottom;
  165.       int locationX = 100;
  166.       int locationY = 100;
  167.      
  168.       frame.setSize(windowW, windowH);
  169.       frame.setLocation(locationX, locationY);
  170.      
  171.       int usableWindowH = windowH - insets.top - insets.bottom;
  172.       applet.setBounds((windowW - width)/2, insets.top + (usableWindowH - height)/2, width, height);      
  173.     }
  174.    
  175.     frame.add(this);
  176.     frame.addWindowListener(new WindowAdapter() {
  177.       public void windowClosing(WindowEvent e) {
  178.           System.exit(0);
  179.       }
  180.     });    
  181.    
  182.     frame.setVisible(true);
  183.  
  184.     // Canvas setup ----------------------------------------------------------
  185.    
  186.     profile = GLProfile.getDefault();
  187.     capabilities = new GLCapabilities(profile);
  188.     capabilities.setSampleBuffers(true);
  189.     capabilities.setNumSamples(numSamples);
  190.     capabilities.setDepthBits(24);
  191.     capabilities.setStencilBits(8);
  192.     capabilities.setAlphaBits(8);
  193.    
  194.     canvas = new GLCanvas(capabilities);
  195.     canvas.setBounds(0, 0, width, height);
  196.        
  197.     this.setLayout(new BorderLayout());
  198.     this.add(canvas, BorderLayout.CENTER);
  199.     canvas.addMouseMotionListener(this);
  200.     canvas.addKeyListener(this);
  201.        
  202.     // Setting up animation
  203.     listener = new SimpleListener();
  204.     canvas.addGLEventListener(listener);
  205.     if (useAnimator) {
  206.       animator = new CustomAnimator(canvas);
  207.       animator.start();
  208.     }    
  209.     initialized = true;    
  210.   }
  211.  
  212.   void restart() {
  213.     System.out.println("Restarting surface...");
  214.    
  215.     // Stopping animation, removing current canvas.
  216.     if (useAnimator) {
  217.       animator.stop();
  218.       animator.remove(canvas);
  219.     }
  220.     canvas.removeGLEventListener(listener);
  221.     this.remove(canvas);    
  222.        
  223.     capabilities = new GLCapabilities(profile);
  224.     capabilities.setSampleBuffers(true);
  225.     capabilities.setNumSamples(numSamples);
  226.    
  227.     canvas = new GLCanvas(capabilities);
  228.     canvas.setBounds(0, 0, width, height);
  229.    
  230.     // Setting up animation again
  231.     this.setLayout(new BorderLayout());
  232.     this.add(canvas, BorderLayout.CENTER);
  233.     canvas.addMouseMotionListener(this);
  234.     canvas.addKeyListener(this);
  235.    
  236.     canvas.addGLEventListener(listener);
  237.     if (useAnimator) {
  238.       animator.add(canvas);
  239.       animator.start();
  240.     }    
  241.        
  242.     setFramerate = false;
  243.     restarted = true;
  244.    
  245.     System.out.println("Done");
  246.   }
  247.  
  248.   void draw(GL2 gl) {
  249.     frame.setTitle("frame " + frameCount);
  250.    
  251.     if (printThreadInfo) System.out.println("Current thread at draw(): " + Thread.currentThread());      
  252.    
  253.     if (OPENGL_VENDOR == null) {
  254.       OPENGL_VENDOR     = gl.glGetString(GL.GL_VENDOR);  
  255.       OPENGL_RENDERER   = gl.glGetString(GL.GL_RENDERER);
  256.       OPENGL_VERSION    = gl.glGetString(GL.GL_VERSION);    
  257.       OPENGL_EXTENSIONS = gl.glGetString(GL.GL_EXTENSIONS);
  258.       System.out.println(OPENGL_VENDOR);
  259.       System.out.println(OPENGL_RENDERER);
  260.       System.out.println(OPENGL_VERSION);
  261.       System.out.println(OPENGL_EXTENSIONS);
  262.      
  263.       int[] temp = { 0 };
  264.       gl.glGetIntegerv(GL2.GL_MAX_SAMPLES, temp, 0);
  265.       System.out.println("Maximum number of samples supported by the hardware: " + temp[0]);
  266.     }
  267.    
  268.     if (currentSamples == -1) {
  269.       int[] temp = { 0 };
  270.       gl.glGetIntegerv(GL.GL_SAMPLES, temp, 0);
  271.       currentSamples = temp[0];
  272.       if (numSamples != currentSamples) {
  273.         System.err.println("Requested sampling level " + numSamples + " not supported. Using " + currentSamples + " samples instead.");
  274.       }
  275.     }
  276.    
  277.     if (!setFramerate) {      
  278.       if (60 < frameRate) {
  279.         // Disables vsync
  280.         gl.setSwapInterval(0);  
  281.       } else if (30 < frameRate) {        
  282.         gl.setSwapInterval(1);
  283.       } else {
  284.         gl.setSwapInterval(2);
  285.       }      
  286.       setFramerate = true;      
  287.     }
  288.    
  289.     if (restarted) {
  290.       int[] temp = { 0 };
  291.       gl.glGetIntegerv(GL.GL_SAMPLES, temp, 0);    
  292.       if (numSamples != temp[0]) {
  293.         System.err.println("Multisampling level requested " + numSamples + " not supported. Using " + temp[0] + "samples instead.");
  294.       }    
  295.     }
  296.    
  297.     gl.glClearColor(0, 0, 0, 1);
  298.     gl.glClear(GL.GL_COLOR_BUFFER_BIT);
  299.    
  300.     theta += 0.01;
  301.     s = Math.sin(theta);
  302.     c = Math.cos(theta);      
  303.    
  304.     gl.glBegin(GL.GL_TRIANGLES);
  305.     gl.glColor3f(1, 0, 0);
  306.     gl.glVertex2d(-c, -c);
  307.     gl.glColor3f(0, 1, 0);
  308.     gl.glVertex2d(0, c);
  309.     gl.glColor3f(0, 0, 1);
  310.     gl.glVertex2d(s, -s);
  311.     gl.glEnd();    
  312.    
  313.     gl.glFlush();
  314.    
  315.     fcount += 1;
  316.     int m = (int) (System.currentTimeMillis() - millisOffset);
  317.     if (m - lastm > 1000 * fint) {
  318.       frate = (float)(fcount) / fint;
  319.       fcount = 0;
  320.       lastm = m;
  321.       System.err.println("fps: " + frate);
  322.     }    
  323.   }
  324.  
  325.   void clock() {
  326.     long afterTime = System.nanoTime();
  327.     long timeDiff = afterTime - beforeTime;
  328.     long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
  329.  
  330.     if (sleepTime > 0) {  // some time left in this cycle
  331.       try {
  332.         Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
  333.       } catch (InterruptedException ex) { }
  334.  
  335.       overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
  336.  
  337.     } else {    // sleepTime <= 0; the frame took longer than the period
  338.       overSleepTime = 0L;
  339.     }
  340.  
  341.     beforeTime = System.nanoTime();    
  342.   }  
  343.  
  344.   class SimpleListener implements GLEventListener {
  345.     @Override
  346.     public void display(GLAutoDrawable drawable) {
  347.       draw(drawable.getGL().getGL2());
  348.     }
  349.  
  350.     @Override
  351.     public void dispose(GLAutoDrawable drawable) { }
  352.  
  353.     @Override
  354.     public void init(GLAutoDrawable drawable) { }
  355.  
  356.     @Override
  357.     public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { }    
  358.   }
  359.  
  360.   public void mouseDragged(MouseEvent ev) {
  361.     if (printEventInfo) {
  362.       System.err.println("Mouse dragged event: " + ev);
  363.     }
  364.   }
  365.  
  366.   public void mouseMoved(MouseEvent ev) {
  367.     if (printEventInfo) {
  368.       System.err.println("Mouse moved event: " + ev);
  369.     }
  370.   }  
  371.  
  372.   public void keyPressed(KeyEvent ev) {
  373.     if (printEventInfo) {
  374.       System.err.println("Key pressed event: " + ev);
  375.     }
  376.   }
  377.  
  378.   public void keyReleased(KeyEvent ev) {
  379.     if (printEventInfo) {
  380.       System.err.println("Key released event: " + ev);
  381.     }  
  382.   }
  383.  
  384.   public void keyTyped(KeyEvent ev) {
  385.     if (printEventInfo) {
  386.       System.err.println("Key typed event: " + ev);
  387.     }  
  388.   }  
  389.  
  390.   public static void main(String[] args) {
  391.     MiniPApplet mini;
  392.     try {
  393.       Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(MiniPApplet.class.getName());
  394.       mini = (MiniPApplet) c.newInstance();
  395.     } catch (Exception e) {
  396.       throw new RuntimeException(e);
  397.     }    
  398.     if (mini != null) {
  399.       mini.run();
  400.     }
  401.   }      
  402.  
  403.   /** An Animator subclass which renders one frame at the time
  404.    *  upon calls to the requestRender() method.
  405.    **/
  406.   public class CustomAnimator extends AnimatorBase {    
  407.       private Timer timer = null;
  408.       private TimerTask task = null;
  409.       private volatile boolean shouldRun;
  410.  
  411.       protected String getBaseName(String prefix) {
  412.           return "Custom" + prefix + "Animator" ;
  413.       }
  414.  
  415.       /** Creates an CustomAnimator with an initial drawable to
  416.        * animate. */
  417.       public CustomAnimator(GLAutoDrawable drawable) {
  418.           if (drawable != null) {
  419.               add(drawable);
  420.           }
  421.       }
  422.  
  423.       public synchronized void requestRender() {
  424.           shouldRun = true;
  425.       }
  426.  
  427.       public final boolean isStarted() {
  428.           stateSync.lock();
  429.           try {
  430.               return (timer != null);
  431.           } finally {
  432.               stateSync.unlock();
  433.           }
  434.       }
  435.  
  436.       public final boolean isAnimating() {
  437.           stateSync.lock();
  438.           try {
  439.               return (timer != null) && (task != null);
  440.           } finally {
  441.               stateSync.unlock();
  442.           }
  443.       }
  444.  
  445.       private void startTask() {
  446.           if(null != task) {
  447.               return;
  448.           }
  449.          
  450.           task = new TimerTask() {
  451.               private boolean firstRun = true;
  452.               public void run() {
  453.                   if (firstRun) {
  454.                     Thread.currentThread().setName("OPENGL");
  455.                     firstRun = false;
  456.                   }
  457.                   if(CustomAnimator.this.shouldRun) {
  458.                      CustomAnimator.this.animThread = Thread.currentThread();
  459.                       // display impl. uses synchronized block on the animator instance
  460.                       display();                
  461.                       synchronized (this) {
  462.                         // done with current frame.
  463.                         shouldRun = false;
  464.                       }                    
  465.                   }
  466.               }
  467.           };
  468.  
  469.           fpsCounter.resetFPSCounter();
  470.           shouldRun = false;
  471.          
  472.           timer.schedule(task, 0, 1);
  473.       }
  474.      
  475.       public synchronized boolean  start() {
  476.           if (timer != null) {
  477.               return false;
  478.           }
  479.           stateSync.lock();
  480.           try {
  481.               timer = new Timer();
  482.               startTask();
  483.           } finally {
  484.               stateSync.unlock();
  485.           }
  486.           return true;
  487.       }
  488.  
  489.       /** Stops this CustomAnimator. */
  490.       public synchronized boolean stop() {
  491.           if (timer == null) {
  492.               return false;
  493.           }
  494.           stateSync.lock();
  495.           try {
  496.               shouldRun = false;
  497.               if(null != task) {
  498.                   task.cancel();
  499.                   task = null;
  500.               }
  501.               if(null != timer) {
  502.                   timer.cancel();
  503.                   timer = null;
  504.               }
  505.               animThread = null;
  506.               try {
  507.                   Thread.sleep(20); // ~ 1/60 hz wait, since we can't ctrl stopped threads
  508.               } catch (InterruptedException e) { }
  509.           } finally {
  510.               stateSync.unlock();
  511.           }
  512.           return true;
  513.       }
  514.      
  515.       public final boolean isPaused() { return false; }
  516.       public synchronized boolean resume() { return false; }
  517.       public synchronized boolean pause() { return false; }    
  518.   }
  519. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement