StrikeCache.java revision 3611
4185N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 1472N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * or visit www.oracle.com if you need additional information or have any 0N/AA FontStrike is the keeper of scaled glyph image data which is expensive 0N/Ato compute so needs to be cached. 0N/ASo long as that data may be being used it cannot be invalidated. 0N/AYet we also need to limit the amount of native memory and number of 0N/Astrike objects in use. 0N/AFor scaleability and ease of use, a key goal is multi-threaded read 0N/Aaccess to a strike, so that it may be shared by multiple client objects, 0N/Apotentially executing on different threads, with no special reference 0N/Aburden of keeping track of strike references to the SG2D and other clients. 610N/AA cache of strikes is maintained via Reference objects. 610N/AThis helps in two ways : 4185N/A1. The VM will free references when memory is low or they have not been 0N/A2. Reference queues provide a way to get notification of this so we can 0N/Afree native memory resources. 0N/A /* Reference objects may have their referents cleared when GC chooses. 0N/A * During application client start-up there is typically at least one 0N/A * GC which causes the hotspot VM to clear soft (not just weak) references 0N/A * Thus not only is there a GC pause, but the work done do rasterise 0N/A * glyphs that are fairly certain to be needed again almost immediately 0N/A * is thrown away. So for performance reasons a simple optimisation is to 0N/A * keep up to 8 strong references to strikes to reduce the chance of 0N/A * GC'ing strikes that have been used recently. Note that this may not 0N/A * suffice in Solaris UTF-8 locales where a single composite strike may be 0N/A * composed of 15 individual strikes, plus the composite strike. 0N/A * And this assumes the new architecture doesn't maintain strikes for 0N/A * natively accessed bitmaps. It may be worth "tuning" the number of 4185N/A * strikes kept around for the platform or locale. 4185N/A * Since no attempt is made to ensure uniqueness or ensure synchronized 4185N/A * access there is no guarantee that this cache will ensure that unique 4185N/A * strikes are cached. Every time a strike is looked up it is added 4185N/A * to the current index in this cache. All this cache has to do to be 4185N/A * worthwhile is prevent excessive cache flushing of strikes that are 4185N/A * referenced frequently. The logic that adds references here could be 0N/A * tweaked to keep only strikes that represent untransformed, screen 0N/A * sizes as that's the typical performance case. 0N/A * Native sizes and offsets for glyph cache 0N/A * There are 10 values. 0N/A /* Native method used to return information used for unsafe 0N/A * access to native data. 0N/A * return values as follows:- 0N/A * arr[1] = size of a GlyphInfo 0N/A * arr[2] = offset of advanceX 0N/A * arr[3] = offset of advanceY 0N/A * arr[4] = offset of width 0N/A * arr[5] = offset of height 0N/A * arr[6] = offset of rowBytes 0N/A * arr[7] = offset of topLeftX 0N/A * arr[8] = offset of topLeftY 0N/A * arr[9] = offset of pixel data. 0N/A * arr[10] = address of a GlyphImageRef representing the invisible glyph //Can also get address size from Unsafe class :- //nativeAddressSize = unsafe.addressSize(); throw new InternalError(
"Unexpected address size for font data: " +
/* Allow a client to override the reference type used to * cache strikes. The default is "soft" which hints to keep * the strikes around. This property allows the client to * override this to "weak" which hint to the GC to free * memory more agressively. /* NB Now making multiple JNI calls in this case. * But assuming that there's a reasonable amount of locality * rather than sparse references then it should be OK. /* native will only free the scaler context once */ /* This may appear inefficient but it should only be invoked * for a strike that never was asked to rasterise a glyph. /* Rarely a strike may have been created that never cached * any glyphs. In this case we still want to free the scaler // we need to execute the strike disposal on the rendering thread // because they may be accessed on that thread at the time of the // disposal (for example, when the accel. cache is invalidated) // Whilst this is a bit heavyweight, in most applications // strike disposal is a relatively infrequent operation, so it // doesn't matter. But in some tests that use vast numbers // of strikes, the switching back and forth is measurable. // So the "pollRemove" call is added to batch up the work. // If we are polling we know we've already been called back // and can directly dispose the record. // Also worrisome is the necessity of getting a GC here. // Any reference by the disposers to the native glyph ptrs // must be done before this returns. // Any reference by the disposers to the native glyph ptrs // must be done before this returns. /* Some strikes may have no disposer as there's nothing * for them to free, as they allocated no native resource * eg, if they did not allocate resources because of a problem, * or they never hold native resources. So they create no disposer. * But any strike that reaches here that has a null disposer is * a potential memory leak.