Skip to content

Commit 9f997c9

Browse files
committed
opengl: shared textures
1 parent 396041c commit 9f997c9

File tree

29 files changed

+1521
-76
lines changed

29 files changed

+1521
-76
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: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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.exported.JBRApi;
30+
import sun.awt.image.SurfaceManager;
31+
import sun.awt.image.TextureWrapperSurfaceManager;
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+
static SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
78+
SurfaceData sd;
79+
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
80+
sd = new GLXTextureWrapperSurfaceData(glxGraphicsConfig, image, texture);
81+
} else {
82+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
83+
}
84+
85+
return new TextureWrapperSurfaceManager(sd);
86+
}
87+
88+
public long getSharedOpenGLContext(GraphicsConfiguration gc) {
89+
if (gc instanceof GLXGraphicsConfig) {
90+
return GLXGraphicsConfigExt.getSharedContext();
91+
}
92+
93+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
94+
}
95+
96+
public long getSharedOpenGLPixelFormat(GraphicsConfiguration gc) {
97+
if (gc instanceof GLXGraphicsConfig) {
98+
return GLXGraphicsConfigExt.getPixelFormat();
99+
}
100+
101+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
102+
}
103+
}

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

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
import sun.awt.image.TextureWrapperSurfaceManager;
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.*;
3636

3737
import java.awt.GraphicsConfiguration;
3838
import java.awt.GraphicsEnvironment;
@@ -42,49 +42,67 @@
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

52-
private SharedTextures() {
53-
textureType = getTextureTypeImpl();
54-
if (textureType == 0) {
55-
throw new JBRApi.ServiceNotAvailableException();
56-
}
57-
}
58-
59-
public int getTextureType() {
60-
return textureType;
61-
}
51+
private SharedTextures() {}
6252

6353
public Image wrapTexture(GraphicsConfiguration gc, long texture) {
6454
return new TextureWrapperImage(gc, texture);
6555
}
6656

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

8080
static SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
8181
SurfaceData sd;
8282
if (gc instanceof MTLGraphicsConfig mtlGraphicsConfig) {
8383
sd = new MTLTextureWrapperSurfaceData(mtlGraphicsConfig, image, texture);
84+
} else if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
85+
sd = new CGLTextureWrapperSurfaceData(cglGraphicsConfig, image, texture);
8486
} else {
8587
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
8688
}
8789

8890
return new TextureWrapperSurfaceManager(sd);
8991
}
92+
93+
public long getSharedOpenGLContext(GraphicsConfiguration gc) {
94+
if (gc instanceof CGLGraphicsConfig) {
95+
return CGLGraphicsConfigExt.getSharedContext();
96+
}
97+
98+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
99+
}
100+
101+
public long getSharedOpenGLPixelFormat(GraphicsConfiguration gc) {
102+
if (gc instanceof CGLGraphicsConfig) {
103+
return CGLGraphicsConfigExt.getPixelFormat();
104+
}
105+
106+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
107+
}
90108
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package sun.java2d.metal;
22

33
public class MTLSurfaceDataExt {
4-
public static native boolean initWithTexture(long pData, boolean isOpaque, long texturePtr);
4+
public static boolean initWithTexture(MTLSurfaceData sd, long texturePtr) {
5+
return initWithTexture(sd.getNativeOps(), false, texturePtr);
6+
}
7+
8+
private static native boolean initWithTexture(long pData, boolean isOpaque, long texturePtr);
59
}

src/java.desktop/macosx/classes/sun/java2d/metal/MTLTextureWrapperSurfaceData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public MTLTextureWrapperSurfaceData(MTLGraphicsConfig gc, Image image, long pTex
2222
rq.lock();
2323
try {
2424
MTLContext.setScratchSurface(gc);
25-
rq.flushAndInvokeNow(() -> success.set(MTLSurfaceDataExt.initWithTexture(getNativeOps(), false, pTexture)));
25+
rq.flushAndInvokeNow(() -> success.set(MTLSurfaceDataExt.initWithTexture(this, pTexture)));
2626
} finally {
2727
rq.unlock();
2828
}
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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
return ptr_to_jlong(sharedContext.CGLContextObj) ;
12+
}
13+
14+
JNIEXPORT jlong JNICALL
15+
Java_sun_java2d_opengl_CGLGraphicsConfigExt_getPixelFormat
16+
(JNIEnv *env, jclass cls) {
17+
return ptr_to_jlong(sharedPixelFormat.CGLPixelFormatObj);
18+
}

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,15 @@ private static SurfaceManager createManager(GraphicsConfiguration gc, Image imag
138138
}
139139

140140
try {
141-
if (gc == null) {
142-
throw new IllegalArgumentException("GraphicsConfiguration cannot be null");
143-
}
144-
if (texture == 0) {
145-
throw new IllegalArgumentException("Invalid texture");
146-
}
147-
148141
return (SurfaceManager) createSurfaceManagerMethod.invoke(null, gc, image, texture);
149-
} catch (java.lang.reflect.InvocationTargetException e) {
150-
if (e.getCause() instanceof IllegalArgumentException iae) {
142+
}
143+
catch (java.lang.reflect.InvocationTargetException e) {
144+
Throwable cause = e.getCause();
145+
if (cause instanceof IllegalArgumentException iae) {
151146
throw iae;
152-
} else if (e.getCause() instanceof UnsupportedOperationException uoe) {
147+
} else if (cause instanceof UnsupportedOperationException uoe) {
153148
throw uoe;
154149
} else {
155-
Throwable cause = e.getTargetException();
156150
String message = String.format("Failed to create surface manager - Cause: %s, Message: %s",
157151
cause.getClass().getName(),
158152
cause.getMessage());

0 commit comments

Comments
 (0)