Skip to content

Commit 67e68d3

Browse files
committed
JBR-8118 metal: refactor shared textures
1 parent f043fcc commit 67e68d3

File tree

12 files changed

+262
-223
lines changed

12 files changed

+262
-223
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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.TextureWrapperSurfaceManager;
29+
import com.jetbrains.exported.JBRApi;
30+
import sun.awt.image.SurfaceManager;
31+
import sun.java2d.SurfaceData;
32+
import sun.java2d.metal.MTLGraphicsConfig;
33+
import sun.java2d.metal.MTLTextureWrapperSurfaceData;
34+
35+
import java.awt.GraphicsConfiguration;
36+
import java.awt.GraphicsEnvironment;
37+
import java.awt.Image;
38+
39+
@JBRApi.Service
40+
@JBRApi.Provides("SharedTextures")
41+
public class SharedTexturesService extends SharedTextures {
42+
private final int textureType;
43+
44+
public SharedTexturesService() {
45+
textureType = getTextureTypeImpl();
46+
if (textureType == UNDEFINED_TEXTURE_TYPE) {
47+
throw new JBRApi.ServiceNotAvailableException();
48+
}
49+
}
50+
51+
@Override
52+
public int getTextureType() {
53+
return textureType;
54+
}
55+
56+
private static int getTextureTypeImpl() {
57+
GraphicsConfiguration gc = GraphicsEnvironment
58+
.getLocalGraphicsEnvironment()
59+
.getDefaultScreenDevice()
60+
.getDefaultConfiguration();
61+
62+
if (gc instanceof MTLGraphicsConfig) {
63+
return METAL_TEXTURE_TYPE;
64+
}
65+
66+
return 0;
67+
}
68+
69+
@Override
70+
protected SurfaceManager createSurfaceManager(GraphicsConfiguration gc, Image image, long texture) {
71+
SurfaceData sd;
72+
if (gc instanceof MTLGraphicsConfig mtlGraphicsConfig) {
73+
sd = new MTLTextureWrapperSurfaceData(mtlGraphicsConfig, image, texture);
74+
} else {
75+
throw new IllegalArgumentException("Unsupported graphics configuration: " + gc);
76+
}
77+
78+
return new TextureWrapperSurfaceManager(sd);
79+
}
80+
}

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
3131
import sun.awt.image.OffScreenImage;
3232
import sun.awt.image.SunVolatileImage;
3333
import sun.awt.image.SurfaceManager;
34-
import sun.awt.image.TextureWrapperSurfaceManager;
3534
import sun.awt.image.VolatileSurfaceManager;
3635
import sun.java2d.Disposer;
3736
import sun.java2d.DisposerRecord;
@@ -49,7 +48,6 @@
4948
import java.awt.Component;
5049
import java.awt.Graphics;
5150
import java.awt.Graphics2D;
52-
import java.awt.GraphicsConfiguration;
5351
import java.awt.Image;
5452
import java.awt.ImageCapabilities;
5553
import java.awt.Rectangle;
@@ -71,7 +69,7 @@
7169
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
7270

7371
public final class MTLGraphicsConfig extends CGraphicsConfig
74-
implements AccelGraphicsConfig, SurfaceManager.Factory, SurfaceManager.TextureWrapperFactory
72+
implements AccelGraphicsConfig, SurfaceManager.Factory
7573
{
7674
private static ImageCapabilities imageCaps = new MTLImageCaps();
7775

@@ -382,11 +380,4 @@ public VolatileSurfaceManager createVolatileManager(SunVolatileImage image,
382380
Object context) {
383381
return new MTLVolatileSurfaceManager(image, context);
384382
}
385-
386-
@Override
387-
public SurfaceManager createTextureWrapperSurfaceManager(
388-
GraphicsConfiguration gc, Image image, long texture) {
389-
SurfaceData sd = MTLSurfaceData.createData(this, image, texture);
390-
return new TextureWrapperSurfaceManager(sd);
391-
}
392383
}

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

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050

5151
import java.awt.image.ColorModel;
5252
import java.awt.image.Raster;
53-
import java.util.concurrent.atomic.AtomicBoolean;
5453

