gzz-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gzz-commits] gzz gfx/jni/GzzGL-jni.cxx gfx/libos/Os-GLX.cxx ...


From: Tuomas J. Lukka
Subject: [Gzz-commits] gzz gfx/jni/GzzGL-jni.cxx gfx/libos/Os-GLX.cxx ...
Date: Sat, 18 Jan 2003 09:53:09 -0500

CVSROOT:        /cvsroot/gzz
Module name:    gzz
Changes by:     Tuomas J. Lukka <address@hidden>        03/01/18 09:53:09

Modified files:
        gfx/jni        : GzzGL-jni.cxx 
        gfx/libos      : Os-GLX.cxx Os.hxx 
        gzz/client     : AbstractUpdateManager.java 
        gzz/client/gl  : GLUpdateManager.java 
        gzz/gfx/gl     : GL.java 

Log message:
        Rework event loop; next: retry mipzip

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/jni/GzzGL-jni.cxx.diff?tr1=1.77&tr2=1.78&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libos/Os-GLX.cxx.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libos/Os.hxx.diff?tr1=1.17&tr2=1.18&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/client/AbstractUpdateManager.java.diff?tr1=1.30&tr2=1.31&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/client/gl/GLUpdateManager.java.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/gfx/gl/GL.java.diff?tr1=1.41&tr2=1.42&r1=text&r2=text

Patches:
Index: gzz/gfx/jni/GzzGL-jni.cxx
diff -u gzz/gfx/jni/GzzGL-jni.cxx:1.77 gzz/gfx/jni/GzzGL-jni.cxx:1.78
--- gzz/gfx/jni/GzzGL-jni.cxx:1.77      Thu Jan 16 07:54:24 2003
+++ gzz/gfx/jni/GzzGL-jni.cxx   Sat Jan 18 09:53:08 2003
@@ -210,29 +210,6 @@
     }
 };
 
-/*
-struct GZZJNIIdler : public Gzz::AbstractWin::IdleTasks {
-    jobject globalRef;
-    jclass globalclass; // must keep for mid to remain valid
-    jmethodID mid_tick;
-    GZZJNIIdler(JNIEnv *env, jobject globalRef) : globalRef(globalRef) {
-       jclass cls = env->GetObjectClass(globalRef);
-       globalclass = (jclass)env->NewGlobalRef(cls);
-       mid_tick = env->GetMethodID(globalclass,
-                    "tick", "()Z");
-    }
-    ~GZZJNIIdler() {
-    }
-    bool tick() {
-       // cout << "Starting to call tick\n";
-       // cout << "Calling tick "<<mid<<"\n";
-       bool ret = jnienv_eventloop->CallBooleanMethod(globalRef, mid_tick);
-       // cout << "Finished: \n" << ret;
-       return ret;
-    }
-};
-*/
-
 extern "C" {
 
 int inited = 0;
@@ -315,13 +292,6 @@
       windows.remove(id);
   }
 
-JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_repaintWindow
-  (JNIEnv *env, jclass, jint id) {
-      DBG(dbg_event) << "RepaintWindow called\n";
-      Os::Window *w = (Os::Window *)windows.get(id);
-      w->repaint();
-  }
-
 JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_getWindowSize
   (JNIEnv *env, jclass, jint id, jobject rect) {
       Os::RenderingSurface *win = windows.get(id);
@@ -1023,12 +993,15 @@
       } catch(JavaException e) {
          cerr << "CAUGHT JAVA EXCEPTION\n";
       }
-      /*
-       ticker = env->NewGlobalRef(ticker);
-       ws->addIdle(new GZZJNIIdler(env, ticker));
-       ws->eventLoop();
-      */
   }
