< prev index next >
src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -892,21 +892,20 @@
// reference type stored in either TL or CLQ
static final int REF_TYPE;
// Per-thread RendererContext
private static final ThreadLocal<Object> rdrCtxThreadLocal;
- // RendererContext queue when ThreadLocal is disabled
- private static final ConcurrentLinkedQueue<Object> rdrCtxQueue;
+ // RendererContext queue when
+ // ThreadLocal is disabled or for child contexts (reentrance)
+ private static final ConcurrentLinkedQueue<Object> rdrCtxQueue
+ = new ConcurrentLinkedQueue<Object>();
// Static initializer to use TL or CLQ mode
static {
- // CLQ mode by default:
useThreadLocal = MarlinProperties.isUseThreadLocal();
rdrCtxThreadLocal = (useThreadLocal) ? new ThreadLocal<Object>()
: null;
- rdrCtxQueue = (!useThreadLocal) ? new ConcurrentLinkedQueue<Object>()
- : null;
// Soft reference by default:
String refType = AccessController.doPrivileged(
new GetPropertyAction("sun.java2d.renderer.useRef",
"soft"));
@@ -1024,41 +1023,67 @@
* @return RendererContext instance
*/
@SuppressWarnings({"unchecked"})
static RendererContext getRendererContext() {
RendererContext rdrCtx = null;
- final Object ref = (useThreadLocal) ? rdrCtxThreadLocal.get()
- : rdrCtxQueue.poll();
- if (ref != null) {
- // resolve reference:
- rdrCtx = (REF_TYPE == REF_HARD) ? ((RendererContext) ref)
- : ((Reference<RendererContext>) ref).get();
- }
- // create a new RendererContext if none is available
- if (rdrCtx == null) {
- rdrCtx = RendererContext.createContext();
- if (useThreadLocal) {
+ if (useThreadLocal) {
+ final Object ref = rdrCtxThreadLocal.get();
+ if (ref != null) {
+ rdrCtx = (REF_TYPE == REF_HARD) ? ((RendererContext) ref)
+ : ((Reference<RendererContext>) ref).get();
+ }
+ if (rdrCtx == null) {
+ // create a new RendererContext (TL) if none is available
+ rdrCtx = RendererContext.createContext(false);
// update thread local reference:
rdrCtxThreadLocal.set(rdrCtx.reference);
}
+ // Check reentrance:
+ if (rdrCtx.usedTL) {
+ // get or create another RendererContext:
+ rdrCtx = getOrCreateContextFromQueue();
+ } else {
+ // TL mode: set used flag:
+ rdrCtx.usedTL = true;
+ }
+ } else {
+ rdrCtx = getOrCreateContextFromQueue();
}
if (doMonitors) {
RendererContext.stats.mon_pre_getAATileGenerator.start();
}
return rdrCtx;
}
+ @SuppressWarnings({"unchecked"})
+ private static RendererContext getOrCreateContextFromQueue() {
+ RendererContext rdrCtx = null;
+ final Object ref = rdrCtxQueue.poll();
+ if (ref != null) {
+ rdrCtx = (REF_TYPE == REF_HARD) ? ((RendererContext) ref)
+ : ((Reference<RendererContext>) ref).get();
+ }
+ if (rdrCtx == null) {
+ // create a new RendererContext (QUEUE) if none is available
+ rdrCtx = RendererContext.createContext(true);
+ }
+ return rdrCtx;
+ }
+
/**
* Reset and return the given RendererContext instance for reuse
* @param rdrCtx RendererContext instance
*/
static void returnRendererContext(final RendererContext rdrCtx) {
rdrCtx.dispose();
if (doMonitors) {
RendererContext.stats.mon_pre_getAATileGenerator.stop();
}
- if (!useThreadLocal) {
+ if (!useThreadLocal || rdrCtx.storageQueue) {
rdrCtxQueue.offer(rdrCtx.reference);
+ } else {
+ // TL mode: unset used flag:
+ rdrCtx.usedTL = false;
}
}
}
< prev index next >