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/MTLPaints.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
#include "MTLPaints.h"
27
#include "MTLClip.h"
28
#include "common.h"
29
30
#include "sun_java2d_SunGraphics2D.h"
31
#include "sun_java2d_pipe_BufferedPaints.h"
32
#import "MTLComposite.h"
33
#import "MTLBufImgOps.h"
34
#include "MTLRenderQueue.h"
35
36
#define RGBA_TO_V4(c) \
37
{ \
38
(((c) >> 16) & (0xFF))/255.0f, \
39
(((c) >> 8) & 0xFF)/255.0f, \
40
((c) & 0xFF)/255.0f, \
41
(((c) >> 24) & 0xFF)/255.0f \
42
}
43
44
#define FLOAT_ARR_TO_V4(p) \
45
{ \
46
p[0], \
47
p[1], \
48
p[2], \
49
p[3] \
50
}
51
52
static MTLRenderPipelineDescriptor * templateRenderPipelineDesc = nil;
53
static MTLRenderPipelineDescriptor * templateTexturePipelineDesc = nil;
54
static MTLRenderPipelineDescriptor * templateAATexturePipelineDesc = nil;
55
static MTLRenderPipelineDescriptor * templateLCDPipelineDesc = nil;
56
static MTLRenderPipelineDescriptor * templateAAPipelineDesc = nil;
57
static void
58
setTxtUniforms(MTLContext *mtlc, int color, id <MTLRenderCommandEncoder> encoder, int interpolation, bool repeat,
59
jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode);
60
61
static void initTemplatePipelineDescriptors() {
62
if (templateRenderPipelineDesc != nil && templateTexturePipelineDesc != nil &&
63
templateAATexturePipelineDesc != nil && templateLCDPipelineDesc != nil &&
64
templateAAPipelineDesc != nil)
65
return;
66
67
MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease];
68
vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2;
69
vertDesc.attributes[VertexAttributePosition].offset = 0;
70
vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer;
71
vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex);
72
vertDesc.layouts[MeshVertexBuffer].stepRate = 1;
73
vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
74
75
templateRenderPipelineDesc = [MTLRenderPipelineDescriptor new];
76
templateRenderPipelineDesc.sampleCount = 1;
77
templateRenderPipelineDesc.vertexDescriptor = vertDesc;
78
templateRenderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
79
templateRenderPipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
80
templateRenderPipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
81
templateRenderPipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne;
82
templateRenderPipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
83
templateRenderPipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
84
templateRenderPipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
85
templateRenderPipelineDesc.label = @"template_render";
86
87
templateTexturePipelineDesc = [templateRenderPipelineDesc copy];
88
templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2;
89
templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float);
90
templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer;
91
templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex);
92
templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1;
93
templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
94
templateTexturePipelineDesc.label = @"template_texture";
95
96
templateAATexturePipelineDesc = [templateTexturePipelineDesc copy];
97
templateAATexturePipelineDesc.label = @"template_aa_texture";
98
99
templateLCDPipelineDesc = [MTLRenderPipelineDescriptor new];
100
templateLCDPipelineDesc.sampleCount = 1;
101
templateLCDPipelineDesc.vertexDescriptor = vertDesc;
102
templateLCDPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
103
templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2;
104
templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float);
105
templateLCDPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer;
106
templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex);
107
templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1;
108
templateLCDPipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
109
templateLCDPipelineDesc.label = @"template_lcd";
110
111
vertDesc = [[MTLVertexDescriptor new] autorelease];
112
vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2;
113
vertDesc.attributes[VertexAttributePosition].offset = 0;
114
vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer;
115
vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct AAVertex);
116
vertDesc.layouts[MeshVertexBuffer].stepRate = 1;
117
vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
118
119
templateAAPipelineDesc = [MTLRenderPipelineDescriptor new];
120
templateAAPipelineDesc.sampleCount = 1;
121
templateAAPipelineDesc.vertexDescriptor = vertDesc;
122
templateAAPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
123
templateAAPipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
124
templateAAPipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
125
templateAAPipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne;
126
templateAAPipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
127
templateAAPipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
128
templateAAPipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
129
templateAAPipelineDesc.colorAttachments[0].blendingEnabled = YES;
130
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2;
131
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 2*sizeof(float);
132
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer;
133
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].format = MTLVertexFormatFloat2;
134
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].offset = 4*sizeof(float);
135
templateAAPipelineDesc.vertexDescriptor.attributes[VertexAttributeITexPos].bufferIndex = MeshVertexBuffer;
136
templateAAPipelineDesc.label = @"template_aa";
137
}
138
139
140
@implementation MTLColorPaint {
141
// color-mode
142
jint _color;
143
}
144
- (id)initWithColor:(jint)color {
145
self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR];
146
147
if (self) {
148
_color = color;
149
}
150
return self;
151
}
152
153
- (jint)color {
154
return _color;
155
}
156
157
- (BOOL)isEqual:(MTLColorPaint *)other {
158
if (other == self)
159
return YES;
160
if (!other || ![[other class] isEqual:[self class]])
161
return NO;
162
163
return _color == other->_color;
164
}
165
166
- (NSUInteger)hash {
167
NSUInteger h = [super hash];
168
h = h*31 + _color;
169
return h;
170
}
171
172
- (NSString *)description {
173
return [NSString stringWithFormat:
174
@"[r=%d g=%d b=%d a=%d]",
175
(_color >> 16) & (0xFF),
176
(_color >> 8) & 0xFF,
177
(_color) & 0xFF,
178
(_color >> 24) & 0xFF];
179
}
180
181
- (void)setPipelineState:(id<MTLRenderCommandEncoder>)encoder
182
context:(MTLContext *)mtlc
183
renderOptions:(const RenderOptions *)renderOptions
184
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
185
{
186
initTemplatePipelineDescriptors();
187
188
MTLRenderPipelineDescriptor *rpDesc = nil;
189
190
NSString *vertShader = @"vert_col";
191
NSString *fragShader = @"frag_col";
192
193
if (renderOptions->isTexture) {
194
vertShader = @"vert_txt";
195
fragShader = @"frag_txt";
196
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
197
if (renderOptions->isAA) {
198
fragShader = @"aa_frag_txt";
199
rpDesc = [[templateAATexturePipelineDesc copy] autorelease];
200
}
201
if (renderOptions->isText) {
202
fragShader = @"frag_text";
203
}
204
if (renderOptions->isLCD) {
205
vertShader = @"vert_txt_lcd";
206
fragShader = @"lcd_color";
207
rpDesc = [[templateLCDPipelineDesc copy] autorelease];
208
}
209
setTxtUniforms(mtlc, _color, encoder,
210
renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], &renderOptions->srcFlags,
211
&renderOptions->dstFlags, 1);
212
} else if (renderOptions->isAAShader) {
213
vertShader = @"vert_col_aa";
214
fragShader = @"frag_col_aa";
215
rpDesc = [[templateAAPipelineDesc copy] autorelease];
216
} else {
217
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
218
}
219
220
struct FrameUniforms uf = {RGBA_TO_V4(_color)};
221
[encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
222
223
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
224
vertexShaderId:vertShader
225
fragmentShaderId:fragShader
226
composite:mtlc.composite
227
renderOptions:renderOptions
228
stencilNeeded:[mtlc.clip isShape]];
229
[encoder setRenderPipelineState:pipelineState];
230
}
231
232
- (void)setXorModePipelineState:(id<MTLRenderCommandEncoder>)encoder
233
context:(MTLContext *)mtlc
234
renderOptions:(const RenderOptions *)renderOptions
235
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
236
{
237
initTemplatePipelineDescriptors();
238
NSString * vertShader = @"vert_col_xorMode";
239
NSString * fragShader = @"frag_col_xorMode";
240
MTLRenderPipelineDescriptor * rpDesc = nil;
241
jint xorColor = (jint) [mtlc.composite getXorColor];
242
// Calculate _color ^ xorColor for RGB components
243
// This color gets XORed with destination framebuffer pixel color
244
const int col = _color ^ xorColor;
245
BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();
246
247
if (renderOptions->isTexture) {
248
vertShader = @"vert_txt_xorMode";
249
fragShader = @"frag_txt_xorMode";
250
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
251
252
setTxtUniforms(mtlc, col, encoder,
253
renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha],
254
&renderOptions->srcFlags, &renderOptions->dstFlags, 1);
255
[encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex:0];
256
257
[encoder setFragmentTexture:dstOps->pTexture atIndex:1];
258
} else {
259
struct FrameUniforms uf = {RGBA_TO_V4(col)};
260
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
261
262
[encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
263
[encoder setFragmentTexture:dstOps->pTexture atIndex:0];
264
}
265
266
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
267
vertexShaderId:vertShader
268
fragmentShaderId:fragShader
269
composite:mtlc.composite
270
renderOptions:renderOptions
271
stencilNeeded:[mtlc.clip isShape]];
272
[encoder setRenderPipelineState:pipelineState];
273
}
274
@end
275
276
@implementation MTLBaseGradPaint {
277
jboolean _useMask;
278
@protected
279
jint _cyclic;
280
}
281
282
- (id)initWithState:(jint)state mask:(jboolean)useMask cyclic:(jboolean)cyclic {
283
self = [super initWithState:state];
284
285
if (self) {
286
_useMask = useMask;
287
_cyclic = cyclic;
288
}
289
return self;
290
}
291
292
- (BOOL)isEqual:(MTLBaseGradPaint *)other {
293
if (other == self)
294
return YES;
295
if (!other || ![[other class] isEqual:[self class]])
296
return NO;
297
298
return [super isEqual:self] && _cyclic == other->_cyclic && _useMask == other->_useMask;
299
}
300
301
- (NSUInteger)hash {
302
NSUInteger h = [super hash];
303
h = h*31 + _cyclic;
304
h = h*31 + _useMask;
305
return h;
306
}
307
308
@end
309
310
@implementation MTLGradPaint {
311
jdouble _p0;
312
jdouble _p1;
313
jdouble _p3;
314
jint _pixel1;
315
jint _pixel2;
316
}
317
- (id)initWithUseMask:(jboolean)useMask
318
cyclic:(jboolean)cyclic
319
p0:(jdouble)p0
320
p1:(jdouble)p1
321
p3:(jdouble)p3
322
pixel1:(jint)pixel1
323
pixel2:(jint)pixel2
324
{
325
self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_GRADIENT
326
mask:useMask
327
cyclic:cyclic];
328
329
if (self) {
330
_p0 = p0;
331
_p1 = p1;
332
_p3 = p3;
333
_pixel1 = pixel1;
334
_pixel2 = pixel2;
335
}
336
return self;
337
}
338
339
- (BOOL)isEqual:(MTLGradPaint *)other {
340
if (other == self)
341
return YES;
342
if (!other || ![[other class] isEqual:[self class]])
343
return NO;
344
345
return [super isEqual:self] && _p0 == other->_p0 &&
346
_p1 == other->_p1 && _p3 == other->_p3 &&
347
_pixel1 == other->_pixel1 && _pixel2 == other->_pixel2;
348
}
349
350
- (NSUInteger)hash {
351
NSUInteger h = [super hash];
352
h = h*31 + [@(_p0) hash];
353
h = h*31 + [@(_p1) hash];;
354
h = h*31 + [@(_p3) hash];;
355
h = h*31 + _pixel1;
356
h = h*31 + _pixel2;
357
return h;
358
}
359
- (NSString *)description {
360
return [NSString stringWithFormat:@"gradient"];
361
}
362
363
- (void)setPipelineState:(id)encoder
364
context:(MTLContext *)mtlc
365
renderOptions:(const RenderOptions *)renderOptions
366
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
367
{
368
initTemplatePipelineDescriptors();
369
MTLRenderPipelineDescriptor *rpDesc = nil;
370
371
NSString *vertShader = @"vert_grad";
372
NSString *fragShader = @"frag_grad";
373
374
struct GradFrameUniforms uf = {
375
{_p0, _p1, _p3},
376
RGBA_TO_V4(_pixel1),
377
RGBA_TO_V4(_pixel2),
378
_cyclic,
379
[mtlc.composite getExtraAlpha]
380
};
381
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0];
382
383
if (renderOptions->isTexture) {
384
vertShader = @"vert_txt_grad";
385
fragShader = @"frag_txt_grad";
386
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
387
} else {
388
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
389
}
390
391
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
392
vertexShaderId:vertShader
393
fragmentShaderId:fragShader
394
composite:mtlc.composite
395
renderOptions:renderOptions
396
stencilNeeded:[mtlc.clip isShape]];
397
[encoder setRenderPipelineState:pipelineState];
398
}
399
400
- (void)setXorModePipelineState:(id)encoder
401
context:(MTLContext *)mtlc
402
renderOptions:(const RenderOptions *)renderOptions
403
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
404
{
405
// This block is not reached in current implementation.
406
// Gradient paint XOR mode rendering uses a tile based rendering using a SW pipe (similar to OGL)
407
initTemplatePipelineDescriptors();
408
NSString* vertShader = @"vert_grad_xorMode";
409
NSString* fragShader = @"frag_grad_xorMode";
410
MTLRenderPipelineDescriptor *rpDesc = [[templateRenderPipelineDesc copy] autorelease];
411
jint xorColor = (jint) [mtlc.composite getXorColor];
412
413
struct GradFrameUniforms uf = {
414
{_p0, _p1, _p3},
415
RGBA_TO_V4(_pixel1 ^ xorColor),
416
RGBA_TO_V4(_pixel2 ^ xorColor),
417
_cyclic,
418
[mtlc.composite getExtraAlpha]
419
};
420
421
[encoder setFragmentBytes: &uf length:sizeof(uf) atIndex:0];
422
BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();
423
[encoder setFragmentTexture:dstOps->pTexture atIndex:0];
424
425
J2dTraceLn(J2D_TRACE_INFO, "MTLPaints - setXorModePipelineState -- PAINT_GRADIENT");
426
427
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
428
vertexShaderId:vertShader
429
fragmentShaderId:fragShader
430
composite:mtlc.composite
431
renderOptions:renderOptions
432
stencilNeeded:[mtlc.clip isShape]];
433
[encoder setRenderPipelineState:pipelineState];
434
}
435
436
@end
437
438
@implementation MTLBaseMultiGradPaint {
439
@protected
440
jboolean _linear;
441
jint _numFracts;
442
jfloat _fract[GRAD_MAX_FRACTIONS];
443
jint _pixel[GRAD_MAX_FRACTIONS];
444
}
445
446
- (id)initWithState:(jint)state
447
mask:(jboolean)useMask
448
linear:(jboolean)linear
449
cycleMethod:(jboolean)cycleMethod
450
numStops:(jint)numStops
451
fractions:(jfloat *)fractions
452
pixels:(jint *)pixels
453
{
454
self = [super initWithState:state
455
mask:useMask
456
cyclic:cycleMethod];
457
458
if (self) {
459
_linear = linear;
460
memcpy(_fract, fractions,numStops*sizeof(jfloat));
461
memcpy(_pixel, pixels, numStops*sizeof(jint));
462
_numFracts = numStops;
463
}
464
return self;
465
}
466
467
- (BOOL)isEqual:(MTLBaseMultiGradPaint *)other {
468
if (other == self)
469
return YES;
470
if (!other || ![[other class] isEqual:[self class]])
471
return NO;
472
473
if (_numFracts != other->_numFracts || ![super isEqual:self])
474
return NO;
475
for (int i = 0; i < _numFracts; i++) {
476
if (_fract[i] != other->_fract[i]) return NO;
477
if (_pixel[i] != other->_pixel[i]) return NO;
478
}
479
return YES;
480
}
481
482
- (NSUInteger)hash {
483
NSUInteger h = [super hash];
484
h = h*31 + _numFracts;
485
for (int i = 0; i < _numFracts; i++) {
486
h = h*31 + [@(_fract[i]) hash];
487
h = h*31 + _pixel[i];
488
}
489
return h;
490
}
491
492
@end
493
494
@implementation MTLLinearGradPaint {
495
jdouble _p0;
496
jdouble _p1;
497
jdouble _p3;
498
}
499
- (void)setPipelineState:(id)encoder
500
context:(MTLContext *)mtlc
501
renderOptions:(const RenderOptions *)renderOptions
502
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
503
504
{
505
initTemplatePipelineDescriptors();
506
MTLRenderPipelineDescriptor *rpDesc = nil;
507
508
NSString *vertShader = @"vert_grad";
509
NSString *fragShader = @"frag_lin_grad";
510
511
if (renderOptions->isTexture) {
512
vertShader = @"vert_txt_grad";
513
fragShader = @"frag_txt_lin_grad";
514
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
515
} else {
516
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
517
}
518
519
struct LinGradFrameUniforms uf = {
520
{_p0, _p1, _p3},
521
{},
522
{},
523
_numFracts,
524
_linear,
525
_cyclic,
526
[mtlc.composite getExtraAlpha]
527
};
528
529
memcpy(uf.fract, _fract, _numFracts*sizeof(jfloat));
530
for (int i = 0; i < _numFracts; i++) {
531
vector_float4 v = RGBA_TO_V4(_pixel[i]);
532
uf.color[i] = v;
533
}
534
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0];
535
536
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
537
vertexShaderId:vertShader
538
fragmentShaderId:fragShader
539
composite:mtlc.composite
540
renderOptions:renderOptions
541
stencilNeeded:[mtlc.clip isShape]];
542
[encoder setRenderPipelineState:pipelineState];
543
}
544
545
- (id)initWithUseMask:(jboolean)useMask
546
linear:(jboolean)linear
547
cycleMethod:(jboolean)cycleMethod
548
numStops:(jint)numStops
549
p0:(jfloat)p0
550
p1:(jfloat)p1
551
p3:(jfloat)p3
552
fractions:(jfloat *)fractions
553
pixels:(jint *)pixels
554
{
555
self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_LIN_GRADIENT
556
mask:useMask
557
linear:linear
558
cycleMethod:cycleMethod
559
numStops:numStops
560
fractions:fractions
561
pixels:pixels];
562
563
if (self) {
564
_p0 = p0;
565
_p1 = p1;
566
_p3 = p3;
567
}
568
return self;
569
}
570
571
- (BOOL)isEqual:(MTLLinearGradPaint *)other {
572
if (other == self)
573
return YES;
574
if (!other || ![[other class] isEqual:[self class]] || ![super isEqual:other])
575
return NO;
576
577
return _p0 == other->_p0 && _p1 == other->_p1 && _p3 == other->_p3;
578
}
579
580
- (NSUInteger)hash {
581
NSUInteger h = [super hash];
582
h = h*31 + [@(_p0) hash];
583
h = h*31 + [@(_p1) hash];
584
h = h*31 + [@(_p3) hash];
585
return h;
586
}
587
588
- (NSString *)description {
589
return [NSString stringWithFormat:@"linear_gradient"];
590
}
591
@end
592
593
@implementation MTLRadialGradPaint {
594
jfloat _m00;
595
jfloat _m01;
596
jfloat _m02;
597
jfloat _m10;
598
jfloat _m11;
599
jfloat _m12;
600
jfloat _focusX;
601
}
602
603
- (id)initWithUseMask:(jboolean)useMask
604
linear:(jboolean)linear
605
cycleMethod:(jint)cycleMethod
606
numStops:(jint)numStops
607
m00:(jfloat)m00
608
m01:(jfloat)m01
609
m02:(jfloat)m02
610
m10:(jfloat)m10
611
m11:(jfloat)m11
612
m12:(jfloat)m12
613
focusX:(jfloat)focusX
614
fractions:(void *)fractions
615
pixels:(void *)pixels
616
{
617
self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_RAD_GRADIENT
618
mask:useMask
619
linear:linear
620
cycleMethod:cycleMethod
621
numStops:numStops
622
fractions:fractions
623
pixels:pixels];
624
625
if (self) {
626
_m00 = m00;
627
_m01 = m01;
628
_m02 = m02;
629
_m10 = m10;
630
_m11 = m11;
631
_m12 = m12;
632
_focusX = focusX;
633
}
634
return self;
635
}
636
637
- (BOOL)isEqual:(MTLRadialGradPaint *)other {
638
if (other == self)
639
return YES;
640
if (!other || ![[other class] isEqual:[self class]]
641
|| ![super isEqual:self])
642
return NO;
643
644
return _m00 == other->_m00 && _m01 == other->_m01 && _m02 == other->_m02 &&
645
_m10 == other->_m10 && _m11 == other->_m11 && _m12 == other->_m12 &&
646
_focusX == other->_focusX;
647
}
648
649
- (NSUInteger)hash {
650
NSUInteger h = [super hash];
651
h = h*31 + [@(_m00) hash];
652
h = h*31 + [@(_m01) hash];
653
h = h*31 + [@(_m02) hash];
654
h = h*31 + [@(_m10) hash];
655
h = h*31 + [@(_m11) hash];
656
h = h*31 + [@(_m12) hash];
657
return h;
658
}
659
660
- (NSString *)description {
661
return [NSString stringWithFormat:@"radial_gradient"];
662
}
663
664
- (void)setPipelineState:(id)encoder
665
context:(MTLContext *)mtlc
666
renderOptions:(const RenderOptions *)renderOptions
667
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
668
{
669
initTemplatePipelineDescriptors();
670
MTLRenderPipelineDescriptor *rpDesc = nil;
671
672
NSString *vertShader = @"vert_grad";
673
NSString *fragShader = @"frag_rad_grad";
674
675
if (renderOptions->isTexture) {
676
vertShader = @"vert_txt_grad";
677
fragShader = @"frag_txt_rad_grad";
678
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
679
} else {
680
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
681
}
682
683
struct RadGradFrameUniforms uf = {
684
{},
685
{},
686
_numFracts,
687
_linear,
688
_cyclic,
689
{_m00, _m01, _m02},
690
{_m10, _m11, _m12},
691
{},
692
[mtlc.composite getExtraAlpha]
693
};
694
695
uf.precalc[0] = _focusX;
696
uf.precalc[1] = 1.0 - (_focusX * _focusX);
697
uf.precalc[2] = 1.0 / uf.precalc[1];
698
699
memcpy(uf.fract, _fract, _numFracts*sizeof(jfloat));
700
for (int i = 0; i < _numFracts; i++) {
701
vector_float4 v = RGBA_TO_V4(_pixel[i]);
702
uf.color[i] = v;
703
}
704
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:0];
705
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
706
vertexShaderId:vertShader
707
fragmentShaderId:fragShader
708
composite:mtlc.composite
709
renderOptions:renderOptions
710
stencilNeeded:[mtlc.clip isShape]];
711
[encoder setRenderPipelineState:pipelineState];
712
}
713
714
715
@end
716
717
@implementation MTLTexturePaint {
718
struct AnchorData _anchor;
719
id <MTLTexture> _paintTexture;
720
jboolean _isOpaque;
721
}
722
723
- (id)initWithUseMask:(jboolean)useMask
724
textureID:(id)textureId
725
isOpaque:(jboolean)isOpaque
726
filter:(jboolean)filter
727
xp0:(jdouble)xp0
728
xp1:(jdouble)xp1
729
xp3:(jdouble)xp3
730
yp0:(jdouble)yp0
731
yp1:(jdouble)yp1
732
yp3:(jdouble)yp3
733
{
734
self = [super initWithState:sun_java2d_SunGraphics2D_PAINT_TEXTURE];
735
736
if (self) {
737
_paintTexture = textureId;
738
_anchor.xParams[0] = xp0;
739
_anchor.xParams[1] = xp1;
740
_anchor.xParams[2] = xp3;
741
742
_anchor.yParams[0] = yp0;
743
_anchor.yParams[1] = yp1;
744
_anchor.yParams[2] = yp3;
745
_isOpaque = isOpaque;
746
}
747
return self;
748
749
}
750
751
- (BOOL)isEqual:(MTLTexturePaint *)other {
752
if (other == self)
753
return YES;
754
if (!other || ![[other class] isEqual:[self class]])
755
return NO;
756
757
return [_paintTexture isEqual:other->_paintTexture]
758
&& _anchor.xParams[0] == other->_anchor.xParams[0]
759
&& _anchor.xParams[1] == other->_anchor.xParams[1]
760
&& _anchor.xParams[2] == other->_anchor.xParams[2]
761
&& _anchor.yParams[0] == other->_anchor.yParams[0]
762
&& _anchor.yParams[1] == other->_anchor.yParams[1]
763
&& _anchor.yParams[2] == other->_anchor.yParams[2];
764
}
765
766
- (NSString *)description {
767
return [NSString stringWithFormat:@"texture_paint"];
768
}
769
770
- (void)setPipelineState:(id)encoder
771
context:(MTLContext *)mtlc
772
renderOptions:(const RenderOptions *)renderOptions
773
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
774
{
775
initTemplatePipelineDescriptors();
776
MTLRenderPipelineDescriptor *rpDesc = nil;
777
778
NSString* vertShader = @"vert_tp";
779
NSString* fragShader = @"frag_tp";
780
781
[encoder setVertexBytes:&_anchor length:sizeof(_anchor) atIndex:FrameUniformBuffer];
782
783
if (renderOptions->isTexture) {
784
vertShader = @"vert_txt_tp";
785
fragShader = @"frag_txt_tp";
786
rpDesc = [[templateTexturePipelineDesc copy] autorelease];
787
[encoder setFragmentTexture:_paintTexture atIndex:1];
788
} else {
789
rpDesc = [[templateRenderPipelineDesc copy] autorelease];
790
[encoder setFragmentTexture:_paintTexture atIndex:0];
791
}
792
const SurfaceRasterFlags srcFlags = {_isOpaque, renderOptions->srcFlags.isPremultiplied};
793
setTxtUniforms(mtlc, 0, encoder,
794
renderOptions->interpolation, YES, [mtlc.composite getExtraAlpha],
795
&srcFlags, &renderOptions->dstFlags, 0);
796
797
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
798
vertexShaderId:vertShader
799
fragmentShaderId:fragShader
800
composite:mtlc.composite
801
renderOptions:renderOptions
802
stencilNeeded:[mtlc.clip isShape]];
803
[encoder setRenderPipelineState:pipelineState];
804
}
805
806
- (void)setXorModePipelineState:(id)encoder
807
context:(MTLContext *)mtlc
808
renderOptions:(const RenderOptions *)renderOptions
809
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
810
{
811
initTemplatePipelineDescriptors();
812
// This block is not reached in current implementation.
813
// Texture paint XOR mode rendering uses a tile based rendering using a SW pipe (similar to OGL)
814
NSString* vertShader = @"vert_tp_xorMode";
815
NSString* fragShader = @"frag_tp_xorMode";
816
MTLRenderPipelineDescriptor *rpDesc = [[templateRenderPipelineDesc copy] autorelease];
817
jint xorColor = (jint) [mtlc.composite getXorColor];
818
819
[encoder setVertexBytes:&_anchor length:sizeof(_anchor) atIndex:FrameUniformBuffer];
820
[encoder setFragmentTexture:_paintTexture atIndex: 0];
821
BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();
822
[encoder setFragmentTexture:dstOps->pTexture atIndex:1];
823
[encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex: 0];
824
825
J2dTraceLn(J2D_TRACE_INFO, "MTLPaints - setXorModePipelineState -- PAINT_TEXTURE");
826
827
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
828
vertexShaderId:vertShader
829
fragmentShaderId:fragShader
830
composite:mtlc.composite
831
renderOptions:renderOptions
832
stencilNeeded:[mtlc.clip isShape]];
833
[encoder setRenderPipelineState:pipelineState];
834
}
835
836
@end
837
838
@implementation MTLPaint {
839
jint _paintState;
840
}
841
842
- (instancetype)init {
843
self = [super init];
844
if (self) {
845
_paintState = sun_java2d_SunGraphics2D_PAINT_UNDEFINED;
846
}
847
848
return self;
849
}
850
851
- (instancetype)initWithState:(jint)state {
852
self = [super init];
853
if (self) {
854
_paintState = state;
855
}
856
return self;
857
}
858
859
- (BOOL)isEqual:(MTLPaint *)other {
860
if (other == self)
861
return YES;
862
if (!other || ![other isKindOfClass:[self class]])
863
return NO;
864
return _paintState == other->_paintState;
865
}
866
867
- (NSUInteger)hash {
868
return _paintState;
869
}
870
871
- (NSString *)description {
872
return @"unknown-paint";
873
}
874
875
static void
876
setTxtUniforms(MTLContext *mtlc, int color, id <MTLRenderCommandEncoder> encoder, int interpolation, bool repeat,
877
jfloat extraAlpha, const SurfaceRasterFlags *srcFlags, const SurfaceRasterFlags *dstFlags, int mode) {
878
struct TxtFrameUniforms uf = {RGBA_TO_V4(color), mode, srcFlags->isOpaque, dstFlags->isOpaque, extraAlpha};
879
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
880
[mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:interpolation repeat:repeat];
881
}
882
883
// For the current paint mode:
884
// 1. Selects vertex+fragment shaders (and corresponding pipelineDesc) and set pipelineState
885
// 2. Set vertex and fragment buffers
886
// Base implementation is used in drawTex2Tex
887
- (void)setPipelineState:(id <MTLRenderCommandEncoder>)encoder
888
context:(MTLContext *)mtlc
889
renderOptions:(const RenderOptions *)renderOptions
890
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
891
{
892
initTemplatePipelineDescriptors();
893
// Called from drawTex2Tex used in flushBuffer and for buffered image ops
894
if (renderOptions->isTexture) {
895
NSString * vertShader = @"vert_txt";
896
NSString * fragShader = @"frag_txt";
897
MTLRenderPipelineDescriptor* rpDesc = [[templateTexturePipelineDesc copy] autorelease];
898
899
NSObject *bufImgOp = [mtlc getBufImgOp];
900
if (bufImgOp != nil) {
901
if ([bufImgOp isKindOfClass:[MTLRescaleOp class]]) {
902
MTLRescaleOp *rescaleOp = bufImgOp;
903
fragShader = @"frag_txt_op_rescale";
904
905
struct TxtFrameOpRescaleUniforms uf = {
906
RGBA_TO_V4(0), [mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque,
907
rescaleOp.isNonPremult,
908
FLOAT_ARR_TO_V4([rescaleOp getScaleFactors]), FLOAT_ARR_TO_V4([rescaleOp getOffsets])
909
};
910
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
911
[mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO];
912
} else if ([bufImgOp isKindOfClass:[MTLConvolveOp class]]) {
913
MTLConvolveOp *convolveOp = bufImgOp;
914
fragShader = @"frag_txt_op_convolve";
915
916
struct TxtFrameOpConvolveUniforms uf = {
917
[mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque,
918
FLOAT_ARR_TO_V4([convolveOp getImgEdge]),
919
convolveOp.kernelSize, convolveOp.isEdgeZeroFill,
920
};
921
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
922
[mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO];
923
924
[encoder setFragmentBuffer:[convolveOp getBuffer] offset:0 atIndex:2];
925
} else if ([bufImgOp isKindOfClass:[MTLLookupOp class]]) {
926
MTLLookupOp *lookupOp = bufImgOp;
927
fragShader = @"frag_txt_op_lookup";
928
929
struct TxtFrameOpLookupUniforms uf = {
930
[mtlc.composite getExtraAlpha], renderOptions->srcFlags.isOpaque,
931
FLOAT_ARR_TO_V4([lookupOp getOffset]), lookupOp.isUseSrcAlpha, lookupOp.isNonPremult,
932
};
933
[encoder setFragmentBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
934
[mtlc.samplerManager setSamplerWithEncoder:encoder interpolation:renderOptions->interpolation repeat:NO];
935
[encoder setFragmentTexture:[lookupOp getLookupTexture] atIndex:1];
936
}
937
} else {
938
setTxtUniforms(mtlc, 0, encoder,
939
renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha],
940
&renderOptions->srcFlags,
941
&renderOptions->dstFlags, 0);
942
943
}
944
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
945
vertexShaderId:vertShader
946
fragmentShaderId:fragShader
947
composite:mtlc.composite
948
renderOptions:renderOptions
949
stencilNeeded:[mtlc.clip isShape]];
950
[encoder setRenderPipelineState:pipelineState];
951
}
952
}
953
954
// For the current paint mode:
955
// 1. Selects vertex+fragment shaders (and corresponding pipelineDesc) and set pipelineState
956
// 2. Set vertex and fragment buffers
957
- (void)setXorModePipelineState:(id <MTLRenderCommandEncoder>)encoder
958
context:(MTLContext *)mtlc
959
renderOptions:(const RenderOptions *)renderOptions
960
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
961
{
962
initTemplatePipelineDescriptors();
963
if (renderOptions->isTexture) {
964
jint xorColor = (jint) [mtlc.composite getXorColor];
965
NSString * vertShader = @"vert_txt_xorMode";
966
NSString * fragShader = @"frag_txt_xorMode";
967
MTLRenderPipelineDescriptor * rpDesc = [[templateTexturePipelineDesc copy] autorelease];
968
969
const int col = 0 ^ xorColor;
970
setTxtUniforms(mtlc, col, encoder,
971
renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha],
972
&renderOptions->srcFlags, &renderOptions->dstFlags, 0);
973
[encoder setFragmentBytes:&xorColor length:sizeof(xorColor) atIndex: 0];
974
975
BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();
976
[encoder setFragmentTexture:dstOps->pTexture atIndex:1];
977
978
setTxtUniforms(mtlc, 0, encoder,
979
renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha],
980
&renderOptions->srcFlags,
981
&renderOptions->dstFlags, 0);
982
983
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:rpDesc
984
vertexShaderId:vertShader
985
fragmentShaderId:fragShader
986
composite:mtlc.composite
987
renderOptions:renderOptions
988
stencilNeeded:[mtlc.clip isShape]];
989
[encoder setRenderPipelineState:pipelineState];
990
}
991
}
992
993
@end
994
995