/*
* Copyright (c) 2007, 2018, 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.marlin;
import java.security.AccessController;
import static com.sun.marlin.MarlinUtils.logInfo;
import com.sun.util.reentrant.ReentrantContextProvider;
import com.sun.util.reentrant.ReentrantContextProviderCLQ;
import com.sun.util.reentrant.ReentrantContextProviderTL;
import com.sun.javafx.geom.PathIterator;
import com.sun.prism.BasicStroke;
import java.security.PrivilegedAction;
Marlin RendererEngine implementation (derived from Pisces)
/**
* Marlin RendererEngine implementation (derived from Pisces)
*/
public final class DMarlinRenderingEngine implements MarlinConst
{
Private constructor to prevent instantiation.
/**
* Private constructor to prevent instantiation.
*/
private DMarlinRenderingEngine() {
}
static {
if (PathIterator.WIND_NON_ZERO != WIND_NON_ZERO ||
PathIterator.WIND_EVEN_ODD != WIND_EVEN_ODD ||
BasicStroke.JOIN_MITER != JOIN_MITER ||
BasicStroke.JOIN_ROUND != JOIN_ROUND ||
BasicStroke.JOIN_BEVEL != JOIN_BEVEL ||
BasicStroke.CAP_BUTT != CAP_BUTT ||
BasicStroke.CAP_ROUND != CAP_ROUND ||
BasicStroke.CAP_SQUARE != CAP_SQUARE)
{
throw new InternalError("mismatched renderer constants");
}
}
// --- DRendererContext handling ---
// use ThreadLocal or ConcurrentLinkedQueue to get one DRendererContext
private static final boolean USE_THREAD_LOCAL;
// reference type stored in either TL or CLQ
static final int REF_TYPE;
// Per-thread DRendererContext
private static final ReentrantContextProvider<DRendererContext> RDR_CTX_PROVIDER;
// Static initializer to use TL or CLQ mode
static {
USE_THREAD_LOCAL = MarlinProperties.isUseThreadLocal();
// Soft reference by default:
final String refType = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> {
String value = System.getProperty("prism.marlin.useRef");
return (value == null) ? "soft" : value;
});
switch (refType) {
default:
case "soft":
REF_TYPE = ReentrantContextProvider.REF_SOFT;
break;
case "weak":
REF_TYPE = ReentrantContextProvider.REF_WEAK;
break;
case "hard":
REF_TYPE = ReentrantContextProvider.REF_HARD;
break;
}
if (USE_THREAD_LOCAL) {
RDR_CTX_PROVIDER = new ReentrantContextProviderTL<DRendererContext>(REF_TYPE)
{
@Override
protected DRendererContext newContext() {
return DRendererContext.createContext();
}
};
} else {
RDR_CTX_PROVIDER = new ReentrantContextProviderCLQ<DRendererContext>(REF_TYPE)
{
@Override
protected DRendererContext newContext() {
return DRendererContext.createContext();
}
};
}
logSettings(DRenderer.class.getName());
}
private static boolean SETTINGS_LOGGED = !ENABLE_LOGS;
public static void logSettings(final String reClass) {
// log information at startup
if (SETTINGS_LOGGED) {
return;
}
SETTINGS_LOGGED = true;
String refType;
switch (REF_TYPE) {
default:
case ReentrantContextProvider.REF_HARD:
refType = "hard";
break;
case ReentrantContextProvider.REF_SOFT:
refType = "soft";
break;
case ReentrantContextProvider.REF_WEAK:
refType = "weak";
break;
}
logInfo("=========================================================="
+ "=====================");
logInfo("Marlin software rasterizer = ENABLED");
logInfo("Version = ["
+ Version.getVersion() + "]");
logInfo("prism.marlin = "
+ reClass);
logInfo("prism.marlin.useThreadLocal = "
+ USE_THREAD_LOCAL);
logInfo("prism.marlin.useRef = "
+ refType);
logInfo("prism.marlin.edges = "
+ MarlinConst.INITIAL_EDGES_COUNT);
logInfo("prism.marlin.pixelWidth = "
+ MarlinConst.INITIAL_PIXEL_WIDTH);
logInfo("prism.marlin.pixelHeight = "
+ MarlinConst.INITIAL_PIXEL_HEIGHT);
logInfo("prism.marlin.profile = "
+ (MarlinProperties.isProfileQuality() ?
"quality" : "speed"));
logInfo("prism.marlin.subPixel_log2_X = "
+ MarlinConst.SUBPIXEL_LG_POSITIONS_X);
logInfo("prism.marlin.subPixel_log2_Y = "
+ MarlinConst.SUBPIXEL_LG_POSITIONS_Y);
logInfo("prism.marlin.blockSize_log2 = "
+ MarlinConst.BLOCK_SIZE_LG);
// RLE / blockFlags settings
logInfo("prism.marlin.forceRLE = "
+ MarlinProperties.isForceRLE());
logInfo("prism.marlin.forceNoRLE = "
+ MarlinProperties.isForceNoRLE());
logInfo("prism.marlin.useTileFlags = "
+ MarlinProperties.isUseTileFlags());
logInfo("prism.marlin.useTileFlags.useHeuristics = "
+ MarlinProperties.isUseTileFlagsWithHeuristics());
logInfo("prism.marlin.rleMinWidth = "
+ MarlinConst.RLE_MIN_WIDTH);
// optimisation parameters
logInfo("prism.marlin.useSimplifier = "
+ MarlinConst.USE_SIMPLIFIER);
logInfo("prism.marlin.usePathSimplifier= "
+ MarlinConst.USE_PATH_SIMPLIFIER);
logInfo("prism.marlin.pathSimplifier.pixTol = "
+ MarlinProperties.getPathSimplifierPixelTolerance());
logInfo("prism.marlin.clip = "
+ MarlinProperties.isDoClip());
logInfo("prism.marlin.clip.runtime.enable = "
+ MarlinProperties.isDoClipRuntimeFlag());
logInfo("prism.marlin.clip.subdivider = "
+ MarlinProperties.isDoClipSubdivider());
logInfo("prism.marlin.clip.subdivider.minLength = "
+ MarlinProperties.getSubdividerMinLength());
// debugging parameters
logInfo("prism.marlin.doStats = "
+ MarlinConst.DO_STATS);
logInfo("prism.marlin.doMonitors = "
+ MarlinConst.DO_MONITORS);
logInfo("prism.marlin.doChecks = "
+ MarlinConst.DO_CHECKS);
// logging parameters
logInfo("prism.marlin.log = "
+ MarlinConst.ENABLE_LOGS);
logInfo("prism.marlin.useLogger = "
+ MarlinConst.USE_LOGGER);
logInfo("prism.marlin.logCreateContext = "
+ MarlinConst.LOG_CREATE_CONTEXT);
logInfo("prism.marlin.logUnsafeMalloc = "
+ MarlinConst.LOG_UNSAFE_MALLOC);
// quality settings
logInfo("prism.marlin.curve_len_err = "
+ MarlinProperties.getCurveLengthError());
logInfo("prism.marlin.cubic_dec_d2 = "
+ MarlinProperties.getCubicDecD2());
logInfo("prism.marlin.cubic_inc_d1 = "
+ MarlinProperties.getCubicIncD1());
logInfo("prism.marlin.quad_dec_d2 = "
+ MarlinProperties.getQuadDecD2());
logInfo("Renderer settings:");
logInfo("CUB_DEC_BND = " + DRenderer.CUB_DEC_BND);
logInfo("CUB_INC_BND = " + DRenderer.CUB_INC_BND);
logInfo("QUAD_DEC_BND = " + DRenderer.QUAD_DEC_BND);
logInfo("INITIAL_EDGES_CAPACITY = "
+ MarlinConst.INITIAL_EDGES_CAPACITY);
logInfo("INITIAL_CROSSING_COUNT = "
+ DRenderer.INITIAL_CROSSING_COUNT);
logInfo("=========================================================="
+ "=====================");
}
Get the DRendererContext instance dedicated to the current thread
Returns: DRendererContext instance
/**
* Get the DRendererContext instance dedicated to the current thread
* @return DRendererContext instance
*/
@SuppressWarnings({"unchecked"})
public static DRendererContext getRendererContext() {
final DRendererContext rdrCtx = RDR_CTX_PROVIDER.acquire();
if (DO_MONITORS) {
rdrCtx.stats.mon_pre_getAATileGenerator.start();
}
return rdrCtx;
}
Reset and return the given DRendererContext instance for reuse
Params: - rdrCtx – DRendererContext instance
/**
* Reset and return the given DRendererContext instance for reuse
* @param rdrCtx DRendererContext instance
*/
public static void returnRendererContext(final DRendererContext rdrCtx) {
rdrCtx.dispose();
if (DO_MONITORS) {
rdrCtx.stats.mon_pre_getAATileGenerator.stop();
}
RDR_CTX_PROVIDER.release(rdrCtx);
}
}