Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
339f35c4
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
339f35c4
编写于
4月 01, 2014
作者:
A
alexsch
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8035069: [macosx] Loading resolution variants by demand
Reviewed-by: serb, pchelko
上级
4393ad17
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
394 addition
and
96 deletion
+394
-96
src/macosx/classes/com/apple/laf/AquaIcon.java
src/macosx/classes/com/apple/laf/AquaIcon.java
+2
-8
src/macosx/classes/com/apple/laf/AquaImageFactory.java
src/macosx/classes/com/apple/laf/AquaImageFactory.java
+18
-39
src/macosx/classes/com/apple/laf/AquaPainter.java
src/macosx/classes/com/apple/laf/AquaPainter.java
+61
-2
src/macosx/classes/com/apple/laf/AquaUtils.java
src/macosx/classes/com/apple/laf/AquaUtils.java
+1
-10
src/macosx/classes/sun/lwawt/macosx/CImage.java
src/macosx/classes/sun/lwawt/macosx/CImage.java
+4
-17
src/share/classes/sun/awt/AppContext.java
src/share/classes/sun/awt/AppContext.java
+19
-0
src/share/classes/sun/awt/image/ImageCache.java
src/share/classes/sun/awt/image/ImageCache.java
+163
-0
src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java
...e/classes/sun/awt/image/MultiResolutionBufferedImage.java
+125
-19
test/java/awt/image/MultiResolutionImage/NSImageToMultiResolutionImageTest.java
...ltiResolutionImage/NSImageToMultiResolutionImageTest.java
+1
-1
未找到文件。
src/macosx/classes/com/apple/laf/AquaIcon.java
浏览文件 @
339f35c4
...
...
@@ -295,14 +295,8 @@ public class AquaIcon {
}
Image
createImage
()
{
int
w
=
getIconWidth
();
int
h
=
getIconHeight
();
return
new
AquaImageFactory
.
MultiResolutionIconImage
(
AquaUtils
.
getCImageCreator
().
createSystemImageFromSelector
(
selector
,
w
,
h
),
AquaUtils
.
getCImageCreator
().
createSystemImageFromSelector
(
selector
,
2
*
w
,
2
*
h
)
);
return
AquaUtils
.
getCImageCreator
().
createSystemImageFromSelector
(
selector
,
getIconWidth
(),
getIconHeight
());
}
}
}
src/macosx/classes/com/apple/laf/AquaImageFactory.java
浏览文件 @
339f35c4
...
...
@@ -125,16 +125,14 @@ public class AquaImageFactory {
private
static
final
int
kAlertIconSize
=
64
;
static
IconUIResource
getAppIconCompositedOn
(
final
Image
background
)
{
final
BufferedImage
iconImage
=
getAppIconImageCompositedOn
(
background
,
1
);
if
(
background
instanceof
MultiResolutionIconImage
)
{
BufferedImage
background2x
=
((
MultiResolutionIconImage
)
background
).
resolutionVariant
;
BufferedImage
icon2xImage
=
getAppIconImageCompositedOn
(
background2x
,
2
);
return
new
IconUIResource
(
new
ImageIcon
(
new
MultiResolutionIconImage
(
iconImage
,
icon2xImage
)));
if
(
background
instanceof
MultiResolutionBufferedImage
)
{
int
width
=
background
.
getWidth
(
null
);
Image
mrIconImage
=
((
MultiResolutionBufferedImage
)
background
).
map
(
rv
->
getAppIconImageCompositedOn
(
rv
,
rv
.
getWidth
(
null
)
/
width
));
return
new
IconUIResource
(
new
ImageIcon
(
mrIconImage
));
}
BufferedImage
iconImage
=
getAppIconImageCompositedOn
(
background
,
1
);
return
new
IconUIResource
(
new
ImageIcon
(
iconImage
));
}
...
...
@@ -312,10 +310,16 @@ public class AquaImageFactory {
return
icon
;
}
Image
icon2x
=
AquaUtils
.
getCImageCreator
().
createImageFromName
(
imageName
,
2
*
icon
.
getWidth
(
null
),
2
*
icon
.
getHeight
(
null
));
return
new
MultiResolutionBufferedImage
(
BufferedImage
.
TYPE_INT_ARGB_PRE
,
0
,
icon
,
icon2x
);
int
w
=
icon
.
getWidth
(
null
);
int
h
=
icon
.
getHeight
(
null
);
Dimension
[]
sizes
=
new
Dimension
[]{
new
Dimension
(
w
,
h
),
new
Dimension
(
2
*
w
,
2
*
h
)
};
return
new
MultiResolutionBufferedImage
(
icon
,
sizes
,
(
width
,
height
)
->
AquaUtils
.
getCImageCreator
().
createImageFromName
(
imageName
,
width
,
height
));
}
public
static
class
NineSliceMetrics
{
...
...
@@ -524,29 +528,4 @@ public class AquaImageFactory {
public
static
Color
getSelectionInactiveForegroundColorUIResource
()
{
return
new
SystemColorProxy
(
LWCToolkit
.
getAppleColor
(
LWCToolkit
.
INACTIVE_SELECTION_FOREGROUND_COLOR
));
}
static
class
MultiResolutionIconImage
extends
BufferedImage
implements
MultiResolutionImage
{
BufferedImage
resolutionVariant
;
public
MultiResolutionIconImage
(
BufferedImage
image
,
BufferedImage
resolutionVariant
)
{
super
(
image
.
getWidth
(),
image
.
getHeight
(),
image
.
getType
());
this
.
resolutionVariant
=
resolutionVariant
;
Graphics
g
=
getGraphics
();
g
.
drawImage
(
image
,
0
,
0
,
null
);
g
.
dispose
();
}
@Override
public
Image
getResolutionVariant
(
int
width
,
int
height
)
{
return
((
width
<=
getWidth
()
&&
height
<=
getHeight
()))
?
this
:
resolutionVariant
;
}
@Override
public
List
<
Image
>
getResolutionVariants
()
{
return
Arrays
.
asList
(
this
,
resolutionVariant
);
}
}
}
}
\ No newline at end of file
src/macosx/classes/com/apple/laf/AquaPainter.java
浏览文件 @
339f35c4
...
...
@@ -38,6 +38,7 @@ import sun.java2d.*;
import
sun.print.*
;
import
apple.laf.*
;
import
apple.laf.JRSUIUtils.NineSliceMetricsProvider
;
import
sun.awt.image.ImageCache
;
abstract
class
AquaPainter
<
T
extends
JRSUIState
>
{
static
<
T
extends
JRSUIState
>
AquaPainter
<
T
>
create
(
final
T
state
)
{
...
...
@@ -155,10 +156,15 @@ abstract class AquaPainter <T extends JRSUIState> {
final
ImageCache
cache
=
ImageCache
.
getInstance
();
final
int
imgW
=
bounds
.
width
*
scale
;
final
int
imgH
=
bounds
.
height
*
scale
;
BufferedImage
img
=
(
BufferedImage
)
cache
.
getImage
(
config
,
imgW
,
imgH
,
scale
,
controlState
);
AquaPixelsKey
key
=
new
AquaPixelsKey
(
config
,
imgW
,
imgH
,
scale
,
controlState
);
BufferedImage
img
=
(
BufferedImage
)
cache
.
getImage
(
key
);
if
(
img
==
null
)
{
img
=
new
BufferedImage
(
imgW
,
imgH
,
BufferedImage
.
TYPE_INT_ARGB_PRE
);
cache
.
setImage
(
img
,
config
,
imgW
,
imgH
,
scale
,
controlState
);
if
(!
controlState
.
is
(
JRSUIConstants
.
Animating
.
YES
))
{
cache
.
setImage
(
key
,
img
);
}
final
WritableRaster
raster
=
img
.
getRaster
();
final
DataBufferInt
buffer
=
(
DataBufferInt
)
raster
.
getDataBuffer
();
...
...
@@ -172,6 +178,59 @@ abstract class AquaPainter <T extends JRSUIState> {
}
}
private
static
class
AquaPixelsKey
implements
ImageCache
.
PixelsKey
{
private
final
int
pixelCount
;
private
final
int
hash
;
// key parts
private
final
GraphicsConfiguration
config
;
private
final
int
w
;
private
final
int
h
;
private
final
int
scale
;
private
final
JRSUIState
state
;
AquaPixelsKey
(
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
this
.
pixelCount
=
w
*
h
;
this
.
config
=
config
;
this
.
w
=
w
;
this
.
h
=
h
;
this
.
scale
=
scale
;
this
.
state
=
state
;
this
.
hash
=
hash
();
}
public
int
getPixelCount
()
{
return
pixelCount
;
}
private
int
hash
()
{
int
hash
=
config
!=
null
?
config
.
hashCode
()
:
0
;
hash
=
31
*
hash
+
w
;
hash
=
31
*
hash
+
h
;
hash
=
31
*
hash
+
scale
;
hash
=
31
*
hash
+
state
.
hashCode
();
return
hash
;
}
@Override
public
int
hashCode
()
{
return
hash
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
instanceof
AquaPixelsKey
)
{
AquaPixelsKey
key
=
(
AquaPixelsKey
)
obj
;
return
config
==
key
.
config
&&
w
==
key
.
w
&&
h
==
key
.
h
&&
scale
==
key
.
scale
&&
state
.
equals
(
key
.
state
);
}
return
false
;
}
}
private
static
class
RecyclableJRSUISlicedImageControl
extends
RecyclableSlicedImageControl
{
...
...
src/macosx/classes/com/apple/laf/AquaUtils.java
浏览文件 @
339f35c4
...
...
@@ -177,16 +177,7 @@ final class AquaUtils {
abstract
static
class
RecyclableSingleton
<
T
>
{
final
T
get
()
{
final
AppContext
appContext
=
AppContext
.
getAppContext
();
SoftReference
<
T
>
ref
=
(
SoftReference
<
T
>)
appContext
.
get
(
this
);
if
(
ref
!=
null
)
{
final
T
object
=
ref
.
get
();
if
(
object
!=
null
)
return
object
;
}
final
T
object
=
getInstance
();
ref
=
new
SoftReference
<
T
>(
object
);
appContext
.
put
(
this
,
ref
);
return
object
;
return
AppContext
.
getSoftReferenceValue
(
this
,
()
->
getInstance
());
}
void
reset
()
{
...
...
src/macosx/classes/sun/lwawt/macosx/CImage.java
浏览文件 @
339f35c4
...
...
@@ -224,24 +224,11 @@ public class CImage extends CFRetainedResource {
=
nativeGetNSImageRepresentationSizes
(
ptr
,
size
.
getWidth
(),
size
.
getHeight
());
if
(
sizes
==
null
||
sizes
.
length
<
2
)
{
return
toImage
(
w
,
h
,
w
,
h
);
}
BufferedImage
[]
images
=
new
BufferedImage
[
sizes
.
length
];
int
currentImageIndex
=
0
;
for
(
int
i
=
0
;
i
<
sizes
.
length
;
i
++)
{
int
imageRepWidth
=
(
int
)
sizes
[
i
].
getWidth
();
int
imageRepHeight
=
(
int
)
sizes
[
i
].
getHeight
();
BufferedImage
baseImage
=
toImage
(
w
,
h
,
w
,
h
);
if
(
imageRepHeight
<=
w
&&
imageRepHeight
<=
h
){
currentImageIndex
=
i
;
}
images
[
i
]
=
toImage
(
w
,
h
,
imageRepWidth
,
imageRepHeight
);
}
return
new
MultiResolutionBufferedImage
(
BufferedImage
.
TYPE_INT_ARGB_PRE
,
currentImageIndex
,
images
);
return
sizes
==
null
||
sizes
.
length
<
2
?
baseImage
:
new
MultiResolutionBufferedImage
(
baseImage
,
sizes
,
(
width
,
height
)
->
toImage
(
w
,
h
,
width
,
height
));
}
private
BufferedImage
toImage
(
int
srcWidth
,
int
srcHeight
,
int
dstWidth
,
int
dstHeight
)
{
...
...
src/share/classes/sun/awt/AppContext.java
浏览文件 @
339f35c4
...
...
@@ -42,11 +42,13 @@ import java.util.Set;
import
java.util.HashSet
;
import
java.beans.PropertyChangeSupport
;
import
java.beans.PropertyChangeListener
;
import
java.lang.ref.SoftReference
;
import
sun.util.logging.PlatformLogger
;
import
java.util.concurrent.locks.Condition
;
import
java.util.concurrent.locks.Lock
;
import
java.util.concurrent.locks.ReentrantLock
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.Supplier
;
/**
* The AppContext is a table referenced by ThreadGroup which stores
...
...
@@ -883,6 +885,23 @@ public final class AppContext {
});
}
public
static
<
T
>
T
getSoftReferenceValue
(
Object
key
,
Supplier
<
T
>
supplier
)
{
final
AppContext
appContext
=
AppContext
.
getAppContext
();
SoftReference
<
T
>
ref
=
(
SoftReference
<
T
>)
appContext
.
get
(
key
);
if
(
ref
!=
null
)
{
final
T
object
=
ref
.
get
();
if
(
object
!=
null
)
{
return
object
;
}
}
final
T
object
=
supplier
.
get
();
ref
=
new
SoftReference
<>(
object
);
appContext
.
put
(
key
,
ref
);
return
object
;
}
}
final
class
MostRecentKeyValue
{
...
...
src/
macosx/classes/com/apple/laf
/ImageCache.java
→
src/
share/classes/sun/awt/image
/ImageCache.java
浏览文件 @
339f35c4
/*
* Copyright (c) 2011, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 201
4
, 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
...
...
@@ -23,25 +23,28 @@
* questions.
*/
package
com.apple.laf
;
package
sun.awt.image
;
import
java.awt.*
;
import
java.lang.ref.*
;
import
java.util.*
;
import
java.util.concurrent.locks.*
;
import
apple.laf.JRSUIConstants
;
import
apple.laf.JRSUIState
;
import
com.apple.laf.AquaUtils.RecyclableSingleton
;
import
sun.awt.AppContext
;
/**
* ImageCache - A fixed pixel count sized cache of Images keyed by arbitrary set of arguments. All images are held with
* SoftReferences so they will be dropped by the GC if heap memory gets tight. When our size hits max pixel count least
* recently requested images are removed first.
* ImageCache - A fixed pixel count sized cache of Images keyed by arbitrary
* set of arguments. All images are held with SoftReferences so they will be
* dropped by the GC if heap memory gets tight. When our size hits max pixel
* count least recently requested images are removed first.
*
* The ImageCache must be used from the thread with an AppContext only.
*
*/
final
class
ImageCache
{
final
public
class
ImageCache
{
// Ordered Map keyed by args hash, ordered by most recent accessed entry.
private
final
LinkedHashMap
<
Integer
,
PixelCountSoftReference
>
map
=
new
LinkedHashMap
<>(
16
,
0.75f
,
true
);
private
final
LinkedHashMap
<
PixelsKey
,
ImageSoftReference
>
map
=
new
LinkedHashMap
<>(
16
,
0.75f
,
true
);
// Maximum number of pixels to cache, this is used if maxCount
private
final
int
maxPixelCount
;
...
...
@@ -53,15 +56,9 @@ final class ImageCache {
// Reference queue for tracking lost softreferences to images in the cache
private
final
ReferenceQueue
<
Image
>
referenceQueue
=
new
ReferenceQueue
<>();
// Singleton Instance
private
static
final
RecyclableSingleton
<
ImageCache
>
instance
=
new
RecyclableSingleton
<
ImageCache
>()
{
@Override
protected
ImageCache
getInstance
()
{
return
new
ImageCache
();
}
};
static
ImageCache
getInstance
()
{
return
instance
.
get
();
public
static
ImageCache
getInstance
()
{
return
AppContext
.
getSoftReferenceValue
(
ImageCache
.
class
,
()
->
new
ImageCache
());
}
ImageCache
(
final
int
maxPixelCount
)
{
...
...
@@ -81,186 +78,86 @@ final class ImageCache {
}
}
public
Image
getImage
(
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
final
int
hash
=
hash
(
config
,
w
,
h
,
scale
,
state
);
final
PixelCountSoftReference
ref
;
public
Image
getImage
(
final
PixelsKey
key
){
final
ImageSoftReference
ref
;
lock
.
readLock
().
lock
();
try
{
ref
=
map
.
get
(
hash
);
ref
=
map
.
get
(
key
);
}
finally
{
lock
.
readLock
().
unlock
();
}
// check reference has not been lost and the key truly matches,
// in case of false positive hash match
if
(
ref
!=
null
&&
ref
.
equals
(
config
,
w
,
h
,
scale
,
state
))
{
return
ref
.
get
();
}
return
null
;
return
ref
==
null
?
null
:
ref
.
get
();
}
/**
* Sets the cached image for the specified constraints.
*
* @param key The key with which the specified image is to be associated
* @param image The image to store in cache
* @param config The graphics configuration, needed if cached image is a Volatile Image. Used as part of cache key
* @param w The image width, used as part of cache key
* @param h The image height, used as part of cache key
* @param scale The image scale factor, used as part of cache key
* @return true if the image could be cached, false otherwise.
*/
public
boolean
setImage
(
final
Image
image
,
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
if
(
state
.
is
(
JRSUIConstants
.
Animating
.
YES
))
{
return
false
;
}
final
int
hash
=
hash
(
config
,
w
,
h
,
scale
,
state
);
public
void
setImage
(
final
PixelsKey
key
,
final
Image
image
)
{
lock
.
writeLock
().
lock
();
try
{
PixelCountSoftReference
ref
=
map
.
get
(
hash
);
// check if currently in map
if
(
ref
!=
null
&&
ref
.
get
()
==
image
)
return
true
;
ImageSoftReference
ref
=
map
.
get
(
key
);
// c
lear out old
// c
heck if currently in map
if
(
ref
!=
null
)
{
currentPixelCount
-=
ref
.
pixelCount
;
map
.
remove
(
hash
);
}
if
(
ref
.
get
()
!=
null
)
{
return
;
}
// soft image has been removed
currentPixelCount
-=
key
.
getPixelCount
();
map
.
remove
(
key
);
};
// add new image to pixel count
final
int
newPixelCount
=
image
.
getWidth
(
null
)
*
image
.
getHeight
(
null
);
final
int
newPixelCount
=
key
.
getPixelCount
(
);
currentPixelCount
+=
newPixelCount
;
// clean out lost references if not enough space
if
(
currentPixelCount
>
maxPixelCount
)
{
while
((
ref
=
(
PixelCount
SoftReference
)
referenceQueue
.
poll
())
!=
null
)
{
while
((
ref
=
(
Image
SoftReference
)
referenceQueue
.
poll
())
!=
null
)
{
//reference lost
map
.
remove
(
ref
.
hash
);
currentPixelCount
-=
ref
.
pixelCount
;
map
.
remove
(
ref
.
key
);
currentPixelCount
-=
ref
.
key
.
getPixelCount
()
;
}
}
// remove old items till there is enough free space
if
(
currentPixelCount
>
maxPixelCount
)
{
final
Iterator
<
Map
.
Entry
<
Integer
,
PixelCountSoftReference
>>
mapIter
=
map
.
entrySet
().
iterator
();
final
Iterator
<
Map
.
Entry
<
PixelsKey
,
ImageSoftReference
>>
mapIter
=
map
.
entrySet
().
iterator
();
while
((
currentPixelCount
>
maxPixelCount
)
&&
mapIter
.
hasNext
())
{
final
Map
.
Entry
<
Integer
,
PixelCountSoftReference
>
entry
=
mapIter
.
next
();
final
Map
.
Entry
<
PixelsKey
,
ImageSoftReference
>
entry
=
mapIter
.
next
();
mapIter
.
remove
();
final
Image
img
=
entry
.
getValue
().
get
();
if
(
img
!=
null
)
img
.
flush
();
currentPixelCount
-=
entry
.
getValue
().
pixelCount
;
currentPixelCount
-=
entry
.
getValue
().
key
.
getPixelCount
()
;
}
}
// finally put new in map
map
.
put
(
hash
,
new
PixelCountSoftReference
(
image
,
referenceQueue
,
newPixelCount
,
hash
,
config
,
w
,
h
,
scale
,
state
));
return
true
;
map
.
put
(
key
,
new
ImageSoftReference
(
key
,
image
,
referenceQueue
));
}
finally
{
lock
.
writeLock
().
unlock
();
}
}
private
static
int
hash
(
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
int
hash
=
config
!=
null
?
config
.
hashCode
()
:
0
;
hash
=
31
*
hash
+
w
;
hash
=
31
*
hash
+
h
;
hash
=
31
*
hash
+
scale
;
hash
=
31
*
hash
+
state
.
hashCode
();
return
hash
;
}
public
interface
PixelsKey
{
/**
* Extended SoftReference that stores the pixel count even after the image
* is lost.
*/
private
static
class
PixelCountSoftReference
extends
SoftReference
<
Image
>
{
int
getPixelCount
();
}
// default access, because access to these fields shouldn't be emulated
// by a synthetic accessor.
final
int
pixelCount
;
final
int
hash
;
private
static
class
ImageSoftReference
extends
SoftReference
<
Image
>
{
// key parts
private
final
GraphicsConfiguration
config
;
private
final
int
w
;
private
final
int
h
;
private
final
int
scale
;
private
final
JRSUIState
state
;
final
PixelsKey
key
;
PixelCountSoftReference
(
final
Image
referent
,
final
ReferenceQueue
<?
super
Image
>
q
,
final
int
pixelCount
,
final
int
hash
,
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
ImageSoftReference
(
final
PixelsKey
key
,
final
Image
referent
,
final
ReferenceQueue
<?
super
Image
>
q
)
{
super
(
referent
,
q
);
this
.
pixelCount
=
pixelCount
;
this
.
hash
=
hash
;
this
.
config
=
config
;
this
.
w
=
w
;
this
.
h
=
h
;
this
.
scale
=
scale
;
this
.
state
=
state
;
}
boolean
equals
(
final
GraphicsConfiguration
config
,
final
int
w
,
final
int
h
,
final
int
scale
,
final
JRSUIState
state
)
{
return
config
==
this
.
config
&&
w
==
this
.
w
&&
h
==
this
.
h
&&
scale
==
this
.
scale
&&
state
.
equals
(
this
.
state
);
this
.
key
=
key
;
}
}
// /** Gets the rendered image for this painter at the requested size, either from cache or create a new one */
// private VolatileImage getImage(GraphicsConfiguration config, JComponent c, int w, int h, Object[] extendedCacheKeys) {
// VolatileImage buffer = (VolatileImage)getImage(config, w, h, this, extendedCacheKeys);
//
// int renderCounter = 0; // to avoid any potential, though unlikely, infinite loop
// do {
// //validate the buffer so we can check for surface loss
// int bufferStatus = VolatileImage.IMAGE_INCOMPATIBLE;
// if (buffer != null) {
// bufferStatus = buffer.validate(config);
// }
//
// //If the buffer status is incompatible or restored, then we need to re-render to the volatile image
// if (bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE || bufferStatus == VolatileImage.IMAGE_RESTORED) {
// // if the buffer isn't the right size, or has lost its contents, then recreate
// if (buffer != null) {
// if (buffer.getWidth() != w || buffer.getHeight() != h || bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE) {
// // clear any resources related to the old back buffer
// buffer.flush();
// buffer = null;
// }
// }
//
// if (buffer == null) {
// // recreate the buffer
// buffer = config.createCompatibleVolatileImage(w, h, Transparency.TRANSLUCENT);
// // put in cache for future
// setImage(buffer, config, w, h, this, extendedCacheKeys);
// }
//
// //create the graphics context with which to paint to the buffer
// Graphics2D bg = buffer.createGraphics();
//
// //clear the background before configuring the graphics
// bg.setComposite(AlphaComposite.Clear);
// bg.fillRect(0, 0, w, h);
// bg.setComposite(AlphaComposite.SrcOver);
// bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//
// // paint the painter into buffer
// paint0(bg, c, w, h, extendedCacheKeys);
// //close buffer graphics
// bg.dispose();
// }
// } while (buffer.contentsLost() && renderCounter++ < 3);
//
// // check if we failed
// if (renderCounter >= 3) return null;
//
// return buffer;
// }
}
src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java
浏览文件 @
339f35c4
...
...
@@ -26,46 +26,152 @@ package sun.awt.image;
import
java.awt.Image
;
import
java.awt.Graphics
;
import
java.awt.geom.Dimension2D
;
import
java.awt.image.BufferedImage
;
import
java.awt.image.ImageObserver
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.function.Function
;
import
java.util.function.BiFunction
;
import
java.util.stream.Collectors
;
public
class
MultiResolutionBufferedImage
extends
BufferedImage
implements
MultiResolutionImage
{
Image
[]
resolutionVariants
;
int
baseIndex
;
private
final
BiFunction
<
Integer
,
Integer
,
Image
>
mapper
;
private
final
Dimension2D
[]
sizes
;
private
int
availableInfo
;
public
MultiResolutionBufferedImage
(
int
imageType
,
int
baseIndex
,
Image
...
images
)
{
super
(
images
[
baseIndex
].
getWidth
(
null
),
images
[
baseIndex
].
getHeight
(
null
),
imageType
);
this
.
baseIndex
=
baseIndex
;
this
.
resolutionVariants
=
images
;
public
MultiResolutionBufferedImage
(
Image
baseImage
,
Dimension2D
[]
sizes
,
BiFunction
<
Integer
,
Integer
,
Image
>
mapper
)
{
super
(
baseImage
.
getWidth
(
null
),
baseImage
.
getHeight
(
null
),
BufferedImage
.
TYPE_INT_ARGB_PRE
);
this
.
sizes
=
sizes
;
this
.
mapper
=
mapper
;
this
.
availableInfo
=
getInfo
(
baseImage
);
Graphics
g
=
getGraphics
();
g
.
drawImage
(
images
[
baseIndex
]
,
0
,
0
,
null
);
g
.
drawImage
(
baseImage
,
0
,
0
,
null
);
g
.
dispose
();
images
[
baseIndex
]
=
this
;
}
@Override
public
Image
getResolutionVariant
(
int
width
,
int
height
)
{
for
(
Image
image
:
resolutionVariants
)
{
if
(
width
<=
image
.
getWidth
(
null
)
&&
height
<=
image
.
getHeight
(
null
))
{
return
image
;
}
int
baseWidth
=
getWidth
();
int
baseHeight
=
getHeight
();
if
(
baseWidth
==
width
&&
baseHeight
==
height
)
{
return
this
;
}
return
this
;
ImageCache
cache
=
ImageCache
.
getInstance
();
ImageCacheKey
key
=
new
ImageCacheKey
(
this
,
width
,
height
);
Image
resolutionVariant
=
cache
.
getImage
(
key
);
if
(
resolutionVariant
==
null
)
{
resolutionVariant
=
mapper
.
apply
(
width
,
height
);
cache
.
setImage
(
key
,
resolutionVariant
);
preload
(
resolutionVariant
,
availableInfo
);
}
return
resolutionVariant
;
}
@Override
public
List
<
Image
>
getResolutionVariants
()
{
return
Arrays
.
asList
(
resolutionVariants
);
return
Arrays
.
stream
(
sizes
).
map
((
Function
<
Dimension2D
,
Image
>)
size
->
getResolutionVariant
((
int
)
size
.
getWidth
(),
(
int
)
size
.
getHeight
())).
collect
(
Collectors
.
toList
());
}
public
MultiResolutionBufferedImage
map
(
Function
<
Image
,
Image
>
mapper
)
{
return
new
MultiResolutionBufferedImage
(
getType
(),
baseIndex
,
Arrays
.
stream
(
resolutionVariants
).
map
(
mapper
)
.
toArray
(
length
->
new
Image
[
length
]));
return
new
MultiResolutionBufferedImage
(
mapper
.
apply
(
this
),
sizes
,
(
width
,
height
)
->
mapper
.
apply
(
getResolutionVariant
(
width
,
height
)));
}
@Override
public
int
getWidth
(
ImageObserver
observer
)
{
availableInfo
|=
ImageObserver
.
WIDTH
;
return
super
.
getWidth
(
observer
);
}
@Override
public
int
getHeight
(
ImageObserver
observer
)
{
availableInfo
|=
ImageObserver
.
HEIGHT
;
return
super
.
getHeight
(
observer
);
}
@Override
public
Object
getProperty
(
String
name
,
ImageObserver
observer
)
{
availableInfo
|=
ImageObserver
.
PROPERTIES
;
return
super
.
getProperty
(
name
,
observer
);
}
private
static
int
getInfo
(
Image
image
)
{
if
(
image
instanceof
ToolkitImage
)
{
return
((
ToolkitImage
)
image
).
getImageRep
().
check
(
(
img
,
infoflags
,
x
,
y
,
w
,
h
)
->
false
);
}
return
0
;
}
private
static
void
preload
(
Image
image
,
int
availableInfo
)
{
if
(
image
instanceof
ToolkitImage
)
{
((
ToolkitImage
)
image
).
preload
(
new
ImageObserver
()
{
int
flags
=
availableInfo
;
@Override
public
boolean
imageUpdate
(
Image
img
,
int
infoflags
,
int
x
,
int
y
,
int
width
,
int
height
)
{
flags
&=
~
infoflags
;
return
(
flags
!=
0
)
&&
((
infoflags
&
(
ImageObserver
.
ERROR
|
ImageObserver
.
ABORT
))
==
0
);
}
});
}
}
private
static
class
ImageCacheKey
implements
ImageCache
.
PixelsKey
{
private
final
int
pixelCount
;
private
final
int
hash
;
private
final
int
w
;
private
final
int
h
;
private
final
Image
baseImage
;
ImageCacheKey
(
final
Image
baseImage
,
final
int
w
,
final
int
h
)
{
this
.
baseImage
=
baseImage
;
this
.
w
=
w
;
this
.
h
=
h
;
this
.
pixelCount
=
w
*
h
;
hash
=
hash
();
}
@Override
public
int
getPixelCount
()
{
return
pixelCount
;
}
private
int
hash
()
{
int
hash
=
baseImage
.
hashCode
();
hash
=
31
*
hash
+
w
;
hash
=
31
*
hash
+
h
;
return
hash
;
}
@Override
public
int
hashCode
()
{
return
hash
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
instanceof
ImageCacheKey
)
{
ImageCacheKey
key
=
(
ImageCacheKey
)
obj
;
return
baseImage
==
key
.
baseImage
&&
w
==
key
.
w
&&
h
==
key
.
h
;
}
return
false
;
}
}
}
}
\ No newline at end of file
test/java/awt/image/MultiResolutionImage/NSImageToMultiResolutionImageTest.java
浏览文件 @
339f35c4
...
...
@@ -27,7 +27,7 @@ import sun.awt.OSInfo;
import
sun.awt.image.MultiResolutionImage
;
/*
* @test
* @bug 8033534
* @bug 8033534
8035069
* @summary [macosx] Get MultiResolution image from native system
* @author Alexander Scherbatiy
* @run main NSImageToMultiResolutionImageTest
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录