Skip to content

Commit f9181fe

Browse files
committed
JBR-8119 JBR-9104 JBR-9106 OpenGL: shared textures
1 parent 01c8c77 commit f9181fe

File tree

23 files changed

+1430
-56
lines changed

23 files changed

+1430
-56
lines changed

make/test/JtregNativeJdk.gmk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ ifeq ($(call isTargetOs, macosx), true)
9696
BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestDynamicStore := \
9797
-framework Cocoa -framework SystemConfiguration
9898
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := \
99-
-framework Cocoa -framework Metal
99+
-framework Cocoa -framework Metal -framework OpenGL
100+
BUILD_JDK_JTREG_EXCLUDE += libSharedTexturesTest.c
100101
else
101102
BUILD_JDK_JTREG_EXCLUDE += libTestMainKeyWindow.m
102103
BUILD_JDK_JTREG_EXCLUDE += libTestDynamicStore.m
@@ -108,6 +109,7 @@ endif
108109
ifeq ($(OPENJDK_TARGET_OS), windows)
109110
BUILD_JDK_JTREG_LIBRARIES_LIBS_libwindows_touch_robot := user32.lib
110111
BUILD_JDK_JTREG_EXCLUDE += libtouchscreen_device.c
112+
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := gdi32.lib opengl32.lib user32.lib
111113
else
112114
ifeq ($(OPENJDK_TARGET_OS), linux)
113115
BUILD_JDK_JTREG_EXCLUDE += libwindows_touch_robot.c
@@ -123,6 +125,7 @@ ifeq ($(call isTargetOs, linux), true)
123125
BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
124126
# nio tests' libCreationTimeHelper native needs -ldl linker flag
125127
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl
128+
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := -lX11 -lGL -lGLX
126129
endif
127130

128131
ifeq ($(ASAN_ENABLED), true)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright 2025 JetBrains s.r.o.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.jetbrains.desktop;
27+
28+
import com.jetbrains.desktop.image.TextureWrapperImage;
29+
import com.jetbrains.desktop.image.TextureWrapperSurfaceManager;
30+
import com.jetbrains.exported.JBRApi;
31+
import sun.awt.image.SurfaceManager;
32+
import sun.java2d.SurfaceData;
33+
34+
import sun.java2d.opengl.*;
35+
36+
import java.awt.GraphicsConfiguration;
37+
import java.awt.GraphicsEnvironment;
38+
import java.awt.Image;
39+
40+
@JBRApi.Service
41+
@JBRApi.Provides("SharedTextures")
42+
public class SharedTextures {
43+
public final static int METAL_TEXTURE_TYPE = 1;
44+
public final static int OPENGL_TEXTURE_TYPE = 2;
45+
46+
public static SharedTextures create() {
47+
return new SharedTextures();
48+
}
49+
50+
private SharedTextures() {}
51+
52+
public Image wrapTexture(GraphicsConfiguration gc, long texture) {
53+
return new TextureWrapperImage(gc, texture);
54+
}
55+
56+
public int getTextureType(GraphicsConfiguration gc) {
57+
try {
58+
if (gc instanceof GLXGraphicsConfig) {
59+
return OPENGL_TEXTURE_TYPE;
60+
}
61+
} catch (Exception e) {
62+
throw new InternalError("Unexpected exception during reflection", e);
63+
}
64+
65+
return 0;
66+
}
67+
68+
@Deprecated
69+
public int getTextureType() {
70+
GraphicsConfiguration gc = GraphicsEnvironment
71+
.getLocalGraphicsEnvironment()
72+
.getDefaultScreenDevice()
73+
.getDefaultConfiguration();
74+
return getTextureType(gc);
75+
}
76+
77+
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
78+
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
79+
return new long[] {
80+
GLXGraphicsConfigExt.getSharedContext(),
81+
GLXGraphicsConfigExt.getAwtDisplay(),
82+
GLXGraphicsConfigExt.getFBConfig(glxGraphicsConfig),
83+
};
84+
}
85+
86+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
87+
}
88+
89+
static SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
90+
SurfaceData sd;
91+
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
92+
sd = new GLXTextureWrapperSurfaceData(glxGraphicsConfig, image, texture);
93+
} else {
94+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
95+
}
96+
97+
return new TextureWrapperSurfaceManager(sd);
98+
}
99+
}

