Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion make/test/JtregNativeJdk.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ ifeq ($(call isTargetOs, macosx), true)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestDynamicStore := \
-framework Cocoa -framework SystemConfiguration
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := \
-framework Cocoa -framework Metal
-framework Cocoa -framework Metal -framework OpenGL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot whether I already asked this, but do we really need an OGL implementation on macOS, given that it's deprecated there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we talked about it and concluded that it won't heart. :)

We still have this pipeline, the OS still supports it so far.

BUILD_JDK_JTREG_EXCLUDE += libSharedTexturesTest.c
else
BUILD_JDK_JTREG_EXCLUDE += libTestMainKeyWindow.m
BUILD_JDK_JTREG_EXCLUDE += libTestDynamicStore.m
Expand All @@ -109,6 +110,7 @@ endif
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libwindows_touch_robot := user32.lib
BUILD_JDK_JTREG_EXCLUDE += libtouchscreen_device.c
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := gdi32.lib opengl32.lib user32.lib
else
ifeq ($(OPENJDK_TARGET_OS), linux)
BUILD_JDK_JTREG_EXCLUDE += libwindows_touch_robot.c
Expand All @@ -124,6 +126,7 @@ ifeq ($(call isTargetOs, linux), true)
BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
# nio tests' libCreationTimeHelper native needs -ldl linker flag
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl
BUILD_JDK_JTREG_LIBRARIES_LIBS_libSharedTexturesTest := -lX11 -lGL -lGLX
endif

ifeq ($(ASAN_ENABLED), true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2025 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package com.jetbrains.desktop;

import com.jetbrains.desktop.image.TextureWrapperSurfaceManager;
import com.jetbrains.exported.JBRApi;
import sun.awt.image.SurfaceManager;
import sun.java2d.SurfaceData;

import sun.java2d.opengl.*;

import java.awt.GraphicsConfiguration;
import java.awt.Image;

@JBRApi.Service
@JBRApi.Provides("SharedTextures")
public class SharedTexturesService extends SharedTextures {
@Override
public int getTextureType(GraphicsConfiguration gc) {
if (gc instanceof GLXGraphicsConfig) {
return OPENGL_TEXTURE_TYPE;
}

return 0;
}

@Override
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
return new long[] {
GLXGraphicsConfigExt.getSharedContext(),
GLXGraphicsConfigExt.getAwtDisplay(),
GLXGraphicsConfigExt.getFBConfig(glxGraphicsConfig),
};
}

throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
}

@Override
public SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
SurfaceData sd;
if (gc instanceof GLXGraphicsConfig glxGraphicsConfig) {
sd = new GLXTextureWrapperSurfaceData(glxGraphicsConfig, image, texture);
} else {
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
}

return new TextureWrapperSurfaceManager(sd);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,21 @@
import sun.java2d.SurfaceData;
import sun.java2d.metal.MTLGraphicsConfig;
import sun.java2d.metal.MTLTextureWrapperSurfaceData;
import sun.java2d.opengl.CGLGraphicsConfig;
import sun.java2d.opengl.CGLGraphicsConfigExt;
import sun.java2d.opengl.CGLTextureWrapperSurfaceData;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.*;

