StrikeCache.java revision 2362
2362N/A * Copyright (c) 2003, 2008, 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 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/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, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/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. 0N/AA cache of strikes is maintained via Reference objects. 0N/AThis helps in two ways : 0N/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 0N/A * strikes kept around for the platform or locale. 0N/A * Since no attempt is made to ensure uniqueness or ensure synchronized 0N/A * access there is no guarantee that this cache will ensure that unique 0N/A * strikes are cached. Every time a strike is looked up it is added 0N/A * to the current index in this cache. All this cache has to do to be 0N/A * worthwhile is prevent excessive cache flushing of strikes that are 0N/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 0N/A //Can also get address size from Unsafe class :- 0N/A //nativeAddressSize = unsafe.addressSize(); 0N/A /* Allow a client to override the reference type used to 0N/A * cache strikes. The default is "soft" which hints to keep 0N/A * the strikes around. This property allows the client to 0N/A * override this to "weak" which hint to the GC to free 0N/A * memory more agressively. 0N/A /* NB Now making multiple JNI calls in this case. 0N/A * But assuming that there's a reasonable amount of locality 0N/A * rather than sparse references then it should be OK. 0N/A /* native will only free the scaler context once */ 0N/A /* This may appear inefficient but it should only be invoked 0N/A * for a strike that never was asked to rasterise a glyph. 979N/A /* Rarely a strike may have been created that never cached 979N/A * any glyphs. In this case we still want to free the scaler 430N/A // we need to execute the strike disposal on the rendering thread 430N/A // because they may be accessed on that thread at the time of the 430N/A // disposal (for example, when the accel. cache is invalidated) 1886N/A // Whilst this is a bit heavyweight, in most applications 1886N/A // strike disposal is a relatively infrequent operation, so it 1886N/A // doesn't matter. But in some tests that use vast numbers 1886N/A // of strikes, the switching back and forth is measurable. 1886N/A // So the "pollRemove" call is added to batch up the work. 1886N/A // If we are polling we know we've already been called back 1886N/A // and can directly dispose the record. 1886N/A // Also worrisome is the necessity of getting a GC here. 0N/A /* Some strikes may have no disposer as there's nothing 0N/A * for them to free, as they allocated no native resource 0N/A * eg, if they did not allocate resources because of a problem, 0N/A * or they never hold native resources. So they create no disposer. 0N/A * But any strike that reaches here that has a null disposer is 0N/A * a potential memory leak.