src/java.desktop/macosx/classes/com/jetbrains/desktop/SharedTextures.java

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,60 +31,74 @@
3131
import sun.awt.image.SurfaceManager;
3232
import sun.java2d.SurfaceData;
3333
import sun.java2d.metal.MTLGraphicsConfig;
34-
import sun.java2d.metal.MTLSurfaceData;
3534
import sun.java2d.metal.MTLTextureWrapperSurfaceData;
35+
import sun.java2d.opengl.CGLGraphicsConfig;
36+
import sun.java2d.opengl.CGLGraphicsConfigExt;
37+
import sun.java2d.opengl.CGLTextureWrapperSurfaceData;
3638

37-
import java.awt.GraphicsConfiguration;
38-
import java.awt.GraphicsEnvironment;
39-
import java.awt.Image;
39+
import java.awt.*;
4040

4141
@JBRApi.Service
4242
@JBRApi.Provides("SharedTextures")
4343
public class SharedTextures {
4444
public final static int METAL_TEXTURE_TYPE = 1;
45-
46-
private final int textureType;
45+
public final static int OPENGL_TEXTURE_TYPE = 2;
4746

4847
public static SharedTextures create() {
4948
return new SharedTextures();
5049
}
5150

5251
private SharedTextures() {
53-
textureType = getTextureTypeImpl();
54-
if (textureType == 0) {
55-
throw new JBRApi.ServiceNotAvailableException();
56-
}
57-
}
58-
59-
public int getTextureType() {
60-
return textureType;
6152
}
6253

6354
public Image wrapTexture(GraphicsConfiguration gc, long texture) {
6455
return new TextureWrapperImage(gc, texture);
6556
}
6657

67-
private static int getTextureTypeImpl() {
58+
public int getTextureType(GraphicsConfiguration gc) {
59+
try {
60+
if (gc instanceof MTLGraphicsConfig) {
61+
return METAL_TEXTURE_TYPE;
62+
} else if (gc instanceof CGLGraphicsConfig) {
63+
return OPENGL_TEXTURE_TYPE;
64+
}
65+
} catch (Exception e) {
66+
throw new InternalError("Unexpected exception during reflection", e);
67+
}
68+
69+
return 0;
70+
}
71+
72+
@Deprecated
73+
public int getTextureType() {
6874
GraphicsConfiguration gc = GraphicsEnvironment
6975
.getLocalGraphicsEnvironment()
7076
.getDefaultScreenDevice()
7177
.getDefaultConfiguration();
72-
73-
if (gc instanceof MTLGraphicsConfig) {
74-
return METAL_TEXTURE_TYPE;
75-
}
76-
77-
return 0;
78+
return getTextureType(gc);
7879
}
7980

8081
static SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
8182
SurfaceData sd;
8283
if (gc instanceof MTLGraphicsConfig mtlGraphicsConfig) {
8384
sd = new MTLTextureWrapperSurfaceData(mtlGraphicsConfig, image, texture);
85+
} else if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
86+
sd = new CGLTextureWrapperSurfaceData(cglGraphicsConfig, image, texture);
8487
} else {
8588
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
8689
}
8790

8891
return new TextureWrapperSurfaceManager(sd);
8992
}
93+
94+
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
95+
if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
96+
return new long[] {
97+
CGLGraphicsConfigExt.getSharedContext(),
98+
CGLGraphicsConfigExt.getPixelFormat()
99+
};
100+
}
101+
102+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
103+
}
90104
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package sun.java2d.opengl;
2+
3+
public class CGLGraphicsConfigExt {
4+
public static native long getSharedContext();
5+
public static native long getPixelFormat();
6+
}

src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
4343
long pPeerData, long layerPtr, int xoff,
4444
int yoff, boolean isOpaque);
4545

