diff --git a/src/com/jetbrains/Extensions.java b/src/com/jetbrains/Extensions.java
index 67ef074..e5596a3 100644
--- a/src/com/jetbrains/Extensions.java
+++ b/src/com/jetbrains/Extensions.java
@@ -30,5 +30,9 @@ public enum Extensions {
/**
* Opts-in {@link com.jetbrains.SystemUtils#shrinkingGC}
*/
- SHRINKING_GC
+ SHRINKING_GC,
+ /**
+ * Extends SharedTextures service with OpenGL support
+ */
+ SHARED_TEXTURES_OPENGL,
}
diff --git a/src/com/jetbrains/SharedTextures.java b/src/com/jetbrains/SharedTextures.java
index 4b8c80f..5b09d12 100644
--- a/src/com/jetbrains/SharedTextures.java
+++ b/src/com/jetbrains/SharedTextures.java
@@ -20,6 +20,8 @@
/**
* The service provides functionality for working with shared textures in JetBrainsRuntime.
+ *
+ * This service is experemental and could be replaced with another service or deprecated.
*/
@Service
@Provided
@@ -30,10 +32,29 @@ public interface SharedTextures {
public final static int METAL_TEXTURE_TYPE = 1;
/**
- * Returns the texture type supported by the current rendering pipeling.
+ * OpenGL textures are supported
+ */
+ public final static int OPENGL_TEXTURE_TYPE = 2;
+
+
+ /**
+ * Returns the texture type supported by the graphics configuration.
+ *
+ * @param gc the GraphicsConfiguration
+ * @return the type of shared texture supported.
+ */
+ @Extension(Extensions.SHARED_TEXTURES_OPENGL)
+ int getTextureType(GraphicsConfiguration gc);
+
+ /**
+ * Returns the texture type supported by the default graphics configuration
+ * of the default graphics device.
*
* @return the type of shared texture supported.
+ * @deprecated The graphics environment may contain configurations of different types.
+ * Use {@link #getTextureType(GraphicsConfiguration)} instead.
*/
+ @Deprecated
int getTextureType();
/**
@@ -50,10 +71,11 @@ public interface SharedTextures {
*
Client code is responsible for ensuring proper synchronization. All operations involving
* the texture must have been completed before the resulting image is used within the JBR rendering
* pipeline.
- * Texture liftime:
+ * Texture lifespan:
*
- * - Metal: This texture is retained for the wrapping image lifetime and will be released
+ *
- Metal: This texture is retained for the wrapping image lifespan and will be released
* after the image has been disposed.
+ * - OpenGL: The wrapping image doesn't take owernship over the texute.
*
*
*
@@ -62,11 +84,43 @@ public interface SharedTextures {
* @param texture the texture to be wrapped.
* Platform-specific:
*
- * - macOS (with the Metal rendering pipeline): a pointer to an {@code MTLTexture} object
+ * - Metal: an {@code MTLTexture} object pointer
+ * - OpenGL: a texture id({@code GLuint})
*
* @return a wrapping image compatible with the specified {@code GraphicsConfiguration}.
* @throws UnsupportedOperationException if the current pipeline is not supported.
* @throws IllegalArgumentException if the texture cannot be wrapped. The details are logged in {@code J2D_TRACE_ERROR}.
*/
Image wrapTexture(GraphicsConfiguration gc, long texture);
+
+ /**
+ * Provides information needed for using shared OpenGL context.
+ *
+ * @param gc the target {@link GraphicsConfiguration}.
+ *
+ * @return an array of
+ *
+ * - 2 elements(Windows):
+ *
+ * - 0 - handle to an OpenGL Rendering Context ({@code HGLRC})
+ * - 1 - pixel format index (see Win32 {@code SetPixelFormat})
+ *
+ *
+ * - 3 elements(Linux):
+ *
+ * - 0 - shared context handle ({@code GLXContext})
+ * - 1 - Xlib connection pointer ({@code Display*})
+ * - 2 - GLX frame buffer configuration ({@code GLXFBConfig})
+ *
+ *
+ * - 2 elements(macOS):
+ *
+ * - 0 - shared context ({@code CGLContextObj})
+ * - 1 - pixel format ({@code CGLPixelFormatObj})
+ *
+ *
+ *
+ */
+ @Extension(Extensions.SHARED_TEXTURES_OPENGL)
+ long[] getOpenGLContextInfo(GraphicsConfiguration gc) throws UnsupportedOperationException;
}
diff --git a/tests/SharedTexturesTest.java b/tests/SharedTexturesTest.java
new file mode 100644
index 0000000..be8f41d
--- /dev/null
+++ b/tests/SharedTexturesTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2025 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @test
+ *
+ * @summary Checks SharedTexture service presence on Linux
+ * @requires (os.family == "linux")
+ *
+ * @run main/othervm -Dsun.java2d.opengl=True -DsharedTexturesSupported=True SharedTexturesTest
+ */
+
+/**
+ * @test
+ *
+ * @summary Checks SharedTexture service presence on Windows
+ * @requires (os.family == "windows")
+ *
+ * @run main/othervm -Dsun.java2d.opengl=True -DsharedTexturesSupported=True SharedTexturesTest
+ */
+
+/**
+ * @test
+ *
+ * @summary Checks SharedTexture service presence on Windows
+ * @requires (os.family == "mac")
+ *
+ * @run main/othervm -Dsun.java2d.opengl=True -DsharedTexturesSupported=True SharedTexturesTest
+ * @run main/othervm -Dsun.java2d.metal=True -DsharedTexturesSupported=True SharedTexturesTest
+ */
+
+
+import com.jetbrains.Extensions;
+import com.jetbrains.JBR;
+import com.jetbrains.SharedTextures;
+
+import java.awt.*;
+
+public class SharedTexturesTest {
+ final static GraphicsConfiguration gc = GraphicsEnvironment
+ .getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice()
+ .getDefaultConfiguration();
+
+ public static void main(String[] args) {
+ if (!JBR.isSharedTexturesSupported()) {
+ throw new RuntimeException("SharedTextures are not supported");
+ }
+
+ SharedTextures sharedTexturesService = JBR.getSharedTextures(Extensions.SHARED_TEXTURES_OPENGL);
+ if (sharedTexturesService == null) {
+ throw new RuntimeException("Extensions.SHARED_TEXTURES_OPENGL is not available");
+ }
+
+ int expectedTextureType = getExpectedTextureType();
+ int actualTextureType = sharedTexturesService.getTextureType(gc);
+
+ if (actualTextureType != expectedTextureType) {
+ throw new RuntimeException("Expected texture type: " + expectedTextureType + ", actual: " + actualTextureType);
+ }
+
+ if (actualTextureType == SharedTextures.OPENGL_TEXTURE_TYPE) {
+ int sharedContextSize = System.getProperty("os.name").toLowerCase().contains("linux") ? 3 : 2;
+ long[] sharedOpenGLContext = sharedTexturesService.getOpenGLContextInfo(gc);
+ if (sharedOpenGLContext.length != sharedContextSize) {
+ throw new RuntimeException("getSharedOpenGLContext: Expected " + sharedContextSize + " elements, actual: " + sharedOpenGLContext.length);
+ }
+ }
+
+ {
+ boolean illegalArgumentExceptionThrown = false;
+ try {
+ sharedTexturesService.wrapTexture(gc, 0);
+ } catch (IllegalArgumentException e) {
+ illegalArgumentExceptionThrown = true;
+ }
+ if (!illegalArgumentExceptionThrown) {
+ throw new RuntimeException("Expected IllegalArgumentException");
+ }
+ }
+ }
+
+ public static int getExpectedTextureType() {
+ if ("true".equalsIgnoreCase(System.getProperty("sun.java2d.opengl"))) {
+ return SharedTextures.OPENGL_TEXTURE_TYPE;
+ } else if ("true".equalsIgnoreCase(System.getProperty("sun.java2d.metal"))) {
+ return SharedTextures.METAL_TEXTURE_TYPE;
+ }
+
+ throw new InternalError("Unexpected rendering pipeline. The default graphics config: " + gc.toString());
+ }
+}