< 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 >