+
+JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_interruptEventloop
+  (JNIEnv *env, jclass) {
+      DBG(dbg) << "Interrupting C++ eventloop";
+      ws->interrupt();
+      DBG(dbg) << "Done interrupting - should wake soon";
+  }
+
 
 #include <sys/time.h>
 double getTime() {
Index: gzz/gfx/libos/Os-GLX.cxx
diff -u gzz/gfx/libos/Os-GLX.cxx:1.20 gzz/gfx/libos/Os-GLX.cxx:1.21
--- gzz/gfx/libos/Os-GLX.cxx:1.20       Thu Dec 19 04:12:39 2002
+++ gzz/gfx/libos/Os-GLX.cxx    Sat Jan 18 09:53:08 2003
@@ -31,6 +31,8 @@
 
 #include <sys/time.h>
 #include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #include <libos/Os.hxx>
 
@@ -155,6 +157,8 @@
 
     typedef ::Window Win; // work around a syntax error.
 
+    /** Return the current time as milliseconds after some unit.
+     */
     long curTime() {
        struct timeval t;
        gettimeofday(&t, 0);
@@ -179,6 +183,15 @@
     }
 
     struct LXWindowSystem : public Os::WindowSystem {
+
+       /** A pipe, used to interrupt waiting of eventloop.
+        */
+       int interruptPipe[2];
+
+       fd_set readFds;
+       fd_set tmpReadFds;
+       int fdsMax;
+
        Display              *dpy;
        XSetWindowAttributes swa;
        int swaMask;
@@ -209,8 +222,20 @@
        Drawable pixmapDrawable;
 
        LXWindowSystem() {
+           if(pipe(interruptPipe) < 0) {
+               perror("Making interrupt pipe");
+               exit(1);
+           }
+           fcntl(interruptPipe[0], F_SETFL, O_NONBLOCK);
+           fcntl(interruptPipe[1], F_SETFL, O_NONBLOCK);
+
            if(!(dpy = XOpenDisplay( NULL ))) BARF("Can't start X");
 
+           FD_ZERO(&readFds);
+           FD_SET(ConnectionNumber(dpy), &readFds);
+           FD_SET(interruptPipe[0], &readFds);
+           fdsMax = (ConnectionNumber(dpy) >? interruptPipe[0]) + 5;
+
 
            int nel;
 
@@ -304,6 +329,7 @@
            return f;
        }
 
+       void interrupt();
        void eventLoop(bool wait);
 
        /*
@@ -313,7 +339,6 @@
        */
 
     private:
-       bool tryRepaint();
        
     };
 
@@ -411,7 +436,6 @@
        virtual void setEventHandler(Eventhandler *h) {
            eventhandler = h;
            DBG(dbg) << "Set window "<<xw<<" eventhandler to "<<((int)h)<<"\n";
-           repaint();
        }
 
        LXWindow(LXWindowSystem *ws, int x, int y, int w, int h) : ws(ws), 
@@ -477,21 +501,6 @@
            glXSwapBuffers(ws->dpy, xw);
        }
 
-       virtual void repaint() {
-           needRepaint = true;
-       }
-
-       bool tryRepaint() {
-           // cout << "TryRepaint\n";
-           if(needRepaint) {
-               needRepaint = false;
-               if(eventhandler) {
-                   eventhandler->repaint();
-                   return true;
-               }
-           }
-           return false;
-       }
 
        virtual void move(int x, int y) {
            XMoveWindow(ws->dpy, xw, x, y);
@@ -593,19 +602,19 @@
            }
            case Expose:
                DBG(dbg) << "Expose\n";
-               repaint();
+               eventhandler->repaint();
                break;
            case ConfigureNotify:
                DBG(dbg) << "Configurenotify\n";
-               repaint();
+               eventhandler->repaint();
                break;
            case MapRequest:
                DBG(dbg) << "MapRequest\n";
-               repaint();
+               eventhandler->repaint();
                break;
            case MapNotify:
                DBG(dbg) << "MapNotify\n";
-               repaint();
+               eventhandler->repaint();
                break;
            default:
                    DBG(dbg) << "Unknown event "<<e->type<<"\n";
@@ -636,52 +645,66 @@
        return instance;
     }
 
