Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m
66646 views
1
/*
2
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
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
#import "MTLGraphicsConfig.h"
27
#import "MTLLayer.h"
28
#import "ThreadUtilities.h"
29
#import "LWCToolkit.h"
30
#import "MTLSurfaceData.h"
31
#import "JNIUtilities.h"
32
33
@implementation MTLLayer
34
35
36
@synthesize javaLayer;
37
@synthesize ctx;
38
@synthesize bufferWidth;
39
@synthesize bufferHeight;
40
@synthesize buffer;
41
@synthesize topInset;
42
@synthesize leftInset;
43
@synthesize nextDrawableCount;
44
@synthesize displayLink;
45
46
- (id) initWithJavaLayer:(jobject)layer
47
{
48
AWT_ASSERT_APPKIT_THREAD;
49
// Initialize ourselves
50
self = [super init];
51
if (self == nil) return self;
52
53
self.javaLayer = layer;
54
55
self.contentsGravity = kCAGravityTopLeft;
56
57
//Disable CALayer's default animation
58
NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
59
[NSNull null], @"anchorPoint",
60
[NSNull null], @"bounds",
61
[NSNull null], @"contents",
62
[NSNull null], @"contentsScale",
63
[NSNull null], @"onOrderIn",
64
[NSNull null], @"onOrderOut",
65
[NSNull null], @"position",
66
[NSNull null], @"sublayers",
67
nil];
68
self.actions = actions;
69
[actions release];
70
self.topInset = 0;
71
self.leftInset = 0;
72
self.framebufferOnly = NO;
73
self.nextDrawableCount = 0;
74
self.opaque = FALSE;
75
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
76
CVDisplayLinkSetOutputCallback(displayLink, &displayLinkCallback, (__bridge void*)self);
77
return self;
78
}
79
80
- (void) blitTexture {
81
if (self.ctx == NULL || self.javaLayer == NULL || self.buffer == nil || self.ctx.device == nil) {
82
J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: uninitialized (mtlc=%p, javaLayer=%p, buffer=%p, devide=%p)", self.ctx, self.javaLayer, self.buffer, ctx.device);
83
[self stopDisplayLink];
84
return;
85
}
86
87
if (self.nextDrawableCount != 0) {
88
return;
89
}
90
@autoreleasepool {
91
if ((self.buffer.width == 0) || (self.buffer.height == 0)) {
92
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: cannot create drawable of size 0");
93
[self stopDisplayLink];
94
return;
95
}
96
97
NSUInteger src_x = self.leftInset * self.contentsScale;
98
NSUInteger src_y = self.topInset * self.contentsScale;
99
NSUInteger src_w = self.buffer.width - src_x;
100
NSUInteger src_h = self.buffer.height - src_y;
101
102
if (src_h <= 0 || src_w <= 0) {
103
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: Invalid src width or height.");
104
[self stopDisplayLink];
105
return;
106
}
107
108
id<MTLCommandBuffer> commandBuf = [self.ctx createBlitCommandBuffer];
109
if (commandBuf == nil) {
110
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: commandBuf is null");
111
[self stopDisplayLink];
112
return;
113
}
114
id<CAMetalDrawable> mtlDrawable = [self nextDrawable];
115
if (mtlDrawable == nil) {
116
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nextDrawable is null)");
117
[self stopDisplayLink];
118
return;
119
}
120
self.nextDrawableCount++;
121
122
id <MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder];
123
124
[blitEncoder
125
copyFromTexture:self.buffer sourceSlice:0 sourceLevel:0
126
sourceOrigin:MTLOriginMake(src_x, src_y, 0)
127
sourceSize:MTLSizeMake(src_w, src_h, 1)
128
toTexture:mtlDrawable.texture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(0, 0, 0)];
129
[blitEncoder endEncoding];
130
131
[commandBuf presentDrawable:mtlDrawable];
132
[commandBuf addCompletedHandler:^(id <MTLCommandBuffer> commandBuf) {
133
self.nextDrawableCount--;
134
}];
135
136
[commandBuf commit];
137
[self stopDisplayLink];
138
}
139
}
140
141
- (void) dealloc {
142
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
143
(*env)->DeleteWeakGlobalRef(env, self.javaLayer);
144
self.javaLayer = nil;
145
[self stopDisplayLink];
146
CVDisplayLinkRelease(self.displayLink);
147
self.displayLink = nil;
148
[super dealloc];
149
}
150
151
- (void) blitCallback {
152
153
JNIEnv *env = [ThreadUtilities getJNIEnv];
154
DECLARE_CLASS(jc_JavaLayer, "sun/java2d/metal/MTLLayer");
155
DECLARE_METHOD(jm_drawInMTLContext, jc_JavaLayer, "drawInMTLContext", "()V");
156
157
jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer);
158
if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
159
return;
160
}
161
162
(*env)->CallVoidMethod(env, javaLayerLocalRef, jm_drawInMTLContext);
163
CHECK_EXCEPTION();
164
(*env)->DeleteLocalRef(env, javaLayerLocalRef);
165
}
166
167
- (void) display {
168
AWT_ASSERT_APPKIT_THREAD;
169
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_display() called");
170
[self blitCallback];
171
[super display];
172
}
173
174
- (void) redraw {
175
AWT_ASSERT_APPKIT_THREAD;
176
[self setNeedsDisplay];
177
}
178
179
- (void) startDisplayLink {
180
if (!CVDisplayLinkIsRunning(self.displayLink))
181
CVDisplayLinkStart(self.displayLink);
182
}
183
184
- (void) stopDisplayLink {
185
if (CVDisplayLinkIsRunning(self.displayLink))
186
CVDisplayLinkStop(self.displayLink);
187
}
188
189
CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
190
{
191
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_displayLinkCallback() called");
192
@autoreleasepool {
193
MTLLayer *layer = (__bridge MTLLayer *)displayLinkContext;
194
[layer performSelectorOnMainThread:@selector(redraw) withObject:nil waitUntilDone:NO];
195
}
196
return kCVReturnSuccess;
197
}
198
@end
199
200
/*
201
* Class: sun_java2d_metal_MTLLayer
202
* Method: nativeCreateLayer
203
* Signature: ()J
204
*/
205
JNIEXPORT jlong JNICALL
206
Java_sun_java2d_metal_MTLLayer_nativeCreateLayer
207
(JNIEnv *env, jobject obj)
208
{
209
__block MTLLayer *layer = nil;
210
211
JNI_COCOA_ENTER(env);
212
213
jobject javaLayer = (*env)->NewWeakGlobalRef(env, obj);
214
215
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
216
AWT_ASSERT_APPKIT_THREAD;
217
218
layer = [[MTLLayer alloc] initWithJavaLayer: javaLayer];
219
}];
220
221
JNI_COCOA_EXIT(env);
222
223
return ptr_to_jlong(layer);
224
}
225
226
// Must be called under the RQ lock.
227
JNIEXPORT void JNICALL
228
Java_sun_java2d_metal_MTLLayer_validate
229
(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
230
{
231
MTLLayer *layer = OBJC(layerPtr);
232
233
if (surfaceData != NULL) {
234
BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData);
235
layer.bufferWidth = bmtlsdo->width;
236
layer.bufferHeight = bmtlsdo->width;
237
layer.buffer = bmtlsdo->pTexture;
238
layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
239
layer.device = layer.ctx.device;
240
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
241
layer.drawableSize =
242
CGSizeMake(layer.buffer.width,
243
layer.buffer.height);
244
[layer startDisplayLink];
245
} else {
246
layer.ctx = NULL;
247
[layer stopDisplayLink];
248
}
249
}
250
251
JNIEXPORT void JNICALL
252
Java_sun_java2d_metal_MTLLayer_nativeSetScale
253
(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
254
{
255
JNI_COCOA_ENTER(env);
256
MTLLayer *layer = jlong_to_ptr(layerPtr);
257
// We always call all setXX methods asynchronously, exception is only in
258
// this method where we need to change native texture size and layer's scale
259
// in one call on appkit, otherwise we'll get window's contents blinking,
260
// during screen-2-screen moving.
261
[ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
262
layer.contentsScale = scale;
263
}];
264
JNI_COCOA_EXIT(env);
265
}
266
267
JNIEXPORT void JNICALL
268
Java_sun_java2d_metal_MTLLayer_nativeSetInsets
269
(JNIEnv *env, jclass cls, jlong layerPtr, jint top, jint left)
270
{
271
MTLLayer *layer = jlong_to_ptr(layerPtr);
272
layer.topInset = top;
273
layer.leftInset = left;
274
}
275
276
JNIEXPORT void JNICALL
277
Java_sun_java2d_metal_MTLLayer_blitTexture
278
(JNIEnv *env, jclass cls, jlong layerPtr)
279
{
280
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blitTexture");
281
MTLLayer *layer = jlong_to_ptr(layerPtr);
282
MTLContext * ctx = layer.ctx;
283
if (layer == NULL || ctx == NULL) {
284
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blit : Layer or Context is null");
285
[layer stopDisplayLink];
286
return;
287
}
288
289
[layer blitTexture];
290
}
291
292