History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/opengl/OGLRenderQueue.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/opengl/OGLRenderQueue.java+239−0
@@ -0,0 +1,239 @@
1+/*
2+ * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.java2d.opengl;
27+
28+import sun.java2d.pipe.RenderBuffer;
29+import sun.java2d.pipe.RenderQueue;
30+import static sun.java2d.pipe.BufferedOpCodes.*;
31+
32+/**
33+ * OGL-specific implementation of RenderQueue. This class provides a
34+ * single (daemon) thread that is responsible for periodically flushing
35+ * the queue, thus ensuring that only one thread communicates with the native
36+ * OpenGL libraries for the entire process.
37+ */
38+public class OGLRenderQueue extends RenderQueue {
39+
40+ private static OGLRenderQueue theInstance;
41+ private final QueueFlusher flusher;
42+
43+ private OGLRenderQueue() {
44+ flusher = new QueueFlusher();
45+ }
46+
47+ /**
48+ * Returns the single OGLRenderQueue instance. If it has not yet been
49+ * initialized, this method will first construct the single instance
50+ * before returning it.
51+ */
52+ public static synchronized OGLRenderQueue getInstance() {
53+ if (theInstance == null) {
54+ theInstance = new OGLRenderQueue();
55+ }
56+ return theInstance;
57+ }
58+
59+ /**
60+ * Flushes the single OGLRenderQueue instance synchronously. If an
61+ * OGLRenderQueue has not yet been instantiated, this method is a no-op.
62+ * This method is useful in the case of Toolkit.sync(), in which we want
63+ * to flush the OGL pipeline, but only if the OGL pipeline is currently
64+ * enabled. Since this class has few external dependencies, callers need
65+ * not be concerned that calling this method will trigger initialization
66+ * of the OGL pipeline and related classes.
67+ */
68+ public static void sync() {
69+ if (theInstance != null) {
70+ theInstance.lock();
71+ try {
72+ theInstance.ensureCapacity(4);
73+ theInstance.getBuffer().putInt(SYNC);
74+ theInstance.flushNow();
75+ } finally {
76+ theInstance.unlock();
77+ }
78+ }
79+ }
80+
81+ /**
82+ * Disposes the native memory associated with the given native
83+ * graphics config info pointer on the single queue flushing thread.
84+ */
85+ public static void disposeGraphicsConfig(long pConfigInfo) {
86+ OGLRenderQueue rq = getInstance();
87+ rq.lock();
88+ try {
89+ // make sure we make the context associated with the given
90+ // GraphicsConfig current before disposing the native resources
91+ OGLContext.setScratchSurface(pConfigInfo);
92+
93+ RenderBuffer buf = rq.getBuffer();
94+ rq.ensureCapacityAndAlignment(12, 4);
95+ buf.putInt(DISPOSE_CONFIG);
96+ buf.putLong(pConfigInfo);
97+
98+ // this call is expected to complete synchronously, so flush now
99+ rq.flushNow();
100+ } finally {
101+ rq.unlock();
102+ }
103+ }
104+
105+ /**
106+ * Returns true if the current thread is the OGL QueueFlusher thread.
107+ */
108+ public static boolean isQueueFlusherThread() {
109+ return (Thread.currentThread() == getInstance().flusher);
110+ }
111+
112+ public void flushNow() {
113+ // assert lock.isHeldByCurrentThread();
114+ try {
115+ flusher.flushNow();
116+ } catch (Exception e) {
117+ System.err.println("exception in flushNow:");
118+ e.printStackTrace();
119+ }
120+ }
121+
122+ public void flushAndInvokeNow(Runnable r) {
123+ // assert lock.isHeldByCurrentThread();
124+ try {
125+ flusher.flushAndInvokeNow(r);
126+ } catch (Exception e) {
127+ System.err.println("exception in flushAndInvokeNow:");
128+ e.printStackTrace();
129+ }
130+ }
131+
132+ private native void flushBuffer(long buf, int limit);
133+
134+ private void flushBuffer() {
135+ // assert lock.isHeldByCurrentThread();
136+ int limit = buf.position();
137+ if (limit > 0) {
138+ // process the queue
139+ flushBuffer(buf.getAddress(), limit);
140+ }
141+ // reset the buffer position
142+ buf.clear();
143+ // clear the set of references, since we no longer need them
144+ refSet.clear();
145+ }
146+
147+ private class QueueFlusher extends Thread {
148+ private boolean needsFlush;
149+ private Runnable task;
150+ private Error error;
151+
152+ public QueueFlusher() {
153+ super("Java2D Queue Flusher");
154+ setDaemon(true);
155+ setPriority(Thread.MAX_PRIORITY);
156+ start();
157+ }
158+
159+ public synchronized void flushNow() {
160+ // wake up the flusher
161+ needsFlush = true;
162+ notify();
163+
164+ // wait for flush to complete
165+ while (needsFlush) {
166+ try {
167+ wait();
168+ } catch (InterruptedException e) {
169+ }
170+ }
171+
172+ // re-throw any error that may have occurred during the flush
173+ if (error != null) {
174+ throw error;
175+ }
176+ }
177+
178+ public synchronized void flushAndInvokeNow(Runnable task) {
179+ this.task = task;
180+ flushNow();
181+ }
182+
183+ public synchronized void run() {
184+ boolean timedOut = false;
185+ while (true) {
186+ while (!needsFlush) {
187+ try {
188+ timedOut = false;
189+ /*
190+ * Wait until we're woken up with a flushNow() call,
191+ * or the timeout period elapses (so that we can
192+ * flush the queue periodically).
193+ */
194+ wait(100);
195+ /*
196+ * We will automatically flush the queue if the
197+ * following conditions apply:
198+ * - the wait() timed out
199+ * - we can lock the queue (without blocking)
200+ * - there is something in the queue to flush
201+ * Otherwise, just continue (we'll flush eventually).
202+ */
203+ if (!needsFlush && (timedOut = tryLock())) {
204+ if (buf.position() > 0) {
205+ needsFlush = true;
206+ } else {
207+ unlock();
208+ }
209+ }
210+ } catch (InterruptedException e) {
211+ }
212+ }
213+ try {
214+ // reset the throwable state
215+ error = null;
216+ // flush the buffer now
217+ flushBuffer();
218+ // if there's a task, invoke that now as well
219+ if (task != null) {
220+ task.run();
221+ }
222+ } catch (Error e) {
223+ error = e;
224+ } catch (Exception x) {
225+ System.err.println("exception in QueueFlusher:");
226+ x.printStackTrace();
227+ } finally {
228+ if (timedOut) {
229+ unlock();
230+ }
231+ task = null;
232+ // allow the waiting thread to continue
233+ needsFlush = false;
234+ notify();
235+ }
236+ }
237+ }
238+ }
239+}