46-
private CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
47-
ColorModel cm, int type, int width, int height) {
46+
protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
47+
ColorModel cm, int type, int width, int height) {
4848
super(gc, cm, type);
4949
// TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
5050
scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package sun.java2d.opengl;
2+
3+
import sun.java2d.SurfaceData;
4+
5+
import java.awt.*;
6+
import java.awt.image.ColorModel;
7+
import java.util.concurrent.atomic.AtomicBoolean;
8+
9+
public class CGLTextureWrapperSurfaceData extends CGLSurfaceData {
10+
11+
public CGLTextureWrapperSurfaceData(CGLGraphicsConfig gc, Image image, long textureId) {
12+
super(null, gc, ColorModel.getRGBdefault(), RT_TEXTURE, 0, 0);
13+
14+
OGLRenderQueue rq = OGLRenderQueue.getInstance();
15+
AtomicBoolean success = new AtomicBoolean(false);
16+
rq.lock();
17+
try {
18+
OGLContext.setScratchSurface(gc);
19+
rq.flushAndInvokeNow(() -> success.set(OGLSurfaceDataExt.initWithTexture(this, textureId)));
20+
} finally {
21+
rq.unlock();
22+
}
23+
24+
if (!success.get()) {
25+
throw new IllegalArgumentException("Failed to init the surface data");
26+
}
27+
}
28+
29+
@Override
30+
public SurfaceData getReplacement() {
31+
throw new UnsupportedOperationException();
32+
}
33+
34+
@Override
35+
public Rectangle getBounds() {
36+
return getNativeBounds();
37+
}
38+
39+
@Override
40+
public Object getDestination() {
41+
return null;
42+
}
43+
44+
@Override
45+
public void flush() {
46+
// reset the texture id first to avoid the texture deallocation
47+
OGLSurfaceDataExt.resetTextureId(this);
48+
super.flush();
49+
}
50+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#import "sun_java2d_opengl_CGLGraphicsConfigExt.h"
2+
3+
#import "JNIUtilities.h"
4+
5+
extern NSOpenGLContext *sharedContext;
6+
extern NSOpenGLPixelFormat *sharedPixelFormat;
7+
8+
JNIEXPORT jlong JNICALL
9+
Java_sun_java2d_opengl_CGLGraphicsConfigExt_getSharedContext
10+
(JNIEnv *env, jclass cls)
11+
{
12+
return ptr_to_jlong(sharedContext.CGLContextObj) ;
13+
}
14+
15+
JNIEXPORT jlong JNICALL
16+
Java_sun_java2d_opengl_CGLGraphicsConfigExt_getPixelFormat
17+
(JNIEnv *env, jclass cls)
18+
{
19+
return ptr_to_jlong(sharedPixelFormat.CGLPixelFormatObj);
20+
}

src/java.desktop/share/classes/com/jetbrains/desktop/image/TextureWrapperSurfaceManager.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434

3535
public class TextureWrapperSurfaceManager extends SurfaceManager {
36-
private final SurfaceData sd;
36+
private SurfaceData sd;
3737

3838
public TextureWrapperSurfaceManager(SurfaceData sd) {
3939
this.sd = sd;
@@ -53,4 +53,10 @@ public SurfaceData restoreContents() {
5353
public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
5454
return new ImageCapabilities(true);
5555
}
56+
57+
@Override
58+
public synchronized void flush() {
59+
sd.flush();
60+
sd = null;
61+
}
5662
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 JetBrains s.r.o.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package sun.java2d.opengl;
27+
28+
import java.awt.*;
29+
30+
public class OGLGraphicsConfigExt {
31+
public static long getSharedContext(GraphicsConfiguration gc) {
32+
if (gc instanceof OGLGraphicsConfig) {
33+
return getSharedContext();
34+
}
35+
36+
throw new IllegalArgumentException("Not an OpenGL graphics config: " + gc);
37+
}
38+
39+
public static long getPixelFormat(GraphicsConfiguration gc) {
40+
if (gc instanceof OGLGraphicsConfig oglGc) {
41+
return getPixelFormat(oglGc.getNativeConfigInfo());
42+
}
43+
44+
throw new IllegalArgumentException("Not an OpenGL graphics config: " + gc);
45+
}
46+
47+
private static native long getPixelFormat(long pConfigInfo);
48+
private static native long getSharedContext();
49+
}

0 commit comments

Comments
 (0)