diff options
author | ceisserer <none@none> | 2010-05-28 11:37:44 -0700 |
---|---|---|
committer | ceisserer <none@none> | 2010-05-28 11:37:44 -0700 |
commit | 15e677fe29164e1d11f364eba1c541587ddb239e (patch) | |
tree | 4b6071c16cc574276e56e03df5af421a9036fbd4 /src/share | |
parent | cd0377f26ab30e5455bb31546b2609c56e2eaa01 (diff) |
6307603: [X11] Use RENDER extension for complex operations done in software
Reviewed-by: bae, igor, prr
Diffstat (limited to 'src/share')
10 files changed, 151 insertions, 20 deletions
diff --git a/src/share/classes/sun/font/GlyphDisposedListener.java b/src/share/classes/sun/font/GlyphDisposedListener.java new file mode 100644 index 000000000..41a38380c --- /dev/null +++ b/src/share/classes/sun/font/GlyphDisposedListener.java @@ -0,0 +1,32 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.font; + +import java.util.*; + +public interface GlyphDisposedListener { + public void glyphDisposed(ArrayList<Long> glyphs); +} diff --git a/src/share/classes/sun/font/StrikeCache.java b/src/share/classes/sun/font/StrikeCache.java index 9e5b02a86..dd9b1b6da 100644 --- a/src/share/classes/sun/font/StrikeCache.java +++ b/src/share/classes/sun/font/StrikeCache.java @@ -31,6 +31,7 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; +import java.util.*; import sun.java2d.Disposer; import sun.java2d.pipe.BufferedContext; @@ -66,6 +67,9 @@ public final class StrikeCache { static ReferenceQueue refQueue = Disposer.getQueue(); + static ArrayList<GlyphDisposedListener> disposeListeners = new ArrayList<GlyphDisposedListener>(1); + + /* Reference objects may have their referents cleared when GC chooses. * During application client start-up there is typically at least one * GC which causes the hotspot VM to clear soft (not just weak) references @@ -108,6 +112,8 @@ public final class StrikeCache { static int topLeftXOffset; static int topLeftYOffset; static int pixelDataOffset; + static int cacheCellOffset; + static int managedOffset; static long invisibleGlyphPtr; /* Native method used to return information used for unsafe @@ -129,7 +135,7 @@ public final class StrikeCache { static { - long[] nativeInfo = new long[11]; + long[] nativeInfo = new long[13]; getGlyphCacheDescription(nativeInfo); //Can also get address size from Unsafe class :- //nativeAddressSize = unsafe.addressSize(); @@ -144,6 +150,9 @@ public final class StrikeCache { topLeftYOffset = (int)nativeInfo[8]; pixelDataOffset = (int)nativeInfo[9]; invisibleGlyphPtr = nativeInfo[10]; + cacheCellOffset = (int) nativeInfo[11]; + managedOffset = (int) nativeInfo[12]; + if (nativeAddressSize < 4) { throw new InternalError("Unexpected address size for font data: " + nativeAddressSize); @@ -195,10 +204,10 @@ public final class StrikeCache { private static final void doDispose(FontStrikeDisposer disposer) { if (disposer.intGlyphImages != null) { - freeIntMemory(disposer.intGlyphImages, + freeCachedIntMemory(disposer.intGlyphImages, disposer.pScalerContext); } else if (disposer.longGlyphImages != null) { - freeLongMemory(disposer.longGlyphImages, + freeCachedLongMemory(disposer.longGlyphImages, disposer.pScalerContext); } else if (disposer.segIntGlyphImages != null) { /* NB Now making multiple JNI calls in this case. @@ -207,7 +216,7 @@ public final class StrikeCache { */ for (int i=0; i<disposer.segIntGlyphImages.length; i++) { if (disposer.segIntGlyphImages[i] != null) { - freeIntMemory(disposer.segIntGlyphImages[i], + freeCachedIntMemory(disposer.segIntGlyphImages[i], disposer.pScalerContext); /* native will only free the scaler context once */ disposer.pScalerContext = 0L; @@ -218,19 +227,19 @@ public final class StrikeCache { * for a strike that never was asked to rasterise a glyph. */ if (disposer.pScalerContext != 0L) { - freeIntMemory(new int[0], disposer.pScalerContext); + freeCachedIntMemory(new int[0], disposer.pScalerContext); } } else if (disposer.segLongGlyphImages != null) { for (int i=0; i<disposer.segLongGlyphImages.length; i++) { if (disposer.segLongGlyphImages[i] != null) { - freeLongMemory(disposer.segLongGlyphImages[i], + freeCachedLongMemory(disposer.segLongGlyphImages[i], disposer.pScalerContext); disposer.pScalerContext = 0L; disposer.segLongGlyphImages[i] = null; } } if (disposer.pScalerContext != 0L) { - freeLongMemory(new long[0], disposer.pScalerContext); + freeCachedLongMemory(new long[0], disposer.pScalerContext); } } else if (disposer.pScalerContext != 0L) { /* Rarely a strike may have been created that never cached @@ -238,9 +247,9 @@ public final class StrikeCache { * context. */ if (longAddresses()) { - freeLongMemory(new long[0], disposer.pScalerContext); + freeCachedLongMemory(new long[0], disposer.pScalerContext); } else { - freeIntMemory(new int[0], disposer.pScalerContext); + freeCachedIntMemory(new int[0], disposer.pScalerContext); } } } @@ -304,6 +313,68 @@ public final class StrikeCache { private static native void freeIntMemory(int[] glyphPtrs, long pContext); private static native void freeLongMemory(long[] glyphPtrs, long pContext); + private static void freeCachedIntMemory(int[] glyphPtrs, long pContext) { + synchronized(disposeListeners) { + if (disposeListeners.size() > 0) { + ArrayList<Long> gids = null; + + for (int i = 0; i < glyphPtrs.length; i++) { + if (glyphPtrs[i] != 0 && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0 + && unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) { + + if (gids == null) { + gids = new ArrayList<Long>(); + } + gids.add((long) glyphPtrs[i]); + } + } + + if (gids != null) { + notifyDisposeListeners(gids); + } + } + } + + freeIntMemory(glyphPtrs, pContext); + } + + private static void freeCachedLongMemory(long[] glyphPtrs, long pContext) { + synchronized(disposeListeners) { + if (disposeListeners.size() > 0) { + ArrayList<Long> gids = null; + + for (int i=0; i < glyphPtrs.length; i++) { + if (glyphPtrs[i] != 0 + && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0 + && unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) { + + if (gids == null) { + gids = new ArrayList<Long>(); + } + gids.add((long) glyphPtrs[i]); + } + } + + if (gids != null) { + notifyDisposeListeners(gids); + } + } + } + + freeLongMemory(glyphPtrs, pContext); + } + + public static void addGlyphDisposedListener(GlyphDisposedListener listener) { + synchronized(disposeListeners) { + disposeListeners.add(listener); + } + } + + private static void notifyDisposeListeners(ArrayList<Long> glyphs) { + for (GlyphDisposedListener listener : disposeListeners) { + listener.glyphDisposed(glyphs); + } + } public static Reference getStrikeRef(FontStrike strike) { return getStrikeRef(strike, cacheRefTypeWeak); diff --git a/src/share/classes/sun/java2d/pipe/BufferedPaints.java b/src/share/classes/sun/java2d/pipe/BufferedPaints.java index 604590ff6..3ff1b3b15 100644 --- a/src/share/classes/sun/java2d/pipe/BufferedPaints.java +++ b/src/share/classes/sun/java2d/pipe/BufferedPaints.java @@ -307,7 +307,7 @@ public class BufferedPaints { * linear RGB space. Copied directly from the * MultipleGradientPaintContext class. */ - private static int convertSRGBtoLinearRGB(int color) { + public static int convertSRGBtoLinearRGB(int color) { float input, output; input = color / 255.0f; diff --git a/src/share/classes/sun/java2d/pipe/RenderBuffer.java b/src/share/classes/sun/java2d/pipe/RenderBuffer.java index f0b8069a5..cf4e56918 100644 --- a/src/share/classes/sun/java2d/pipe/RenderBuffer.java +++ b/src/share/classes/sun/java2d/pipe/RenderBuffer.java @@ -117,6 +117,11 @@ public class RenderBuffer { curAddress = baseAddress; } + public final RenderBuffer skip(long numBytes) { + curAddress += numBytes; + return this; + } + /** * putByte() methods... */ diff --git a/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine b/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine index 607ff5905..66b2ae9c6 100644 --- a/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine +++ b/src/share/classes/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine @@ -1,2 +1,5 @@ +# Jules Rendering Engine module +sun.java2d.jules.JulesRenderingEngine + # Pisces Rendering Engine module -sun.java2d.pisces.PiscesRenderingEngine +sun.java2d.pisces.PiscesRenderingEngine
\ No newline at end of file diff --git a/src/share/native/sun/font/AccelGlyphCache.c b/src/share/native/sun/font/AccelGlyphCache.c index 73e94a91c..7d293fd7a 100644 --- a/src/share/native/sun/font/AccelGlyphCache.c +++ b/src/share/native/sun/font/AccelGlyphCache.c @@ -325,6 +325,7 @@ AccelGlyphCache_AddCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo) cellInfo->glyphInfo = glyph; cellInfo->nextGCI = glyph->cellInfo; glyph->cellInfo = cellInfo; + glyph->managed = MANAGED_GLYPH; } /** diff --git a/src/share/native/sun/font/fontscalerdefs.h b/src/share/native/sun/font/fontscalerdefs.h index d7fd1fbe6..b83f7e00e 100644 --- a/src/share/native/sun/font/fontscalerdefs.h +++ b/src/share/native/sun/font/fontscalerdefs.h @@ -84,15 +84,26 @@ typedef float t2kScalar; #define t2kScalarAverage(a, b) (((a) + (b)) / (t2kScalar)(2)) + /* managed: 1 means the glyph has a hardware cached + * copy, and its freeing is managed by the the usual + * 2D disposer code. + * A value of 0 means its either unaccelerated (and so has no cellInfos) + * or we want to free this in a different way. + * The field uses previously unused padding, so doesn't enlarge + * the structure. + */ +#define UNMANAGED_GLYPH 0 +#define MANAGED_GLYPH 1 typedef struct GlyphInfo { float advanceX; float advanceY; UInt16 width; UInt16 height; UInt16 rowBytes; + UInt8 managed; float topLeftX; float topLeftY; - struct _CacheCellInfo *cellInfo; + void *cellInfo; UInt8 *image; } GlyphInfo; diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c index 93baaea47..66ec606af 100644 --- a/src/share/native/sun/font/freetypeScaler.c +++ b/src/share/native/sun/font/freetypeScaler.c @@ -782,6 +782,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative( return ptr_to_jlong(glyphInfo); } glyphInfo->cellInfo = NULL; + glyphInfo->managed = UNMANAGED_GLYPH; glyphInfo->rowBytes = width; glyphInfo->width = width; glyphInfo->height = height; @@ -1130,7 +1131,7 @@ static void addToGP(GPData* gpdata, FT_Outline*outline) { current_type = SEG_LINETO; } } else if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_CUBIC) { - /* Bit 1 is meaningful for ‘off’ points only. + /* Bit 1 is meaningful for 'off' points only. If set, it indicates a third-order Bezier arc control point; and a second-order control point if unset. */ current_type = SEG_CUBICTO; diff --git a/src/share/native/sun/font/sunFont.c b/src/share/native/sun/font/sunFont.c index 3bd914518..84fa28f08 100644 --- a/src/share/native/sun/font/sunFont.c +++ b/src/share/native/sun/font/sunFont.c @@ -233,7 +233,8 @@ JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntMemory for (i=0; i< len; i++) { if (ptrs[i] != 0) { GlyphInfo *ginfo = (GlyphInfo *)ptrs[i]; - if (ginfo->cellInfo != NULL) { + if (ginfo->cellInfo != NULL && + ginfo->managed == MANAGED_GLYPH) { // invalidate this glyph's accelerated cache cell AccelGlyphCache_RemoveAllCellInfos(ginfo); } @@ -264,7 +265,8 @@ JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongMemory for (i=0; i< len; i++) { if (ptrs[i] != 0L) { GlyphInfo *ginfo = (GlyphInfo *) jlong_to_ptr(ptrs[i]); - if (ginfo->cellInfo != NULL) { + if (ginfo->cellInfo != NULL && + ginfo->managed == MANAGED_GLYPH) { AccelGlyphCache_RemoveAllCellInfos(ginfo); } free((void*)ginfo); @@ -285,7 +287,7 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription GlyphInfo *info; size_t baseAddr; - if ((*env)->GetArrayLength(env, results) < 10) { + if ((*env)->GetArrayLength(env, results) < 13) { return; } @@ -310,6 +312,9 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription nresults[8] = (size_t)&(info->topLeftY)-baseAddr; nresults[9] = (size_t)&(info->image)-baseAddr; nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */ + nresults[11] = (size_t)&(info->cellInfo)-baseAddr; + nresults[12] = (size_t)&(info->managed)-baseAddr; + (*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0); } diff --git a/src/share/native/sun/java2d/opengl/OGLTextRenderer.c b/src/share/native/sun/java2d/opengl/OGLTextRenderer.c index b709be3cc..fa98114f7 100644 --- a/src/share/native/sun/java2d/opengl/OGLTextRenderer.c +++ b/src/share/native/sun/java2d/opengl/OGLTextRenderer.c @@ -244,6 +244,7 @@ static void OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder) { GLenum pixelFormat; + CacheCellInfo *ccinfo; J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache"); @@ -258,11 +259,12 @@ OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder) } AccelGlyphCache_AddGlyph(glyphCache, glyph); + ccinfo = (CacheCellInfo *) glyph->cellInfo; - if (glyph->cellInfo != NULL) { + if (ccinfo != NULL) { // store glyph image in texture cell j2d_glTexSubImage2D(GL_TEXTURE_2D, 0, - glyph->cellInfo->x, glyph->cellInfo->y, + ccinfo->x, ccinfo->y, glyph->width, glyph->height, pixelFormat, GL_UNSIGNED_BYTE, glyph->image); } @@ -668,7 +670,7 @@ OGLTR_DrawGrayscaleGlyphViaCache(OGLContext *oglc, } } - cell = ginfo->cellInfo; + cell = (CacheCellInfo *) (ginfo->cellInfo); cell->timesRendered++; x1 = (jfloat)x; @@ -871,7 +873,7 @@ OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps, } } - cell = ginfo->cellInfo; + cell = (CacheCellInfo *) (ginfo->cellInfo); cell->timesRendered++; // location of the glyph in the destination's coordinate space |