+    char intr = 'S';
+    void LXWindowSystem::interrupt() {
+       write(interruptPipe[1], &intr, 1);
+    }
+
 
     void LXWindowSystem::eventLoop(bool wait) {
        DBG(dbg) << "In C++ eventloop : "<<wait<<"\n";
        // We don't want to block;
        while(1) {
            DBG(dbg) << "Start loop\n";
-           XEvent e;
-           if(tryRepaint()) {
-               DBG(dbg) << "TryRepaint returned true, doing again... if no 
events (not now)\n";
-               /*
-               if(!XEventsQueued(dpy, QueuedAfterFlush))
-                   continue;
-               */
-           }
-           /*
-           for(int i=0; i<idletasks.size(); i++) {
-               donthang = (donthang || idletasks[i]->tick());
-           }
-           */
-           DBG(dbg) << "Repaint done\n";
 
            bool eventsWaiting = XEventsQueued(dpy, QueuedAfterFlush);
 
+           // If we should not wait and there are no events, return now
            if(!wait && !eventsWaiting) return;
+           // We only wait once: on the next iteration of the loop,
+           // we'll return
+           wait = false;
 
-           DBG(dbg) << "Get next event\n";
-           // If we're waiting for a timeout, handle things
-           // differently.
-           if(timeouts.size() && !eventsWaiting) {
-               long t = curTime();
-               for(unsigned i=0; i<timeouts.size(); i++) {
-                   if(timeouts[i].time < t) {
-                       int id = timeouts[i].id;
-                       LXWindow *w = windowsByX[timeouts[i].window];
-                       timeouts.erase(timeouts.begin()+i);
-                       w->deliverTimeout(id);
-                       return;
+           DBG(dbg) << "Wait for next event, interrupt or timeout\n";
+
+           // If no events were waiting, now's the time to 
+           // wait for them.
+           if(!eventsWaiting) {
+               // Visit Java at least every .5 seconds
+               timeval timeout;
+               timeout.tv_sec = 0;
+               timeout.tv_usec = 500 * 1000;
+
+               // If we're waiting for a timeout, sleep less.
+               if(timeouts.size() && !eventsWaiting) {
+                   long t = curTime();
+                   for(unsigned i=0; i<timeouts.size(); i++) {
+                       if(timeouts[i].time < t) {
+                           int id = timeouts[i].id;
+                           LXWindow *w = windowsByX[timeouts[i].window];
+                           timeouts.erase(timeouts.begin()+i);
+                           w->deliverTimeout(id);
+                           return;
+                       } else {
+                           int ms = timeouts[i].time - t;
+                           if(ms < timeout.tv_usec / 1000)
+                               timeout.tv_sec = 1000 * ms;
+                       }
                    }
                }
-               timespec ts;
-               ts.tv_sec = 0;
-               ts.tv_nsec = 50000000;  // 50 ms - very bad
-               nanosleep(&ts, &ts);
-               continue;
+               // Call select to wait for something to happen.
+               tmpReadFds = readFds;
+               select(fdsMax, &tmpReadFds, 0, 0, &timeout);
+               char b[4];
+               DBG(dbg) << "Emptying interrupt pipe\n";
+               while(read(interruptPipe[0], &b, 4) > 0) {
+                   DBG(dbg) << "Got "<<b[0]<<" "<<b[1]<<" "<<b[2]<< " 
"<<b[3]<<"\n";
+               }
+               DBG(dbg) << "Empty\n";
            }
-           wait = false;
+
+
+           XEvent e;
            XNextEvent(dpy, &e);
            //cout << "getWindow\n";
            LXWindow *w = windowsByX[e.xkey.window];
@@ -692,13 +715,6 @@
            //cout << "deliver\n";
            w->deliverEvent(&e);
        }
-    }
-
-    bool LXWindowSystem::tryRepaint() {
-       for(unsigned i=0; i<windows.size(); i++) {
-           if(windows[i]->tryRepaint()) return true;
-       }
-       return false;
     }
 
     /** Load an image into a raster using gdk-pixbuf.
Index: gzz/gfx/libos/Os.hxx
diff -u gzz/gfx/libos/Os.hxx:1.17 gzz/gfx/libos/Os.hxx:1.18
--- gzz/gfx/libos/Os.hxx:1.17   Mon Jan 13 01:48:49 2003
+++ gzz/gfx/libos/Os.hxx        Sat Jan 18 09:53:08 2003
@@ -99,9 +99,6 @@
     public:
        Window() { }
        virtual ~Window() { };
-       /** Queue a repaint request.
-        */
-       virtual void repaint() = 0;
        virtual void setEventHandler(Eventhandler *h) = 0;
        /*
        virtual Eventhandler *getEventHandler() { 
@@ -148,7 +145,23 @@
        virtual Text::Font *loadFont(const char *javaName, 
                        int pt) = 0;
 
+       /** Handle events.
+        * @param wait If true, this function will wait for the next event
+        *             and handle it before returning; if false, will return
+        *             immediately.
+        */
        virtual void eventLoop(bool wait) = 0;
+
+       /** Interrupt event loop waiting.
+        * Because there are things happening in multiple threads in Java,
+        * it is useful to be able to stop the event loop from waiting
+        * to perform idle tasks again.
+        * <p>
+        * This is the ONLY function here that may be called from another
+        * thread.
+        */
+       virtual void interrupt() = 0;
+
 
     };
 
Index: gzz/gzz/client/AbstractUpdateManager.java
diff -u gzz/gzz/client/AbstractUpdateManager.java:1.30 
gzz/gzz/client/AbstractUpdateManager.java:1.31
--- gzz/gzz/client/AbstractUpdateManager.java:1.30      Sat Jan 18 08:30:58 2003
+++ gzz/gzz/client/AbstractUpdateManager.java   Sat Jan 18 09:53:08 2003
@@ -41,7 +41,7 @@
  */
 
 public abstract class AbstractUpdateManager implements Runnable {
-public static final String rcsid = "$Id: AbstractUpdateManager.java,v 1.30 
2003/01/18 13:30:58 tjl Exp $";
+public static final String rcsid = "$Id: AbstractUpdateManager.java,v 1.31 
2003/01/18 14:53:08 tjl Exp $";
     public static boolean dbg = false;
     private static void pa(String s) { System.err.println(s); }
 
@@ -330,7 +330,10 @@
            queue.add(r, priority);
            queue.notifyAll();
        }
+       instance.interruptEventloop();
     }
+
+    protected void interruptEventloop() { }
 
     /** Do the background tasks that need to be done in 
      * the main thread.
Index: gzz/gzz/client/gl/GLUpdateManager.java
diff -u gzz/gzz/client/gl/GLUpdateManager.java:1.10 
gzz/gzz/client/gl/GLUpdateManager.java:1.11
--- gzz/gzz/client/gl/GLUpdateManager.java:1.10 Fri Jan 10 13:44:51 2003
+++ gzz/gzz/client/gl/GLUpdateManager.java      Sat Jan 18 09:53:09 2003
@@ -30,7 +30,7 @@
 import java.util.*;
 
 public class GLUpdateManager extends AbstractUpdateManager {
-public static final String rcsid = "$Id: GLUpdateManager.java,v 1.10 
2003/01/10 18:44:51 tjl Exp $";
+public static final String rcsid = "$Id: GLUpdateManager.java,v 1.11 
2003/01/18 14:53:09 tjl Exp $";
     private static boolean dbg = false;
     private static void p(String s) { if(dbg) pa(s); }
     private static void pa(String s) { System.err.println(s); }
@@ -57,5 +57,9 @@
        if(super.doIdle()) return true;
        GL.freeQueue();
        return false;
+    }
+
+    protected void interruptEventloop() {
+       GL.interruptEventloop();
     }
 }
Index: gzz/gzz/gfx/gl/GL.java
diff -u gzz/gzz/gfx/gl/GL.java:1.41 gzz/gzz/gfx/gl/GL.java:1.42
--- gzz/gzz/gfx/gl/GL.java:1.41 Fri Jan 17 09:37:17 2003
+++ gzz/gzz/gfx/gl/GL.java      Sat Jan 18 09:53:09 2003
@@ -264,8 +264,6 @@
 
        private Window(int id) { super(id); }
 
-       // XXX ???
-       public void repaint() { GL.repaintWindow(getId()); }
 
        /** Call the EventHandler.timeout(id) with the given id,
         * after at least ms milliseconds have passed.
@@ -291,8 +289,6 @@
     static private native int createWindowImpl(int x, int y, int w, int h, 
EventHandler eh);
     static private native void deleteWindow(int i);
 
-    static private native void repaintWindow(int id);
-
     static private native void getWindowSize(int id, Rectangle into);
 
     static private native void addTimeoutWindow(int id, int ms, int tid);
@@ -825,6 +821,12 @@
      *                 for the next native event.
      */
     public static native void eventLoop(boolean wait);
+    /** Interrupt the event loop. 
+     * Unlike most functions in GL, this can be called from other threads
+     * to interrup a waiting event loop at any time.
+     * This is useful as a response e.g. for incoming network data.
+     */
+    public static native void interruptEventloop();
 
 
     public static native void setDebugVar(String name, int value);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]