@JBRApi.Service
@JBRApi.Provides("SharedTextures")
public class SharedTexturesService extends SharedTextures {
private final int textureType;

public SharedTexturesService() {
textureType = getTextureTypeImpl();
if (textureType == 0) {
throw new JBRApi.ServiceNotAvailableException();
}
}

@Override
public int getTextureType() {
return textureType;
}

private static int getTextureTypeImpl() {
GraphicsConfiguration gc = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration();

public int getTextureType(GraphicsConfiguration gc) {
if (gc instanceof MTLGraphicsConfig) {
return METAL_TEXTURE_TYPE;
} else if (gc instanceof CGLGraphicsConfig) {
return OPENGL_TEXTURE_TYPE;
}

return 0;
Expand All @@ -71,10 +56,24 @@ protected SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image im
SurfaceData sd;
if (gc instanceof MTLGraphicsConfig mtlGraphicsConfig) {
sd = new MTLTextureWrapperSurfaceData(mtlGraphicsConfig, image, texture);
} else if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
sd = new CGLTextureWrapperSurfaceData(cglGraphicsConfig, image, texture);
} else {
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
}

return new TextureWrapperSurfaceManager(sd);
}

@Override
public long[] getOpenGLContextInfo(GraphicsConfiguration gc) {
if (gc instanceof CGLGraphicsConfig cglGraphicsConfig) {
return new long[] {
CGLGraphicsConfigExt.getSharedContext(),
CGLGraphicsConfigExt.getPixelFormat()
};
}

throw new UnsupportedOperationException("Unsupported graphics configuration: " + gc);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package sun.java2d.opengl;

public class CGLGraphicsConfigExt {
public static native long getSharedContext();
public static native long getPixelFormat();
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
long pPeerData, long layerPtr, int xoff,
int yoff, boolean isOpaque);

private CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
ColorModel cm, int type, int width, int height) {
protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
ColorModel cm, int type, int width, int height) {
super(gc, cm, type);
// TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package sun.java2d.opengl;

import sun.java2d.SurfaceData;

import java.awt.*;
import java.awt.image.ColorModel;
import java.util.concurrent.atomic.AtomicBoolean;

public class CGLTextureWrapperSurfaceData extends CGLSurfaceData {

public CGLTextureWrapperSurfaceData(CGLGraphicsConfig gc, Image image, long textureId) {
super(null, gc, gc.getColorModel(TRANSLUCENT), RT_TEXTURE, 0, 0);

OGLRenderQueue rq = OGLRenderQueue.getInstance();
AtomicBoolean success = new AtomicBoolean(false);
rq.lock();
try {
OGLContext.setScratchSurface(gc);
rq.flushAndInvokeNow(() -> success.set(OGLSurfaceDataExt.initWithTexture(this, textureId)));
} finally {
rq.unlock();
}

if (!success.get()) {
throw new IllegalArgumentException("Failed to init the surface data");
}
}

@Override
public SurfaceData getReplacement() {
throw new UnsupportedOperationException();
}

@Override
public Rectangle getBounds() {
return getNativeBounds();
}

@Override
public Object getDestination() {
return null;
}

@Override
public void flush() {
// reset the texture id first to avoid the texture deallocation
OGLSurfaceDataExt.resetTextureId(this);
super.flush();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#import "sun_java2d_opengl_CGLGraphicsConfigExt.h"

#import "JNIUtilities.h"

extern NSOpenGLContext *sharedContext;
extern NSOpenGLPixelFormat *sharedPixelFormat;

JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfigExt_getSharedContext
(JNIEnv *env, jclass cls)
{
return ptr_to_jlong(sharedContext.CGLContextObj);
}

JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfigExt_getPixelFormat
(JNIEnv *env, jclass cls)
{
return ptr_to_jlong(sharedPixelFormat.CGLPixelFormatObj);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,24 @@

public abstract class SharedTextures {
public final static int METAL_TEXTURE_TYPE = 1;
public final static int OPENGL_TEXTURE_TYPE = 2;

public abstract int getTextureType();
@Deprecated
public int getTextureType() {
GraphicsConfiguration gc = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration();
return getTextureType(gc);
}

public abstract int getTextureType(GraphicsConfiguration gc);

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

public abstract long[] getOpenGLContextInfo(GraphicsConfiguration gc);

protected abstract SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@


public class TextureWrapperSurfaceManager extends SurfaceManager {
private final SurfaceData sd;
private SurfaceData sd;

public TextureWrapperSurfaceManager(SurfaceData sd) {
this.sd = sd;
Expand All @@ -53,4 +53,10 @@ public SurfaceData restoreContents() {
public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
return new ImageCapabilities(true);
}

@Override
public synchronized void flush() {
sd.flush();
sd = null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2025 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package sun.java2d.opengl;

import java.awt.*;

public class OGLGraphicsConfigExt {
public static long getSharedContext(GraphicsConfiguration gc) {
if (gc instanceof OGLGraphicsConfig) {
return getSharedContext();
}

throw new IllegalArgumentException("Not an OpenGL graphics config: " + gc);
}

public static long getPixelFormat(GraphicsConfiguration gc) {
if (gc instanceof OGLGraphicsConfig oglGc) {
return getPixelFormat(oglGc.getNativeConfigInfo());
}

throw new IllegalArgumentException("Not an OpenGL graphics config: " + gc);
}

private static native long getPixelFormat(long pConfigInfo);
private static native long getSharedContext();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2025 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package sun.java2d.opengl;

public class OGLSurfaceDataExt {
public static boolean initWithTexture(OGLSurfaceData surfaceData, long textureId) {
return OGLSurfaceDataExt.initWithTexture(surfaceData.getNativeOps(), textureId);
}

public static void resetTextureId(OGLSurfaceData surfaceData) {
resetTextureId(surfaceData.getNativeOps());
}

private static native boolean initWithTexture(long pData, long textureId);
private static native void resetTextureId(long pData);
}
Loading