1 /* 2 * Copyright (c) 2007, 2017, 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 com.sun.marlin; 27 28 import java.security.AccessController; 29 import static com.sun.marlin.MarlinUtils.logInfo; 30 import com.sun.util.reentrant.ReentrantContextProvider; 31 import com.sun.util.reentrant.ReentrantContextProviderCLQ; 32 import com.sun.util.reentrant.ReentrantContextProviderTL; 33 import com.sun.javafx.geom.PathIterator; 34 import com.sun.prism.BasicStroke; 35 import java.security.PrivilegedAction; 36 37 /** 38 * Marlin RendererEngine implementation (derived from Pisces) 39 */ 40 public final class MarlinRenderingEngine implements MarlinConst 41 { 42 /** 43 * Private constructor to prevent instantiation. 44 */ 45 private MarlinRenderingEngine() { 46 } 47 48 static { 49 if (PathIterator.WIND_NON_ZERO != WIND_NON_ZERO || 50 PathIterator.WIND_EVEN_ODD != WIND_EVEN_ODD || 51 BasicStroke.JOIN_MITER != JOIN_MITER || 52 BasicStroke.JOIN_ROUND != JOIN_ROUND || 53 BasicStroke.JOIN_BEVEL != JOIN_BEVEL || 54 BasicStroke.CAP_BUTT != CAP_BUTT || 55 BasicStroke.CAP_ROUND != CAP_ROUND || 56 BasicStroke.CAP_SQUARE != CAP_SQUARE) 57 { 58 throw new InternalError("mismatched renderer constants"); 59 } 60 } 61 62 // --- RendererContext handling --- 63 // use ThreadLocal or ConcurrentLinkedQueue to get one RendererContext 64 private static final boolean USE_THREAD_LOCAL; 65 66 // reference type stored in either TL or CLQ 67 static final int REF_TYPE; 68 69 // Per-thread RendererContext 70 private static final ReentrantContextProvider<RendererContext> RDR_CTX_PROVIDER; 71 72 // Static initializer to use TL or CLQ mode 73 static { 74 USE_THREAD_LOCAL = MarlinProperties.isUseThreadLocal(); 75 76 // Soft reference by default: 77 final String refType = AccessController.doPrivileged( 78 (PrivilegedAction<String>) () -> { 79 String value = System.getProperty("prism.marlin.useRef"); 80 return (value == null) ? "soft" : value; 81 }); 82 switch (refType) { 83 default: 84 case "soft": 85 REF_TYPE = ReentrantContextProvider.REF_SOFT; 86 break; 87 case "weak": 88 REF_TYPE = ReentrantContextProvider.REF_WEAK; 89 break; 90 case "hard": 91 REF_TYPE = ReentrantContextProvider.REF_HARD; 92 break; 93 } 94 95 if (USE_THREAD_LOCAL) { 96 RDR_CTX_PROVIDER = new ReentrantContextProviderTL<RendererContext>(REF_TYPE) 97 { 98 @Override 99 protected RendererContext newContext() { 100 return RendererContext.createContext(); 101 } 102 }; 103 } else { 104 RDR_CTX_PROVIDER = new ReentrantContextProviderCLQ<RendererContext>(REF_TYPE) 105 { 106 @Override 107 protected RendererContext newContext() { 108 return RendererContext.createContext(); 109 } 110 }; 111 } 112 113 logSettings(Renderer.class.getName()); 114 } 115 116 private static boolean SETTINGS_LOGGED = !ENABLE_LOGS; 117 118 public static void logSettings(final String reClass) { 119 // log information at startup 120 if (SETTINGS_LOGGED) { 121 return; 122 } 123 SETTINGS_LOGGED = true; 124 125 String refType; 126 switch (REF_TYPE) { 127 default: 128 case ReentrantContextProvider.REF_HARD: 129 refType = "hard"; 130 break; 131 case ReentrantContextProvider.REF_SOFT: 132 refType = "soft"; 133 break; 134 case ReentrantContextProvider.REF_WEAK: 135 refType = "weak"; 136 break; 137 } 138 139 logInfo("==========================================================" 140 + "====================="); 141 142 logInfo("Marlin software rasterizer = ENABLED"); 143 logInfo("Version = [" 144 + Version.getVersion() + "]"); 145 logInfo("prism.marlin = " 146 + reClass); 147 logInfo("prism.marlin.useThreadLocal = " 148 + USE_THREAD_LOCAL); 149 logInfo("prism.marlin.useRef = " 150 + refType); 151 152 logInfo("prism.marlin.edges = " 153 + MarlinConst.INITIAL_EDGES_COUNT); 154 logInfo("prism.marlin.pixelsize = " 155 + MarlinConst.INITIAL_PIXEL_DIM); 156 157 logInfo("prism.marlin.subPixel_log2_X = " 158 + MarlinConst.SUBPIXEL_LG_POSITIONS_X); 159 logInfo("prism.marlin.subPixel_log2_Y = " 160 + MarlinConst.SUBPIXEL_LG_POSITIONS_Y); 161 162 logInfo("prism.marlin.blockSize_log2 = " 163 + MarlinConst.BLOCK_SIZE_LG); 164 165 // RLE / blockFlags settings 166 167 logInfo("prism.marlin.forceRLE = " 168 + MarlinProperties.isForceRLE()); 169 logInfo("prism.marlin.forceNoRLE = " 170 + MarlinProperties.isForceNoRLE()); 171 logInfo("prism.marlin.useTileFlags = " 172 + MarlinProperties.isUseTileFlags()); 173 logInfo("prism.marlin.useTileFlags.useHeuristics = " 174 + MarlinProperties.isUseTileFlagsWithHeuristics()); 175 logInfo("prism.marlin.rleMinWidth = " 176 + MarlinConst.RLE_MIN_WIDTH); 177 178 // optimisation parameters 179 logInfo("prism.marlin.useSimplifier = " 180 + MarlinConst.USE_SIMPLIFIER); 181 logInfo("prism.marlin.clip = " 182 + MarlinProperties.isDoClip()); 183 logInfo("prism.marlin.clip.runtime.enable = " 184 + MarlinProperties.isDoClipRuntimeFlag()); 185 186 // debugging parameters 187 logInfo("prism.marlin.doStats = " 188 + MarlinConst.DO_STATS); 189 logInfo("prism.marlin.doMonitors = " 190 + MarlinConst.DO_MONITORS); 191 logInfo("prism.marlin.doChecks = " 192 + MarlinConst.DO_CHECKS); 193 194 // logging parameters 195 logInfo("prism.marlin.log = " 196 + MarlinConst.ENABLE_LOGS); 197 logInfo("prism.marlin.useLogger = " 198 + MarlinConst.USE_LOGGER); 199 logInfo("prism.marlin.logCreateContext = " 200 + MarlinConst.LOG_CREATE_CONTEXT); 201 logInfo("prism.marlin.logUnsafeMalloc = " 202 + MarlinConst.LOG_UNSAFE_MALLOC); 203 204 // quality settings 205 logInfo("prism.marlin.cubic_dec_d2 = " 206 + MarlinProperties.getCubicDecD2()); 207 logInfo("prism.marlin.cubic_inc_d1 = " 208 + MarlinProperties.getCubicIncD1()); 209 logInfo("prism.marlin.quad_dec_d2 = " 210 + MarlinProperties.getQuadDecD2()); 211 212 logInfo("Renderer settings:"); 213 logInfo("CUB_DEC_BND = " + Renderer.CUB_DEC_BND); 214 logInfo("CUB_INC_BND = " + Renderer.CUB_INC_BND); 215 logInfo("QUAD_DEC_BND = " + Renderer.QUAD_DEC_BND); 216 217 logInfo("INITIAL_EDGES_CAPACITY = " 218 + MarlinConst.INITIAL_EDGES_CAPACITY); 219 logInfo("INITIAL_CROSSING_COUNT = " 220 + MarlinConst.INITIAL_CROSSING_COUNT); 221 222 logInfo("==========================================================" 223 + "====================="); 224 } 225 226 /** 227 * Get the RendererContext instance dedicated to the current thread 228 * @return RendererContext instance 229 */ 230 @SuppressWarnings({"unchecked"}) 231 public static RendererContext getRendererContext() { 232 final RendererContext rdrCtx = RDR_CTX_PROVIDER.acquire(); 233 if (DO_MONITORS) { 234 rdrCtx.stats.mon_pre_getAATileGenerator.start(); 235 } 236 return rdrCtx; 237 } 238 239 /** 240 * Reset and return the given RendererContext instance for reuse 241 * @param rdrCtx RendererContext instance 242 */ 243 public static void returnRendererContext(final RendererContext rdrCtx) { 244 rdrCtx.dispose(); 245 246 if (DO_MONITORS) { 247 rdrCtx.stats.mon_pre_getAATileGenerator.stop(); 248 } 249 RDR_CTX_PROVIDER.release(rdrCtx); 250 } 251 }