Our main representation for an OpenGL graphics context. The key complexity in doing graphics is that we wish to defer execution of drawing code to a particular time and place in the internalScene graph and that this internalScene graph drawing can only take place inside an OpenGL graphics contex
| 33 | * enterContext() and exitContext(). |
| 34 | */ |
| 35 | public class GraphicsContext { |
| 36 | |
| 37 | public final ReentrantLock lock = new ReentrantLock(true); |
| 38 | |
| 39 | static protected final ThreadLocal<GraphicsContext> currentGraphicsContext = new ThreadLocal<>(); |
| 40 | static List<GraphicsContext> allGraphicsContexts = new ArrayList<GraphicsContext>(); |
| 41 | |
| 42 | public final StateTracker stateTracker = new StateTracker(); |
| 43 | public final UniformCache uniformCache = new UniformCache(); |
| 44 | |
| 45 | protected WeakHashMap<Object, Object> context = new WeakHashMap<>(); |
| 46 | |
| 47 | static public GraphicsContext getContext() { |
| 48 | return currentGraphicsContext.get(); |
| 49 | } |
| 50 | |
| 51 | static public boolean isResizing = false; |
| 52 | |
| 53 | /** the preQueue is a list of things that run every time that the context is entered */ |
| 54 | public final BlockingQueue<Runnable> preQueue = new LinkedBlockingQueue<>(); |
| 55 | |
| 56 | /** the postQueue is a list of things that run _once_ when the context is exited --- it is cleared every exit (although it is safe to add additional items to this during the exit) */ |
| 57 | public final BlockingQueue<Runnable> postQueue = new LinkedBlockingQueue<>(); |
| 58 | |
| 59 | static public GraphicsContext newContext() { |
| 60 | GraphicsContext c = new GraphicsContext(); |
| 61 | allGraphicsContexts.add(c); |
| 62 | currentGraphicsContext.set(c); |
| 63 | return c; |
| 64 | } |
| 65 | |
| 66 | static public void enterContext(GraphicsContext c) { |
| 67 | Log.log("graphics.trace", () -> ">> graphics context begin "); |
| 68 | currentGraphicsContext.set(c); |
| 69 | |
| 70 | ArrayList<Runnable> q = new ArrayList<>(currentGraphicsContext.get().preQueue); |
| 71 | // currentGraphicsContext.get().preQueue.clear(); |
| 72 | |
| 73 | for (Runnable r : q) |
| 74 | r.run(); |
| 75 | } |
| 76 | |
| 77 | static public void exitContext(GraphicsContext c) { |
| 78 | if (currentGraphicsContext.get() != c) throw new Error(); |
| 79 | ArrayList<Runnable> q = new ArrayList<>(currentGraphicsContext.get().postQueue); |
| 80 | currentGraphicsContext.get().postQueue.clear(); |
| 81 | |
| 82 | for (Runnable r : q) |
| 83 | r.run(); |
| 84 | |
| 85 | currentGraphicsContext.set(null); |
| 86 | Log.log("graphics.trace", () -> "<< graphics context end"); |
| 87 | } |
| 88 | |
| 89 | static public <T> T get(Object o) { |
| 90 | return (T) currentGraphicsContext.get().context.get(o); |
| 91 | } |
| 92 |