5554
import static sun.java2d.pipe.BufferedOpCodes.DISPOSE_SURFACE;
5655
import static sun.java2d.pipe.BufferedOpCodes.FLUSH_SURFACE;
@@ -152,7 +151,7 @@ private static SurfaceType getCustomSurfaceType(int mtlType) {
152151
private native void initOps(MTLGraphicsConfig gc, long pConfigInfo, long pPeerData, long layerPtr,
153152
int xoff, int yoff, boolean isOpaque);
154153

155-
private MTLSurfaceData(MTLLayer layer, MTLGraphicsConfig gc,
154+
protected MTLSurfaceData(MTLLayer layer, MTLGraphicsConfig gc,
156155
ColorModel cm, int type, int width, int height)
157156
{
158157
super(getCustomSurfaceType(type), cm);
@@ -201,10 +200,6 @@ public static MTLOffScreenSurfaceData createData(MTLGraphicsConfig gc,
201200
type);
202201
}
203202

204-
public static MTLTextureWrapperSurfaceData createData(MTLGraphicsConfig gc, Image image, long pTexture) {
205-
return new MTLTextureWrapperSurfaceData(gc, image, pTexture);
206-
}
207-
208203
@Override
209204
public double getDefaultScaleX() {
210205
return scale;
@@ -224,8 +219,6 @@ public Rectangle getBounds() {
224219

225220
protected native boolean initTexture(long pData, boolean isOpaque, int width, int height);
226221

227-
protected native boolean initWithTexture(long pData, boolean isOpaque, long texturePtr);
228-
229222
protected native boolean initRTexture(long pData, boolean isOpaque, int width, int height);
230223

231224
protected native boolean initFlipBackbuffer(long pData, boolean isOpaque, int width, int height);
@@ -689,46 +682,4 @@ protected void loadNativeRaster(long pRaster, int width, int height, long pRects
689682
}
690683

691684
private static native boolean loadNativeRasterWithRects(long sdops, long pRaster, int width, int height, long pRects, int rectsCount);
692-
693-
/**
694-
* Surface data for an existing texture
695-
*/
696-
public static final class MTLTextureWrapperSurfaceData extends MTLSurfaceData {
697-
private final Image myImage;
698-
699-
private MTLTextureWrapperSurfaceData(MTLGraphicsConfig gc, Image image, long pTexture) throws IllegalArgumentException {
700-
super(null, gc, ColorModel.getRGBdefault(), RT_TEXTURE, /*width=*/ 0, /*height=*/ 0);
701-
myImage = image;
702-
703-
MTLRenderQueue rq = MTLRenderQueue.getInstance();
704-
AtomicBoolean success = new AtomicBoolean(false);
705-
706-
rq.lock();
707-
try {
708-
MTLContext.setScratchSurface(gc);
709-
rq.flushAndInvokeNow(() -> success.set(initWithTexture(getNativeOps(), false, pTexture)));
710-
} finally {
711-
rq.unlock();
712-
}
713-
714-
if (!success.get()) {
715-
throw new IllegalArgumentException("Failed to init the surface data");
716-
}
717-
}
718-
719-
@Override
720-
public SurfaceData getReplacement() {
721-
throw new UnsupportedOperationException("not implemented");
722-
}
723-
724-
@Override
725-
public Object getDestination() {
726-
return myImage;
727-
}
728-
729-
@Override
730-
public Rectangle getBounds() {
731-
return getNativeBounds();
732-
}
733-
}
734685
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package sun.java2d.metal;
2+
3+
public class MTLSurfaceDataExt {
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);
9+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package sun.java2d.metal;
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+
/**
10+
* Surface data for an existing texture
11+
*/
12+
public final class MTLTextureWrapperSurfaceData extends MTLSurfaceData {
13+
private final Image myImage;
14+
15+
public MTLTextureWrapperSurfaceData(MTLGraphicsConfig gc, Image image, long pTexture) throws IllegalArgumentException {
16+
super(null, gc, gc.getColorModel(TRANSLUCENT), RT_TEXTURE, /*width=*/ 0, /*height=*/ 0);
17+
myImage = image;
18+
19+
MTLRenderQueue rq = MTLRenderQueue.getInstance();
20+
AtomicBoolean success = new AtomicBoolean(false);
21+
22+
rq.lock();
23+
try {
24+
MTLContext.setScratchSurface(gc);
25+
rq.flushAndInvokeNow(() -> success.set(MTLSurfaceDataExt.initWithTexture(this, pTexture)));
26+
} finally {
27+
rq.unlock();
28+
}
29+
30+
if (!success.get()) {
31+
throw new IllegalArgumentException("Failed to init the surface data");
32+
}
33+
}
34+
35+
@Override
36+
public SurfaceData getReplacement() {
37+
throw new UnsupportedOperationException("not implemented");
38+
}
39+
40+
@Override
41+
public Object getDestination() {
42+
return myImage;
43+
}
44+
45+
@Override
46+
public Rectangle getBounds() {
47+
return getNativeBounds();
48+
}
49+
}

src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -107,81 +107,6 @@ static jboolean MTLSurfaceData_initTexture(BMTLSDOps *bmtlsdo, jboolean isOpaque
107107
}
108108
}
109109

110-
static jboolean MTLSurfaceData_initWithTexture(BMTLSDOps *bmtlsdo, jboolean isOpaque, void* pTexture) {
111-
@autoreleasepool {
112-
if (bmtlsdo == NULL) {
113-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: ops are null");
114-
return JNI_FALSE;
115-
}
116-
117-
if (pTexture == NULL) {
118-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: texture is null");
119-
return JNI_FALSE;
120-
}
121-
122-
id <MTLTexture> texture = (__bridge id <MTLTexture>) pTexture;
123-
if (texture == NULL) {
124-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: failed to cast texture to MTLTexture");
125-
return JNI_FALSE;
126-
}
127-
128-
if (texture.width >= MTL_GPU_FAMILY_MAC_TXT_SIZE || texture.height >= MTL_GPU_FAMILY_MAC_TXT_SIZE ||
129-
texture.width == 0 || texture.height == 0) {
130-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: wrong texture size %d x %d",
131-
texture.width, texture.height);
132-
return JNI_FALSE;
133-
}
134-
135-
if (texture.pixelFormat != MTLPixelFormatBGRA8Unorm) {
136-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: unsupported pixel format: %d",
137-
texture.pixelFormat);
138-
return JNI_FALSE;
139-
}
140-
141-
bmtlsdo->pTexture = texture;
142-
bmtlsdo->pOutTexture = NULL;
143-
144-
MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps;
145-
if (mtlsdo == NULL) {
146-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: MTLSDOps are null");
147-
return JNI_FALSE;
148-
}
149-
if (mtlsdo->configInfo == NULL || mtlsdo->configInfo->context == NULL) {
150-
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initWithTexture: MTLSDOps wasn't initialized (context is null)");
151-
return JNI_FALSE;
152-
}
153-
MTLContext* ctx = mtlsdo->configInfo->context;
154-
MTLTextureDescriptor *stencilDataDescriptor =
155-
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Uint
156-
width:texture.width
157-
height:texture.height
158-
mipmapped:NO];
159-
stencilDataDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
160-
stencilDataDescriptor.storageMode = MTLStorageModePrivate;
161-
bmtlsdo->pStencilData = [ctx.device newTextureWithDescriptor:stencilDataDescriptor];
162-
163-
MTLTextureDescriptor *stencilTextureDescriptor =
164-
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatStencil8
165-
width:texture.width
166-
height:texture.height
167-
mipmapped:NO];
168-
stencilTextureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
169-
stencilTextureDescriptor.storageMode = MTLStorageModePrivate;
170-
bmtlsdo->pStencilTexture = [ctx.device newTextureWithDescriptor:stencilTextureDescriptor];
171-
172-
bmtlsdo->isOpaque = isOpaque;
173-
bmtlsdo->width = texture.width;
174-
bmtlsdo->height = texture.height;
175-
bmtlsdo->drawableType = MTLSD_RT_TEXTURE;
176-
177-
[texture retain];
178-
179-
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLSurfaceData_initTexture: w=%d h=%d bp=%p [tex=%p] opaque=%d sfType=%d",
180-
bmtlsdo->width, bmtlsdo->height, bmtlsdo, bmtlsdo->pTexture, isOpaque, bmtlsdo->drawableType);
181-
return JNI_TRUE;
182-
}
183-
}
184-
185110
/**
186111
* Initializes an MTL texture, using the given width and height as
187112
* a guide.
@@ -198,19 +123,6 @@ static jboolean MTLSurfaceData_initWithTexture(BMTLSDOps *bmtlsdo, jboolean isOp
198123
return JNI_TRUE;
199124
}
200125

201-
JNIEXPORT jboolean JNICALL
202-
Java_sun_java2d_metal_MTLSurfaceData_initWithTexture(
203-
JNIEnv *env, jobject mtlds,
204-
jlong pData, jboolean isOpaque,
205-
jlong pTexture) {
206-
BMTLSDOps *bmtlsdops = (BMTLSDOps *) pData;
207-
if (!MTLSurfaceData_initWithTexture(bmtlsdops, isOpaque, jlong_to_ptr(pTexture))) {
208-
return JNI_FALSE;
209-
}
210-
MTLSD_SetNativeDimensions(env, (BMTLSDOps *) pData, bmtlsdops->width, bmtlsdops->height);
211-
return JNI_TRUE;
212-
}
213-
214126
/**
215127
* Initializes a framebuffer object, using the given width and height as
216128
* a guide. See MTLSD_InitTextureObject() and MTLSD_initRTexture()

0 commit comments

Comments
 (0)