Source Code Cross Referenced for SurfaceDataProxy.java in  » 6.0-JDK-Modules-sun » java2d » sun » java2d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » java2d » sun.java2d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.java2d;
027:
028:        import java.awt.Color;
029:        import java.awt.Rectangle;
030:        import java.awt.AlphaComposite;
031:        import java.awt.GraphicsEnvironment;
032:
033:        import sun.awt.DisplayChangedListener;
034:        import sun.java2d.StateTrackable.State;
035:        import sun.java2d.loops.CompositeType;
036:        import sun.java2d.loops.SurfaceType;
037:        import sun.java2d.loops.Blit;
038:        import sun.java2d.loops.BlitBg;
039:        import sun.awt.image.SurfaceManager;
040:        import sun.awt.image.SurfaceManager.FlushableCacheData;
041:
042:        import java.security.AccessController;
043:        import sun.security.action.GetPropertyAction;
044:
045:        /**
046:         * The proxy class encapsulates the logic for managing alternate
047:         * SurfaceData representations of a primary SurfaceData.
048:         * The main class will handle tracking the state changes of the
049:         * primary SurfaceData and updating the associated SurfaceData
050:         * proxy variants.
051:         * <p>
052:         * Subclasses have 2 main responsibilities:
053:         * <ul>
054:         * <li> Override the isSupportedOperation() method to determine if
055:         *      a given operation can be accelerated with a given source
056:         *      SurfaceData
057:         * <li> Override the validateSurfaceData() method to create or update
058:         *      a given accelerated surface to hold the pixels for the indicated
059:         *      source SurfaceData
060:         * </ul>
061:         * If necessary, a subclass may also override the updateSurfaceData
062:         * method to transfer the pixels to the accelerated surface.
063:         * By default the parent class will transfer the pixels using a
064:         * standard Blit operation between the two SurfaceData objects.
065:         */
066:        public abstract class SurfaceDataProxy implements 
067:                DisplayChangedListener, SurfaceManager.FlushableCacheData {
068:            private static boolean cachingAllowed;
069:            private static int defaultThreshold;
070:
071:            static {
072:                cachingAllowed = true;
073:                String manimg = (String) AccessController
074:                        .doPrivileged(new GetPropertyAction(
075:                                "sun.java2d.managedimages"));
076:                if (manimg != null && manimg.equals("false")) {
077:                    cachingAllowed = false;
078:                    System.out.println("Disabling managed images");
079:                }
080:
081:                defaultThreshold = 1;
082:                String num = (String) AccessController
083:                        .doPrivileged(new GetPropertyAction(
084:                                "sun.java2d.accthreshold"));
085:                if (num != null) {
086:                    try {
087:                        int parsed = Integer.parseInt(num);
088:                        if (parsed >= 0) {
089:                            defaultThreshold = parsed;
090:                            System.out
091:                                    .println("New Default Acceleration Threshold: "
092:                                            + defaultThreshold);
093:                        }
094:                    } catch (NumberFormatException e) {
095:                        System.err.println("Error setting new threshold:" + e);
096:                    }
097:                }
098:            }
099:
100:            public static boolean isCachingAllowed() {
101:                return cachingAllowed;
102:            }
103:
104:            /**
105:             * Determine if an alternate form for the srcData is needed
106:             * and appropriate from the given operational parameters.
107:             */
108:            public abstract boolean isSupportedOperation(SurfaceData srcData,
109:                    int txtype, CompositeType comp, Color bgColor);
110:
111:            /**
112:             * Construct an alternate form of the given SurfaceData.
113:             * The contents of the returned SurfaceData may be undefined
114:             * since the calling code will take care of updating the
115:             * contents with a subsequent call to updateSurfaceData.
116:             * <p>
117:             * If the method returns null then there was a problem with
118:             * allocating the accelerated surface.  The getRetryTracker()
119:             * method will be called to track when to attempt another
120:             * revalidation.
121:             */
122:            public abstract SurfaceData validateSurfaceData(
123:                    SurfaceData srcData, SurfaceData cachedData, int w, int h);
124:
125:            /**
126:             * If the subclass is unable to validate or create a cached
127:             * SurfaceData then this method will be used to get a
128:             * StateTracker object that will indicate when to attempt
129:             * to validate the surface again.  Subclasses may return
130:             * trackers which count down an ever increasing threshold
131:             * to provide hysteresis on creating surfaces during low
132:             * memory conditions.  The default implementation just waits
133:             * another "threshold" number of accesses before trying again.
134:             */
135:            public StateTracker getRetryTracker(SurfaceData srcData) {
136:                return new CountdownTracker(threshold);
137:            }
138:
139:            public static class CountdownTracker implements  StateTracker {
140:                private int countdown;
141:
142:                public CountdownTracker(int threshold) {
143:                    this .countdown = threshold;
144:                }
145:
146:                public synchronized boolean isCurrent() {
147:                    return (--countdown >= 0);
148:                }
149:            }
150:
151:            /**
152:             * This instance is for cases where a caching implementation
153:             * determines that a particular source image will never need
154:             * to be cached - either the source SurfaceData was of an
155:             * incompatible type, or it was in an UNTRACKABLE state or
156:             * some other factor is discovered that permanently prevents
157:             * acceleration or caching.
158:             * This class optimally implements NOP variants of all necessary
159:             * methods to avoid caching with a minimum of fuss.
160:             */
161:            public static SurfaceDataProxy UNCACHED = new SurfaceDataProxy(0) {
162:                @Override
163:                public boolean isAccelerated() {
164:                    return false;
165:                }
166:
167:                @Override
168:                public boolean isSupportedOperation(SurfaceData srcData,
169:                        int txtype, CompositeType comp, Color bgColor) {
170:                    return false;
171:                }
172:
173:                @Override
174:                public SurfaceData validateSurfaceData(SurfaceData srcData,
175:                        SurfaceData cachedData, int w, int h) {
176:                    throw new InternalError(
177:                            "UNCACHED should never validate SDs");
178:                }
179:
180:                @Override
181:                public SurfaceData replaceData(SurfaceData srcData, int txtype,
182:                        CompositeType comp, Color bgColor) {
183:                    // Not necessary to override this, but doing so is faster
184:                    return srcData;
185:                }
186:            };
187:
188:            // The number of attempts to copy from a STABLE source before
189:            // a cached copy is created or updated.
190:            private int threshold;
191:
192:            /*
193:             * Source tracking data
194:             *
195:             * Every time that srcTracker is out of date we will reset numtries
196:             * to threshold and set the cacheTracker to one that is non-current.
197:             * numtries will then count down to 0 at which point the cacheTracker
198:             * will remind us that we need to update the cachedSD before we can
199:             * use it.
200:             *
201:             * Note that since these fields interrelate we should synchronize
202:             * whenever we update them, but it should be OK to read them
203:             * without synchronization.
204:             */
205:            private StateTracker srcTracker;
206:            private int numtries;
207:
208:            /*
209:             * Cached data
210:             *
211:             * We cache a SurfaceData created by the subclass in cachedSD and
212:             * track its state (isValid and !surfaceLost) in cacheTracker.
213:             *
214:             * Also, when we want to note that cachedSD needs to be updated
215:             * we replace the cacheTracker with a NEVER_CURRENT tracker which
216:             * will cause us to try to revalidate and update the surface on
217:             * next use.
218:             */
219:            private SurfaceData cachedSD;
220:            private StateTracker cacheTracker;
221:
222:            /*
223:             * Are we still the best object to control caching of data
224:             * for the source image?
225:             */
226:            private boolean valid;
227:
228:            /**
229:             * Create a SurfaceData proxy manager that attempts to create
230:             * and cache a variant copy of the source SurfaceData after
231:             * the default threshold number of attempts to copy from the
232:             * STABLE source.
233:             */
234:            public SurfaceDataProxy() {
235:                this (defaultThreshold);
236:            }
237:
238:            /**
239:             * Create a SurfaceData proxy manager that attempts to create
240:             * and cache a variant copy of the source SurfaceData after
241:             * the specified threshold number of attempts to copy from
242:             * the STABLE source.
243:             */
244:            public SurfaceDataProxy(int threshold) {
245:                this .threshold = threshold;
246:
247:                this .srcTracker = StateTracker.NEVER_CURRENT;
248:                // numtries will be reset on first use
249:                this .cacheTracker = StateTracker.NEVER_CURRENT;
250:
251:                this .valid = true;
252:            }
253:
254:            /**
255:             * Returns true iff this SurfaceData proxy is still the best
256:             * way to control caching of the given source on the given
257:             * destination.
258:             */
259:            public boolean isValid() {
260:                return valid;
261:            }
262:
263:            /**
264:             * Sets the valid state to false so that the next time this
265:             * proxy is fetched to generate a replacement SurfaceData,
266:             * the code in SurfaceData knows to replace the proxy first.
267:             */
268:            public void invalidate() {
269:                this .valid = false;
270:            }
271:
272:            /**
273:             * Flush all cached resources as per the FlushableCacheData interface.
274:             * The deaccelerated parameter indicates if the flush is
275:             * happening because the associated surface is no longer
276:             * being accelerated (for instance the acceleration priority
277:             * is set below the threshold needed for acceleration).
278:             * Returns a boolean that indicates if the cached object is
279:             * no longer needed and should be removed from the cache.
280:             */
281:            public boolean flush(boolean deaccelerated) {
282:                if (deaccelerated) {
283:                    invalidate();
284:                }
285:                flush();
286:                return !isValid();
287:            }
288:
289:            /**
290:             * Actively flushes (drops and invalidates) the cached surface
291:             * so that it can be reclaimed quickly.
292:             */
293:            public synchronized void flush() {
294:                SurfaceData csd = this .cachedSD;
295:                this .cachedSD = null;
296:                this .cacheTracker = StateTracker.NEVER_CURRENT;
297:                if (csd != null) {
298:                    csd.flush();
299:                }
300:            }
301:
302:            /**
303:             * Returns true iff this SurfaceData proxy is still valid
304:             * and if it has a currently cached replacement that is also
305:             * valid and current.
306:             */
307:            public boolean isAccelerated() {
308:                return (isValid() && srcTracker.isCurrent() && cacheTracker
309:                        .isCurrent());
310:            }
311:
312:            /**
313:             * This method should be called from subclasses which create
314:             * cached SurfaceData objects that depend on the current
315:             * properties of the display.
316:             */
317:            protected void activateDisplayListener() {
318:                GraphicsEnvironment ge = GraphicsEnvironment
319:                        .getLocalGraphicsEnvironment();
320:                // We could have a HeadlessGE at this point, so double-check before
321:                // assuming anything.
322:                // Also, no point in listening to display change events if
323:                // the image is never going to be accelerated.
324:                if (ge instanceof  SunGraphicsEnvironment) {
325:                    ((SunGraphicsEnvironment) ge)
326:                            .addDisplayChangedListener(this );
327:                }
328:            }
329:
330:            /**
331:             * Invoked when the display mode has changed.
332:             * This method will invalidate and drop the internal cachedSD object.
333:             */
334:            public void displayChanged() {
335:                flush();
336:            }
337:
338:            /**
339:             * Invoked when the palette has changed.
340:             */
341:            public void paletteChanged() {
342:                // We could potentially get away with just resetting cacheTracker
343:                // here but there is a small window of vulnerability in the
344:                // replaceData method where we could be just finished with
345:                // updating the cachedSD when this method is called and even
346:                // though we set a non-current cacheTracker here it will then
347:                // immediately get set to a current one by the thread that is
348:                // updating the cachedSD.  It is safer to just replace the
349:                // srcTracker with a non-current version that will trigger a
350:                // full update cycle the next time this proxy is used.
351:                // The downside is having to go through a full threshold count
352:                // before we can update and use our cache again, but palette
353:                // changes should be relatively rare...
354:                this .srcTracker = StateTracker.NEVER_CURRENT;
355:            }
356:
357:            /**
358:             * This method attempts to replace the srcData with a cached version.
359:             * It relies on the subclass to determine if the cached version will
360:             * be useful given the operational parameters.
361:             * This method checks any preexisting cached copy for being "up to date"
362:             * and tries to update it if it is stale or non-existant and the
363:             * appropriate number of accesses have occured since it last was stale.
364:             * <p>
365:             * An outline of the process is as follows:
366:             * <ol>
367:             * <li> Check the operational parameters (txtype, comp, bgColor)
368:             *      to make sure that the operation is supported.  Return the
369:             *      original SurfaceData if the operation cannot be accelerated.
370:             * <li> Check the tracker for the source surface to see if it has
371:             *      remained stable since it was last cached.  Update the state
372:             *      variables to cause both a threshold countdown and an update
373:             *      of the cached copy if it is not.  (Setting cacheTracker to
374:             *      NEVER_CURRENT effectively marks it as "needing to be updated".)
375:             * <li> Check the tracker for the cached copy to see if is still
376:             *      valid and up to date.  Note that the cacheTracker may be
377:             *      non-current if either something happened to the cached copy
378:             *      (eg. surfaceLost) or if the source was out of date and the
379:             *      cacheTracker was set to NEVER_CURRENT to force an update.
380:             *      Decrement the countdown and copy the source to the cache
381:             *      as necessary and then update the variables to show that
382:             *      the cached copy is stable.
383:             * </ol>
384:             */
385:            public SurfaceData replaceData(SurfaceData srcData, int txtype,
386:                    CompositeType comp, Color bgColor) {
387:                if (isSupportedOperation(srcData, txtype, comp, bgColor)) {
388:                    // First deal with tracking the source.
389:                    if (!srcTracker.isCurrent()) {
390:                        synchronized (this ) {
391:                            this .numtries = threshold;
392:                            this .srcTracker = srcData.getStateTracker();
393:                            this .cacheTracker = StateTracker.NEVER_CURRENT;
394:                        }
395:
396:                        if (!srcTracker.isCurrent()) {
397:                            // Dynamic or Untrackable (or a very recent modification)
398:                            if (srcData.getState() == State.UNTRACKABLE) {
399:                                // UNTRACKABLE means we can never cache again.
400:
401:                                // Invalidate so we get replaced next time we are used
402:                                // (presumably with an UNCACHED proxy).
403:                                invalidate();
404:
405:                                // Aggressively drop our reference to the cachedSD
406:                                // in case this proxy is not consulted again (and
407:                                // thus replaced) for a long time.
408:                                flush();
409:                            }
410:                            return srcData;
411:                        }
412:                    }
413:
414:                    // Then deal with checking the validity of the cached SurfaceData
415:                    SurfaceData csd = this .cachedSD;
416:                    if (!cacheTracker.isCurrent()) {
417:                        // Next make sure the dust has settled
418:                        synchronized (this ) {
419:                            if (numtries > 0) {
420:                                --numtries;
421:                                return srcData;
422:                            }
423:                        }
424:
425:                        Rectangle r = srcData.getBounds();
426:                        int w = r.width;
427:                        int h = r.height;
428:
429:                        // Snapshot the tracker in case it changes while
430:                        // we are updating the cached SD...
431:                        StateTracker curTracker = srcTracker;
432:
433:                        csd = validateSurfaceData(srcData, csd, w, h);
434:                        if (csd == null) {
435:                            synchronized (this ) {
436:                                if (curTracker == srcTracker) {
437:                                    this .cacheTracker = getRetryTracker(srcData);
438:                                    this .cachedSD = null;
439:                                }
440:                            }
441:                            return srcData;
442:                        }
443:
444:                        updateSurfaceData(srcData, csd, w, h);
445:                        if (!csd.isValid()) {
446:                            return srcData;
447:                        }
448:
449:                        synchronized (this ) {
450:                            // We only reset these variables if the tracker from
451:                            // before the surface update is still in use and current
452:                            // Note that we must use a srcTracker that was fetched
453:                            // from before the update process to make sure that we
454:                            // do not lose some pixel changes in the shuffle.
455:                            if (curTracker == srcTracker
456:                                    && curTracker.isCurrent()) {
457:                                this .cacheTracker = csd.getStateTracker();
458:                                this .cachedSD = csd;
459:                            }
460:                        }
461:                    }
462:
463:                    if (csd != null) {
464:                        return csd;
465:                    }
466:                }
467:
468:                return srcData;
469:            }
470:
471:            /**
472:             * This is the default implementation for updating the cached
473:             * SurfaceData from the source (primary) SurfaceData.
474:             * A simple Blit is used to copy the pixels from the source to
475:             * the destination SurfaceData.
476:             * A subclass can override this implementation if a more complex
477:             * operation is required to update its cached copies.
478:             */
479:            public void updateSurfaceData(SurfaceData srcData,
480:                    SurfaceData dstData, int w, int h) {
481:                SurfaceType srcType = srcData.getSurfaceType();
482:                SurfaceType dstType = dstData.getSurfaceType();
483:                Blit blit = Blit.getFromCache(srcType, CompositeType.SrcNoEa,
484:                        dstType);
485:                blit.Blit(srcData, dstData, AlphaComposite.Src, null, 0, 0, 0,
486:                        0, w, h);
487:                dstData.markDirty();
488:            }
489:
490:            /**
491:             * This is an alternate implementation for updating the cached
492:             * SurfaceData from the source (primary) SurfaceData using a
493:             * background color for transparent pixels.
494:             * A simple BlitBg is used to copy the pixels from the source to
495:             * the destination SurfaceData with the specified bgColor.
496:             * A subclass can override the normal updateSurfaceData method
497:             * and call this implementation instead if it wants to use color
498:             * keying for bitmask images.
499:             */
500:            public void updateSurfaceDataBg(SurfaceData srcData,
501:                    SurfaceData dstData, int w, int h, Color bgColor) {
502:                SurfaceType srcType = srcData.getSurfaceType();
503:                SurfaceType dstType = dstData.getSurfaceType();
504:                BlitBg blitbg = BlitBg.getFromCache(srcType,
505:                        CompositeType.SrcNoEa, dstType);
506:                blitbg.BlitBg(srcData, dstData, AlphaComposite.Src, null,
507:                        bgColor, 0, 0, 0, 0, w, h);
508:                dstData.markDirty();
509:            }
510:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.