Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
aa627fd2
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看板
提交
aa627fd2
编写于
6月 02, 2015
作者:
B
bae
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8023794: [macosx] LCD Rendering hints seems not working without FRACTIONALMETRICS=ON
Reviewed-by: serb, prr
上级
4cffa7cc
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
136 addition
and
167 deletion
+136
-167
src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+1
-2
src/macosx/native/sun/font/AWTStrike.m
src/macosx/native/sun/font/AWTStrike.m
+17
-12
src/macosx/native/sun/font/CGGlyphImages.m
src/macosx/native/sun/font/CGGlyphImages.m
+85
-42
src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
+15
-4
src/share/native/sun/java2d/opengl/OGLContext.c
src/share/native/sun/java2d/opengl/OGLContext.c
+1
-1
src/share/native/sun/java2d/opengl/OGLTextRenderer.c
src/share/native/sun/java2d/opengl/OGLTextRenderer.c
+17
-106
未找到文件。
src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
浏览文件 @
aa627fd2
...
...
@@ -366,8 +366,7 @@ public final class LWCToolkit extends LWToolkit {
protected
void
initializeDesktopProperties
()
{
super
.
initializeDesktopProperties
();
Map
<
Object
,
Object
>
fontHints
=
new
HashMap
<>();
fontHints
.
put
(
RenderingHints
.
KEY_ANTIALIASING
,
RenderingHints
.
VALUE_ANTIALIAS_ON
);
fontHints
.
put
(
RenderingHints
.
KEY_TEXT_ANTIALIASING
,
RenderingHints
.
VALUE_TEXT_ANTIALIAS_ON
);
fontHints
.
put
(
RenderingHints
.
KEY_TEXT_ANTIALIASING
,
RenderingHints
.
VALUE_TEXT_ANTIALIAS_LCD_HRGB
);
desktopProperties
.
put
(
SunToolkit
.
DESKTOPFONTHINTS
,
fontHints
);
desktopProperties
.
put
(
"awt.mouse.numButtons"
,
BUTTONS
);
...
...
src/macosx/native/sun/font/AWTStrike.m
浏览文件 @
aa627fd2
...
...
@@ -311,21 +311,26 @@ JNF_COCOA_ENTER(env);
jlong
*
glyphInfos
=
(
*
env
)
->
GetPrimitiveArrayCritical
(
env
,
glyphInfoLongArray
,
NULL
);
if
(
glyphInfos
!=
NULL
)
{
jint
*
rawGlyphCodes
=
(
*
env
)
->
GetPrimitiveArrayCritical
(
env
,
glyphCodes
,
NULL
);
jint
*
rawGlyphCodes
=
(
*
env
)
->
GetPrimitiveArrayCritical
(
env
,
glyphCodes
,
NULL
);
@try
{
if
(
rawGlyphCodes
!=
NULL
&&
glyphInfos
!=
NULL
)
{
CGGlyphImages_GetGlyphImagePtrs
(
glyphInfos
,
awtStrike
,
rawGlyphCodes
,
len
);
}
}
@finally
{
if
(
rawGlyphCodes
!=
NULL
)
{
CGGlyphImages_GetGlyphImagePtrs
(
glyphInfos
,
awtStrike
,
rawGlyphCodes
,
len
);
(
*
env
)
->
ReleasePrimitiveArrayCritical
(
env
,
glyphCodes
,
rawGlyphCodes
,
JNI_ABORT
);
(
*
env
)
->
ReleasePrimitiveArrayCritical
(
env
,
glyphCodes
,
rawGlyphCodes
,
JNI_ABORT
);
}
if
(
glyphInfos
!=
NULL
)
{
// Do not use JNI_COMMIT, as that will not free the buffer copy
// when +ProtectJavaHeap is on.
(
*
env
)
->
ReleasePrimitiveArrayCritical
(
env
,
glyphInfoLongArray
,
glyphInfos
,
0
);
}
// Do not use JNI_COMMIT, as that will not free the buffer copy
// when +ProtectJavaHeap is on.
(
*
env
)
->
ReleasePrimitiveArrayCritical
(
env
,
glyphInfoLongArray
,
glyphInfos
,
0
);
}
JNF_COCOA_EXIT
(
env
);
...
...
src/macosx/native/sun/font/CGGlyphImages.m
浏览文件 @
aa627fd2
...
...
@@ -195,19 +195,41 @@ DUMP_GLYPHINFO(const GlyphInfo *info)
#pragma mark --- Font Rendering Mode Descriptors ---
static
Int32
reverseGamma
=
0
;
static
UInt8
reverseGammaLut
[
256
]
=
{
0
};
static
inline
UInt8
*
getReverseGammaLut
()
{
if
(
reverseGamma
==
0
)
{
// initialize gamma lut
double
gamma
;
int
i
;
const
char
*
pGammaEnv
=
getenv
(
"J2D_LCD_REVERSE_GAMMA"
);
if
(
pGammaEnv
!=
NULL
)
{
reverseGamma
=
atol
(
pGammaEnv
);
}
if
(
reverseGamma
<
100
||
reverseGamma
>
250
)
{
reverseGamma
=
180
;
}
gamma
=
100
.
0
/
reverseGamma
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
double
x
=
((
double
)
i
)
/
255
.
0
;
reverseGammaLut
[
i
]
=
(
UInt8
)(
255
*
pow
(
x
,
gamma
));
}
}
return
reverseGammaLut
;
}
static
inline
void
CGGI_CopyARGBPixelToRGBPixel
(
const
UInt32
p
,
UInt8
*
dst
)
{
#if __LITTLE_ENDIAN__
*
(
dst
+
2
)
=
0xFF
-
(
p
>>
24
&
0xFF
);
*
(
dst
+
1
)
=
0xFF
-
(
p
>>
16
&
0xFF
);
*
(
dst
)
=
0xFF
-
(
p
>>
8
&
0xFF
);
#else
*
(
dst
)
=
0xFF
-
(
p
>>
16
&
0xFF
);
*
(
dst
+
1
)
=
0xFF
-
(
p
>>
8
&
0xFF
);
*
(
dst
+
2
)
=
0xFF
-
(
p
&
0xFF
);
#endif
UInt8
*
lut
=
getReverseGammaLut
();
*
(
dst
+
0
)
=
lut
[
0xFF
-
(
p
>>
16
&
0xFF
)];
// red
*
(
dst
+
1
)
=
lut
[
0xFF
-
(
p
>>
8
&
0xFF
)];
// green
*
(
dst
+
2
)
=
lut
[
0xFF
-
(
p
&
0xFF
)];
// blue
}
static
void
...
...
@@ -222,17 +244,14 @@ CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
size_t
height
=
info
->
height
;
size_t
y
;
// fill empty glyph image with black-on-white glyph
for
(
y
=
0
;
y
<
height
;
y
++
)
{
size_t
destRow
=
y
*
destRowWidth
*
3
;
size_t
srcRow
=
y
*
srcRowWidth
;
size_t
x
;
for
(
x
=
0
;
x
<
destRowWidth
;
x
++
)
{
// size_t x3 = x * 3;
// UInt32 p = src[srcRow + x];
// dest[destRow + x3] = 0xFF - (p >> 16 & 0xFF);
// dest[destRow + x3 + 1] = 0xFF - (p >> 8 & 0xFF);
// dest[destRow + x3 + 2] = 0xFF - (p & 0xFF);
CGGI_CopyARGBPixelToRGBPixel
(
src
[
srcRow
+
x
],
dest
+
destRow
+
x
*
3
);
}
...
...
@@ -260,13 +279,9 @@ CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
//}
static
inline
UInt8
CGGI_Convert
PixelToGreyBit
(
UInt32
p
)
CGGI_Convert
BWPixelToByteGray
(
UInt32
p
)
{
#ifdef __LITTLE_ENDIAN__
return
0xFF
-
((
p
>>
24
&
0xFF
)
+
(
p
>>
16
&
0xFF
)
+
(
p
>>
8
&
0xFF
))
/
3
;
#else
return
0xFF
-
((
p
>>
16
&
0xFF
)
+
(
p
>>
8
&
0xFF
)
+
(
p
&
0xFF
))
/
3
;
#endif
return
0xFF
-
(((
p
>>
24
&
0xFF
)
+
(
p
>>
16
&
0xFF
)
+
(
p
>>
8
&
0xFF
))
/
3
);
}
static
void
...
...
@@ -281,14 +296,15 @@ CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
size_t
height
=
info
->
height
;
size_t
y
;
// fill empty glyph image with black-on-white glyph
for
(
y
=
0
;
y
<
height
;
y
++
)
{
size_t
destRow
=
y
*
destRowWidth
;
size_t
srcRow
=
y
*
srcRowWidth
;
size_t
x
;
for
(
x
=
0
;
x
<
destRowWidth
;
x
++
)
{
UInt32
p
=
src
[
srcRow
+
x
];
dest
[
destRow
+
x
]
=
CGGI_Convert
PixelToGreyBit
(
p
);
dest
[
destRow
+
x
]
=
CGGI_Convert
BWPixelToByteGray
(
p
);
}
}
}
...
...
@@ -316,13 +332,11 @@ CGGI_GetRenderingMode(const AWTStrike *strike)
{
CGGI_RenderingMode
mode
;
mode
.
cgFontMode
=
strike
->
fStyle
;
NSException
*
e
=
nil
;
switch
(
strike
->
fAAStyle
)
{
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_DEFAULT
:
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_OFF
:
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON
:
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_GASP
:
default:
mode
.
glyphDescriptor
=
&
grey
;
break
;
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HRGB
:
...
...
@@ -331,6 +345,17 @@ CGGI_GetRenderingMode(const AWTStrike *strike)
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_VBGR
:
mode
.
glyphDescriptor
=
&
rgb
;
break
;
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_GASP
:
case
sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_DEFAULT
:
default:
/* we expect that text antialiasing hint has been already
* evaluated. Report an error if we get 'unevaluated' hint here.
*/
e
=
[
NSException
exceptionWithName:
@"IllegalArgumentException"
reason:
@"Invalid hint value"
userInfo:
nil
];
@throw
e
;
}
return
mode
;
...
...
@@ -345,7 +370,8 @@ CGGI_GetRenderingMode(const AWTStrike *strike)
*/
static
inline
void
CGGI_InitCanvas
(
CGGI_GlyphCanvas
*
canvas
,
const
vImagePixelCount
width
,
const
vImagePixelCount
height
)
const
vImagePixelCount
width
,
const
vImagePixelCount
height
,
const
CGGI_RenderingMode
*
mode
)
{
// our canvas is *always* 4-byte ARGB
size_t
bytesPerRow
=
width
*
sizeof
(
UInt32
);
...
...
@@ -356,19 +382,26 @@ CGGI_InitCanvas(CGGI_GlyphCanvas *canvas,
canvas
->
image
->
height
=
height
;
canvas
->
image
->
rowBytes
=
bytesPerRow
;
canvas
->
image
->
data
=
(
void
*
)
calloc
(
byteCount
,
sizeof
(
UInt
32
));
canvas
->
image
->
data
=
(
void
*
)
calloc
(
byteCount
,
sizeof
(
UInt
8
));
if
(
canvas
->
image
->
data
==
NULL
)
{
[[
NSException
exceptionWithName
:
NSMallocException
reason:
@"Failed to allocate memory for the buffer which backs the CGContext for glyph strikes."
userInfo
:
nil
]
raise
];
}
CGColorSpaceRef
colorSpace
=
CGColorSpaceCreateWithName
(
kCGColorSpaceGenericRGB
);
uint32_t
bmpInfo
=
kCGImageAlphaPremultipliedFirst
;
if
(
mode
->
glyphDescriptor
==
&
rgb
)
{
bmpInfo
|=
kCGBitmapByteOrder32Host
;
}
CGColorSpaceRef
colorSpace
=
CGColorSpaceCreateWithName
(
kCGColorSpaceSRGB
);
canvas
->
context
=
CGBitmapContextCreate
(
canvas
->
image
->
data
,
width
,
height
,
8
,
bytesPerRow
,
colorSpace
,
kCGImageAlphaPremultipliedFirst
);
bmpInfo
);
// set foreground color
CGContextSetRGBFillColor
(
canvas
->
context
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
1
.
0
f
);
CGContextSetFontSize
(
canvas
->
context
,
1
);
CGContextSaveGState
(
canvas
->
context
);
...
...
@@ -404,7 +437,9 @@ CGGI_FreeCanvas(CGGI_GlyphCanvas *canvas)
* Quick and easy inline to check if this canvas is big enough.
*/
static
inline
void
CGGI_SizeCanvas
(
CGGI_GlyphCanvas
*
canvas
,
const
vImagePixelCount
width
,
const
vImagePixelCount
height
,
const
JRSFontRenderingStyle
style
)
CGGI_SizeCanvas
(
CGGI_GlyphCanvas
*
canvas
,
const
vImagePixelCount
width
,
const
vImagePixelCount
height
,
const
CGGI_RenderingMode
*
mode
)
{
if
(
canvas
->
image
!=
NULL
&&
width
<
canvas
->
image
->
width
&&
...
...
@@ -418,8 +453,9 @@ CGGI_SizeCanvas(CGGI_GlyphCanvas *canvas, const vImagePixelCount width, const vI
CGGI_FreeCanvas
(
canvas
);
CGGI_InitCanvas
(
canvas
,
width
*
CGGI_GLYPH_CANVAS_SLACK
,
height
*
CGGI_GLYPH_CANVAS_SLACK
);
JRSFontSetRenderingStyleOnContext
(
canvas
->
context
,
style
);
height
*
CGGI_GLYPH_CANVAS_SLACK
,
mode
);
JRSFontSetRenderingStyleOnContext
(
canvas
->
context
,
mode
->
cgFontMode
);
}
/*
...
...
@@ -443,6 +479,7 @@ CGGI_ClearCanvas(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
Pixel_8888
opaqueWhite
=
{
0xFF
,
0xFF
,
0xFF
,
0xFF
};
#endif
// clear canvas background and set foreground color
vImageBufferFill_ARGB8888
(
&
canvasRectToClear
,
opaqueWhite
,
kvImageNoFlags
);
}
...
...
@@ -577,7 +614,7 @@ CGGI_CreateImageForUnicode
GlyphInfo
*
info
=
CGGI_CreateNewGlyphInfoFrom
(
advance
,
bbox
,
strike
,
mode
);
// fix the context size, just in case the substituted character is unexpectedly large
CGGI_SizeCanvas
(
canvas
,
info
->
width
,
info
->
height
,
mode
->
cgFontMode
);
CGGI_SizeCanvas
(
canvas
,
info
->
width
,
info
->
height
,
mode
);
// align the transform for the real CoreText strike
CGContextSetTextMatrix
(
canvas
->
context
,
strike
->
fAltTx
);
...
...
@@ -653,8 +690,11 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
#endif
}
static
NSString
*
threadLocalCanvasKey
=
@"Java CoreGraphics Text Renderer Cached Canvas"
;
static
NSString
*
threadLocalAACanvasKey
=
@"Java CoreGraphics Text Renderer Cached Canvas for AA"
;
static
NSString
*
threadLocalLCDCanvasKey
=
@"Java CoreGraphics Text Renderer Cached Canvas for LCD"
;
/*
* This is the maximum length and height times the above slack squared
...
...
@@ -678,25 +718,28 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_GLYPH_CANVAS_MAX
*
CGGI_GLYPH_CANVAS_MAX
*
CGGI_GLYPH_CANVAS_SLACK
*
CGGI_GLYPH_CANVAS_SLACK
)
{
CGGI_GlyphCanvas
*
tmpCanvas
=
[[
CGGI_GlyphCanvas
alloc
]
init
];
CGGI_InitCanvas
(
tmpCanvas
,
maxWidth
,
maxHeight
);
CGGI_InitCanvas
(
tmpCanvas
,
maxWidth
,
maxHeight
,
mode
);
CGGI_FillImagesForGlyphsWithSizedCanvas
(
tmpCanvas
,
strike
,
mode
,
glyphInfos
,
uniChars
,
glyphs
,
len
);
mode
,
glyphInfos
,
uniChars
,
glyphs
,
len
);
CGGI_FreeCanvas
(
tmpCanvas
);
[
tmpCanvas
release
];
return
;
}
NSMutableDictionary
*
threadDict
=
[[
NSThread
currentThread
]
threadDictionary
];
CGGI_GlyphCanvas
*
canvas
=
[
threadDict
objectForKey
:
threadLocalCanvasKey
];
NSString
*
theKey
=
(
mode
->
glyphDescriptor
==
&
rgb
)
?
threadLocalLCDCanvasKey
:
threadLocalAACanvasKey
;
CGGI_GlyphCanvas
*
canvas
=
[
threadDict
objectForKey
:
theKey
];
if
(
canvas
==
nil
)
{
canvas
=
[[
CGGI_GlyphCanvas
alloc
]
init
];
[
threadDict
setObject
:
canvas
forKey
:
th
readLocalCanvas
Key
];
[
threadDict
setObject
:
canvas
forKey
:
th
e
Key
];
}
CGGI_SizeCanvas
(
canvas
,
maxWidth
,
maxHeight
,
mode
->
cgFontMode
);
CGGI_SizeCanvas
(
canvas
,
maxWidth
,
maxHeight
,
mode
);
CGGI_FillImagesForGlyphsWithSizedCanvas
(
canvas
,
strike
,
mode
,
glyphInfos
,
uniChars
,
glyphs
,
len
);
}
...
...
src/share/classes/sun/java2d/opengl/OGLSurfaceData.java
浏览文件 @
aa627fd2
...
...
@@ -26,6 +26,7 @@
package
sun.java2d.opengl
;
import
java.awt.AlphaComposite
;
import
java.awt.Composite
;
import
java.awt.GraphicsEnvironment
;
import
java.awt.Rectangle
;
import
java.awt.Transparency
;
...
...
@@ -400,8 +401,8 @@ public abstract class OGLSurfaceData extends SurfaceData
/**
* For now, we can only render LCD text if:
* - the fragment shader extension is available, and
* -
blending is disabled
, and
* -
the source color is opaque
* -
the source color is opaque
, and
* -
blending is SrcOverNoEa or disabled
* - and the destination is opaque
*
* Eventually, we could enhance the native OGL text rendering code
...
...
@@ -411,9 +412,19 @@ public abstract class OGLSurfaceData extends SurfaceData
public
boolean
canRenderLCDText
(
SunGraphics2D
sg2d
)
{
return
graphicsConfig
.
isCapPresent
(
CAPS_EXT_LCD_SHADER
)
&&
sg2d
.
compositeState
<=
SunGraphics2D
.
COMP_ISCOPY
&&
sg2d
.
surfaceData
.
getTransparency
()
==
Transparency
.
OPAQUE
&&
sg2d
.
paintState
<=
SunGraphics2D
.
PAINT_OPAQUECOLOR
&&
sg2d
.
surfaceData
.
getTransparency
()
==
Transparency
.
OPAQUE
;
(
sg2d
.
compositeState
<=
SunGraphics2D
.
COMP_ISCOPY
||
(
sg2d
.
compositeState
<=
SunGraphics2D
.
COMP_ALPHA
&&
canHandleComposite
(
sg2d
.
composite
)));
}
private
boolean
canHandleComposite
(
Composite
c
)
{
if
(
c
instanceof
AlphaComposite
)
{
AlphaComposite
ac
=
(
AlphaComposite
)
c
;
return
ac
.
getRule
()
==
AlphaComposite
.
SRC_OVER
&&
ac
.
getAlpha
()
>=
1
f
;
}
return
false
;
}
public
void
validatePipe
(
SunGraphics2D
sg2d
)
{
...
...
src/share/native/sun/java2d/opengl/OGLContext.c
浏览文件 @
aa627fd2
...
...
@@ -748,7 +748,7 @@ OGLContext_IsLCDShaderSupportAvailable(JNIEnv *env,
// finally, check to see if the hardware supports the required number
// of texture units
j2d_glGetIntegerv
(
GL_MAX_TEXTURE_IMAGE_UNITS_ARB
,
&
maxTexUnits
);
if
(
maxTexUnits
<
4
)
{
if
(
maxTexUnits
<
2
)
{
J2dRlsTraceLn1
(
J2D_TRACE_INFO
,
"OGLContext_IsLCDShaderSupportAvailable: not enough tex units (%d)"
,
maxTexUnits
);
...
...
src/share/native/sun/java2d/opengl/OGLTextRenderer.c
浏览文件 @
aa627fd2
...
...
@@ -275,12 +275,9 @@ OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
* changes, we will modify the "src_adj" value in OGLTR_UpdateLCDTextColor()).
*
* The "main" function is executed for each "fragment" (or pixel) in the
* glyph image. We have determined that the pow() function can be quite
* slow and it only operates on scalar values, not vectors as we require.
* So instead we build two 3D textures containing gamma (and inverse gamma)
* lookup tables that allow us to approximate a component-wise pow() function
* with a single 3D texture lookup. This approach is at least 2x faster
* than the equivalent pow() calls.
* glyph image. The pow() routine operates on vectors, gives precise results,
* and provides acceptable level of performance, so we use it to perform
* the gamma adjustment.
*
* The variables involved in the equation can be expressed as follows:
*
...
...
@@ -299,8 +296,8 @@ static const char *lcdTextShaderSource =
"uniform vec3 src_adj;"
"uniform sampler2D glyph_tex;"
"uniform sampler2D dst_tex;"
"uniform
sampler3D invgamma_tex
;"
"uniform
sampler3D gamma_tex
;"
"uniform
vec3 gamma
;"
"uniform
vec3 invgamma
;"
""
"void main(void)"
"{"
...
...
@@ -312,12 +309,12 @@ static const char *lcdTextShaderSource =
" }"
// load the RGB value from the corresponding destination pixel
" vec3 dst_clr = vec3(texture2D(dst_tex, gl_TexCoord[1].st));"
// gamma adjust the dest color
using the invgamma LUT
" vec3 dst_adj =
vec3(texture3D(invgamma_tex, dst_clr.stp)
);"
// gamma adjust the dest color
" vec3 dst_adj =
pow(dst_clr.rgb, gamma
);"
// linearly interpolate the three color values
" vec3 result = mix(dst_adj, src_adj, glyph_clr);"
// gamma re-adjust the resulting color (alpha is always set to 1.0)
" gl_FragColor = vec4(
vec3(texture3D(gamma_tex, result.stp)
), 1.0);"
" gl_FragColor = vec4(
pow(result.rgb, invgamma
), 1.0);"
"}"
;
/**
...
...
@@ -348,10 +345,6 @@ OGLTR_CreateLCDTextProgram()
j2d_glUniform1iARB
(
loc
,
0
);
// texture unit 0
loc
=
j2d_glGetUniformLocationARB
(
lcdTextProgram
,
"dst_tex"
);
j2d_glUniform1iARB
(
loc
,
1
);
// texture unit 1
loc
=
j2d_glGetUniformLocationARB
(
lcdTextProgram
,
"invgamma_tex"
);
j2d_glUniform1iARB
(
loc
,
2
);
// texture unit 2
loc
=
j2d_glGetUniformLocationARB
(
lcdTextProgram
,
"gamma_tex"
);
j2d_glUniform1iARB
(
loc
,
3
);
// texture unit 3
// "unuse" the program object; it will be re-bound later as needed
j2d_glUseProgramObjectARB
(
0
);
...
...
@@ -360,108 +353,26 @@ OGLTR_CreateLCDTextProgram()
}
/**
* Initializes a 3D texture object for use as a three-dimensional gamma
* lookup table. Note that the wrap mode is initialized to GL_LINEAR so
* that the table will interpolate adjacent values when the index falls
* somewhere in between.
*/
static
GLuint
OGLTR_InitGammaLutTexture
()
{
GLuint
lutTextureID
;
j2d_glGenTextures
(
1
,
&
lutTextureID
);
j2d_glBindTexture
(
GL_TEXTURE_3D
,
lutTextureID
);
j2d_glTexParameteri
(
GL_TEXTURE_3D
,
GL_TEXTURE_MAG_FILTER
,
GL_LINEAR
);
j2d_glTexParameteri
(
GL_TEXTURE_3D
,
GL_TEXTURE_MIN_FILTER
,
GL_LINEAR
);
j2d_glTexParameteri
(
GL_TEXTURE_3D
,
GL_TEXTURE_WRAP_S
,
GL_CLAMP_TO_EDGE
);
j2d_glTexParameteri
(
GL_TEXTURE_3D
,
GL_TEXTURE_WRAP_T
,
GL_CLAMP_TO_EDGE
);
j2d_glTexParameteri
(
GL_TEXTURE_3D
,
GL_TEXTURE_WRAP_R
,
GL_CLAMP_TO_EDGE
);
return
lutTextureID
;
}
/**
* Updates the lookup table in the given texture object with the float
* values in the given system memory buffer. Note that we could use
* glTexSubImage3D() when updating the texture after its first
* initialization, but since we're updating the entire table (with
* power-of-two dimensions) and this is a relatively rare event, we'll
* just stick with glTexImage3D().
*/
static
void
OGLTR_UpdateGammaLutTexture
(
GLuint
texID
,
GLfloat
*
lut
,
jint
size
)
{
j2d_glBindTexture
(
GL_TEXTURE_3D
,
texID
);
j2d_glTexImage3D
(
GL_TEXTURE_3D
,
0
,
GL_RGB8
,
size
,
size
,
size
,
0
,
GL_RGB
,
GL_FLOAT
,
lut
);
}
/**
* (Re)Initializes the gamma lookup table textures.
* (Re)Initializes the gamma related uniforms.
*
* The given contrast value is an int in the range [100, 250] which we will
* then scale to fit in the range [1.0, 2.5]. We create two LUTs, one
* that essentially calculates pow(x, gamma) and the other calculates
* pow(x, 1/gamma). These values are replicated in all three dimensions, so
* given a single 3D texture coordinate (typically this will be a triplet
* in the form (r,g,b)), the 3D texture lookup will return an RGB triplet:
*
* (pow(r,g), pow(y,g), pow(z,g)
*
* where g is either gamma or 1/gamma, depending on the table.
* then scale to fit in the range [1.0, 2.5].
*/
static
jboolean
OGLTR_UpdateLCDTextContrast
(
jint
contrast
)
{
double
gamma
=
((
double
)
contrast
)
/
100
.
0
;
double
ig
=
gamma
;
double
g
=
1
.
0
/
ig
;
GLfloat
lut
[
LUT_EDGE
][
LUT_EDGE
][
LUT_EDGE
][
3
];
GLfloat
invlut
[
LUT_EDGE
][
LUT_EDGE
][
LUT_EDGE
][
3
];
int
min
=
0
;
int
max
=
LUT_EDGE
-
1
;
int
x
,
y
,
z
;
double
g
=
((
double
)
contrast
)
/
100
.
0
;
double
ig
=
1
.
0
/
g
;
GLint
loc
;
J2dTraceLn1
(
J2D_TRACE_INFO
,
"OGLTR_UpdateLCDTextContrast: contrast=%d"
,
contrast
);
for
(
z
=
min
;
z
<=
max
;
z
++
)
{
double
zval
=
((
double
)
z
)
/
max
;
GLfloat
gz
=
(
GLfloat
)
pow
(
zval
,
g
);
GLfloat
igz
=
(
GLfloat
)
pow
(
zval
,
ig
);
for
(
y
=
min
;
y
<=
max
;
y
++
)
{
double
yval
=
((
double
)
y
)
/
max
;
GLfloat
gy
=
(
GLfloat
)
pow
(
yval
,
g
);
GLfloat
igy
=
(
GLfloat
)
pow
(
yval
,
ig
);
loc
=
j2d_glGetUniformLocationARB
(
lcdTextProgram
,
"gamma"
);
j2d_glUniform3fARB
(
loc
,
g
,
g
,
g
);
for
(
x
=
min
;
x
<=
max
;
x
++
)
{
double
xval
=
((
double
)
x
)
/
max
;
GLfloat
gx
=
(
GLfloat
)
pow
(
xval
,
g
);
GLfloat
igx
=
(
GLfloat
)
pow
(
xval
,
ig
);
lut
[
z
][
y
][
x
][
0
]
=
gx
;
lut
[
z
][
y
][
x
][
1
]
=
gy
;
lut
[
z
][
y
][
x
][
2
]
=
gz
;
invlut
[
z
][
y
][
x
][
0
]
=
igx
;
invlut
[
z
][
y
][
x
][
1
]
=
igy
;
invlut
[
z
][
y
][
x
][
2
]
=
igz
;
}
}
}
if
(
gammaLutTextureID
==
0
)
{
gammaLutTextureID
=
OGLTR_InitGammaLutTexture
();
}
OGLTR_UpdateGammaLutTexture
(
gammaLutTextureID
,
(
GLfloat
*
)
lut
,
LUT_EDGE
);
if
(
invGammaLutTextureID
==
0
)
{
invGammaLutTextureID
=
OGLTR_InitGammaLutTexture
();
}
OGLTR_UpdateGammaLutTexture
(
invGammaLutTextureID
,
(
GLfloat
*
)
invlut
,
LUT_EDGE
);
loc
=
j2d_glGetUniformLocationARB
(
lcdTextProgram
,
"invgamma"
);
j2d_glUniform3fARB
(
loc
,
ig
,
ig
,
ig
);
return
JNI_TRUE
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录