Skip to content

Commit cff0f0e

Browse files
committed
opengl: shared textures
1 parent e050cdd commit cff0f0e

File tree

24 files changed

+1423
-56
lines changed

24 files changed

+1423
-56
lines changed

make/test/JtregNativeJdk.gmk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ ifeq ($(call isTargetOs, macosx), true)
9797
BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestDynamicStore := \
9898
-framework Cocoa -framework SystemConfiguration
9999
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := \
100-
-framework Cocoa -framework Metal
100+
-framework Cocoa -framework Metal -framework OpenGL
101+
BUILD_JDK_JTREG_EXCLUDE += libSharedTexturesTest.c
101102
else
102103
BUILD_JDK_JTREG_EXCLUDE += libTestMainKeyWindow.m
103104
BUILD_JDK_JTREG_EXCLUDE += libTestDynamicStore.m
@@ -109,6 +110,7 @@ endif
109110
ifeq ($(OPENJDK_TARGET_OS), windows)
110111
BUILD_JDK_JTREG_LIBRARIES_LIBS_libwindows_touch_robot := user32.lib
111112
BUILD_JDK_JTREG_EXCLUDE += libtouchscreen_device.c
113+
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := gdi32.lib opengl32.lib user32.lib
112114
else
113115
ifeq ($(OPENJDK_TARGET_OS), linux)
114116
BUILD_JDK_JTREG_EXCLUDE += libwindows_touch_robot.c
@@ -124,6 +126,7 @@ ifeq ($(call isTargetOs, linux), true)
124126
BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
125127
# nio tests' libCreationTimeHelper native needs -ldl linker flag
126128
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl
129+
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := -lX11 -lGL -lGLX
127130
endif
128131

129132
ifeq ($(ASAN_ENABLED), true)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
if (gc instanceof GLXGraphicsConfig) {
58+
return OPENGL_TEXTURE_TYPE;
59+
}
60+
61+
return 0;
62+
}
63+
64+
@Deprecated
65+
public int getTextureType() {
66+
GraphicsConfiguration gc = GraphicsEnvironment
67+
.getLocalGraphicsEnvironment()
68+
.getDefaultScreenDevice()
69+
.getDefaultConfiguration();
70+
return getTextureType(gc);
71+
}
72+
73+
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
74+
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
75+
return new long[] {
76+
GLXGraphicsConfigExt.getSharedContext(),
77+
GLXGraphicsConfigExt.getAwtDisplay(),
78+
GLXGraphicsConfigExt.getFBConfig(glxGraphicsConfig),
79+
};
80+
}
81+
82+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
83+
}
84+
85+
static SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
86+
SurfaceData sd;
87+
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
88+
sd = new GLXTextureWrapperSurfaceData(glxGraphicsConfig, image, texture);
89+
} else {
90+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
91+
}
92+
93+
return new TextureWrapperSurfaceManager(sd);
94+
}
95+
}

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

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,36 +31,23 @@
3131
import sun.java2d.SurfaceData;
3232
import sun.java2d.metal.MTLGraphicsConfig;
3333
import sun.java2d.metal.MTLTextureWrapperSurfaceData;
34+
import sun.java2d.opengl.CGLGraphicsConfig;
35+
import sun.java2d.opengl.CGLGraphicsConfigExt;
36+
import sun.java2d.opengl.CGLTextureWrapperSurfaceData;
3437

35-
import java.awt.GraphicsConfiguration;
36-
import java.awt.GraphicsEnvironment;
37-
import java.awt.Image;
38+
import java.awt.*;
3839

3940
@JBRApi.Service
4041
@JBRApi.Provides("SharedTextures")
4142
public class SharedTexturesService extends SharedTextures {
42-
private final int textureType;
43-
4443
public SharedTexturesService() {
45-
textureType = getTextureTypeImpl();
46-
if (textureType == 0) {
47-
throw new JBRApi.ServiceNotAvailableException();
48-
}
49-
}
50-
51-
@Override
52-
public int getTextureType() {
53-
return textureType;
5444
}
5545

56-
private static int getTextureTypeImpl() {
57-
GraphicsConfiguration gc = GraphicsEnvironment
58-
.getLocalGraphicsEnvironment()
59-
.getDefaultScreenDevice()
60-
.getDefaultConfiguration();
61-
46+
public int getTextureType(GraphicsConfiguration gc) {
6247
if (gc instanceof MTLGraphicsConfig) {
6348
return METAL_TEXTURE_TYPE;
49+
} else if (gc instanceof CGLGraphicsConfig) {
50+
return OPENGL_TEXTURE_TYPE;
6451
}
6552

6653
return 0;
@@ -71,10 +58,24 @@ protected SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image im
7158
SurfaceData sd;
7259
if (gc instanceof MTLGraphicsConfig mtlGraphicsConfig) {
7360
sd = new MTLTextureWrapperSurfaceData(mtlGraphicsConfig, image, texture);
61+
} else if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
62+
sd = new CGLTextureWrapperSurfaceData(cglGraphicsConfig, image, texture);
7463
} else {
75-
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
64+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
7665
}
7766

7867
return new TextureWrapperSurfaceManager(sd);
7968
}
69+
70+
@Override
71+
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
72+
if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
73+
return new long[] {
74+
CGLGraphicsConfigExt.getSharedContext(),
75+
CGLGraphicsConfigExt.getPixelFormat()
76+
};
77+
}
78+
79+
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
80+
}
8081
}
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, gc.getColorModel(TRANSLUCENT), 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/SharedTextures.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,24 @@
3232

3333
public abstract class SharedTextures {
3434
public final static int METAL_TEXTURE_TYPE = 1;
35+
public final static int OPENGL_TEXTURE_TYPE = 2;
3536

36-
public abstract int getTextureType();
37+
@Deprecated
38+
public int getTextureType() {
39+
GraphicsConfiguration gc = GraphicsEnvironment
40+
.getLocalGraphicsEnvironment()
41+
.getDefaultScreenDevice()
42+
.getDefaultConfiguration();
43+
return getTextureType(gc);
44+
}
45+
46+
public abstract int getTextureType(GraphicsConfiguration gc);
3747

3848
public final Image wrapTexture(GraphicsConfiguration gc, long texture) {
3949
return new TextureWrapperImage((img) -> createSurfaceManager(gc, img, texture));
4050
}
4151

52+
public abstract long[] getOpenGLContextInfo(GraphicsConfiguration gc);
53+
4254
protected abstract SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture);
4355
}

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)