Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m
41159 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
return;
84
}
85
86
if (self.nextDrawableCount != 0) {
87
return;
88
}
89
@autoreleasepool {
90
if ((self.buffer.width == 0) || (self.buffer.height == 0)) {
91
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: cannot create drawable of size 0");
92
return;
93
}
94
95
NSUInteger src_x = self.leftInset * self.contentsScale;
96
NSUInteger src_y = self.topInset * self.contentsScale;
97
NSUInteger src_w = self.buffer.width - src_x;
98
NSUInteger src_h = self.buffer.height - src_y;
99
100
if (src_h <= 0 || src_w <= 0) {
101
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: Invalid src width or height.");
102
return;
103
}
104
105
id<MTLCommandBuffer> commandBuf = [self.ctx createBlitCommandBuffer];
106
if (commandBuf == nil) {
107
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: commandBuf is null");
108
return;
109
}
110
id<CAMetalDrawable> mtlDrawable = [self nextDrawable];
111
if (mtlDrawable == nil) {
112
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nextDrawable is null)");
113
return;
114
}
115
self.nextDrawableCount++;
116
117
id <MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder];
118
119
[blitEncoder
120
copyFromTexture:self.buffer sourceSlice:0 sourceLevel:0
121
sourceOrigin:MTLOriginMake(src_x, src_y, 0)
122
sourceSize:MTLSizeMake(src_w, src_h, 1)
123
toTexture:mtlDrawable.texture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(0, 0, 0)];
124
[blitEncoder endEncoding];
125
126
[commandBuf presentDrawable:mtlDrawable];
127
[commandBuf addCompletedHandler:^(id <MTLCommandBuffer> commandBuf) {
128
self.nextDrawableCount--;
129
}];
130
131
[commandBuf commit];
132
[self stopDisplayLink];
133
}
134
}
135
136
- (void) dealloc {
137
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
138
(*env)->DeleteWeakGlobalRef(env, self.javaLayer);
139
self.javaLayer = nil;
140
[self stopDisplayLink];
141
CVDisplayLinkRelease(self.displayLink);
142
self.displayLink = nil;
143
[super dealloc];
144
}
145
146
- (void) blitCallback {
147
148
JNIEnv *env = [ThreadUtilities getJNIEnv];
149
DECLARE_CLASS(jc_JavaLayer, "sun/java2d/metal/MTLLayer");
150
DECLARE_METHOD(jm_drawInMTLContext, jc_JavaLayer, "drawInMTLContext", "()V");
151
152
jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer);
153
if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
154
return;
155
}
156
157
(*env)->CallVoidMethod(env, javaLayerLocalRef, jm_drawInMTLContext);
158
CHECK_EXCEPTION();
159
(*env)->DeleteLocalRef(env, javaLayerLocalRef);
160
}
161
162
- (void) display {
163
AWT_ASSERT_APPKIT_THREAD;
164
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_display() called");
165
[self blitCallback];
166
[super display];
167
}
168
169
- (void) redraw {
170
AWT_ASSERT_APPKIT_THREAD;
171
[self setNeedsDisplay];
172
}
173
174
- (void) startDisplayLink {
175
if (!CVDisplayLinkIsRunning(self.displayLink))
176
CVDisplayLinkStart(self.displayLink);
177
}
178
179
- (void) stopDisplayLink {
180
if (CVDisplayLinkIsRunning(self.displayLink))
181
CVDisplayLinkStop(self.displayLink);
182
}
183
184
CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
185
{
186
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_displayLinkCallback() called");
187
@autoreleasepool {
188
MTLLayer *layer = (__bridge MTLLayer *)displayLinkContext;
189
[layer performSelectorOnMainThread:@selector(redraw) withObject:nil waitUntilDone:NO];
190
}
191
return kCVReturnSuccess;
192
}
193
@end
194
195
/*
196
* Class: sun_java2d_metal_MTLLayer
197
* Method: nativeCreateLayer
198
* Signature: ()J
199
*/
200
JNIEXPORT jlong JNICALL
201
Java_sun_java2d_metal_MTLLayer_nativeCreateLayer
202
(JNIEnv *env, jobject obj)
203
{
204
__block MTLLayer *layer = nil;
205
206
JNI_COCOA_ENTER(env);
207
208
jobject javaLayer = (*env)->NewWeakGlobalRef(env, obj);
209
210
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
211
AWT_ASSERT_APPKIT_THREAD;
212
213
layer = [[MTLLayer alloc] initWithJavaLayer: javaLayer];
214
}];
215
216
JNI_COCOA_EXIT(env);
217
218
return ptr_to_jlong(layer);
219
}
220
221
// Must be called under the RQ lock.
222
JNIEXPORT void JNICALL
223
Java_sun_java2d_metal_MTLLayer_validate
224
(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
225
{
226
MTLLayer *layer = OBJC(layerPtr);
227
228
if (surfaceData != NULL) {
229
BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData);
230
layer.bufferWidth = bmtlsdo->width;
231
layer.bufferHeight = bmtlsdo->width;
232
layer.buffer = bmtlsdo->pTexture;
233
layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
234
layer.device = layer.ctx.device;
235
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
236
layer.drawableSize =
237
CGSizeMake(layer.buffer.width,
238
layer.buffer.height);
239
[layer startDisplayLink];
240
} else {
241
layer.ctx = NULL;
242
[layer stopDisplayLink];
243
}
244
}
245
246
JNIEXPORT void JNICALL
247
Java_sun_java2d_metal_MTLLayer_nativeSetScale
248
(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
249
{
250
JNI_COCOA_ENTER(env);
251
MTLLayer *layer = jlong_to_ptr(layerPtr);
252
// We always call all setXX methods asynchronously, exception is only in
253
// this method where we need to change native texture size and layer's scale
254
// in one call on appkit, otherwise we'll get window's contents blinking,
255
// during screen-2-screen moving.
256
[ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
257
layer.contentsScale = scale;
258
}];
259
JNI_COCOA_EXIT(env);
260
}
261
262
JNIEXPORT void JNICALL
263
Java_sun_java2d_metal_MTLLayer_nativeSetInsets
264
(JNIEnv *env, jclass cls, jlong layerPtr, jint top, jint left)
265
{
266
MTLLayer *layer = jlong_to_ptr(layerPtr);
267
layer.topInset = top;
268
layer.leftInset = left;
269
}
270
271
JNIEXPORT void JNICALL
272
Java_sun_java2d_metal_MTLLayer_blitTexture
273
(JNIEnv *env, jclass cls, jlong layerPtr)
274
{
275
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blitTexture");
276
MTLLayer *layer = jlong_to_ptr(layerPtr);
277
MTLContext * ctx = layer.ctx;
278
if (layer == NULL || ctx == NULL) {
279
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blit : Layer or Context is null");
280
return;
281
}
282
283
[layer blitTexture];
284
}
285
286