23 - (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
24 paint:(MTLPaint *)paint
25 composite:(MTLComposite *)composite
26 isTexture:(jboolean)isTexture
27 isAA:(jboolean)isAA
28 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
29 clip:(MTLClip *)clip
30 transform:(MTLTransform *)transform
31 forceUpdate:(jboolean)forceUpdate;
32 @property jboolean aa;
33 @end
34
35 @implementation EncoderStates {
36 MTLPipelineStatesStorage * _pipelineStateStorage;
37 id<MTLDevice> _device;
38
39 // Persistent encoder properties
40 id<MTLTexture> _destination;
41 SurfaceRasterFlags _dstFlags;
42
43 //
44 // Cached 'mutable' states of encoder
45 //
46
47 // Composite rule and source raster flags (it affects the CAD-multipliers (of pipelineState))
48 MTLComposite * _composite;
49 SurfaceRasterFlags _srcFlags;
50
51 // Paint mode (it affects shaders (of pipelineState) and corresponding buffers)
52 MTLPaint * _paint;
53
54 // If true, indicates that encoder is used for texture drawing (user must do [encoder setFragmentTexture:] before drawing)
55 jboolean _isTexture;
56 jboolean _isAA;
57
58 // Clip rect or stencil
59 MTLClip * _clip;
60
61 // Transform (affects transformation inside vertex shader)
62 MTLTransform * _transform;
63 }
64 @synthesize aa = _isAA;
65
66 - (id)init {
67 self = [super init];
68 if (self) {
69 _destination = nil;
70 _composite = [[MTLComposite alloc] init];
71 _paint = [[MTLPaint alloc] init];
72 _transform = [[MTLTransform alloc] init];
73 _clip = [[MTLClip alloc] init];
74 }
75 return self;
76 }
85 - (void)setContext:(MTLContext * _Nonnull)mtlc {
86 self->_pipelineStateStorage = mtlc.pipelineStateStorage;
87 self->_device = mtlc.device;
88 }
89
90 - (void)reset:(id<MTLTexture>)destination
91 isDstOpaque:(jboolean)isDstOpaque
92 isDstPremultiplied:(jboolean)isDstPremultiplied
93 isAA:(jboolean)isAA {
94 _destination = destination;
95 _dstFlags.isOpaque = isDstOpaque;
96 _dstFlags.isPremultiplied = isDstPremultiplied;
97 _isAA = isAA;
98 // NOTE: probably it's better to invalidate/reset all cached states now
99 }
100
101 - (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
102 paint:(MTLPaint *)paint
103 composite:(MTLComposite *)composite
104 isTexture:(jboolean)isTexture
105 isAA:(jboolean)isAA
106 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
107 clip:(MTLClip *)clip
108 transform:(MTLTransform *)transform
109 forceUpdate:(jboolean)forceUpdate
110 {
111 // 1. Process special case for stencil mask generation
112 if (clip.stencilMaskGenerationInProgress == JNI_TRUE) {
113 // use separate pipeline state for stencil generation
114 if (forceUpdate || (_clip.stencilMaskGenerationInProgress != JNI_TRUE)) {
115 [_clip copyFrom:clip];
116 [_clip setMaskGenerationPipelineState:encoder
117 destWidth:_destination.width
118 destHeight:_destination.height
119 pipelineStateStorage:_pipelineStateStorage];
120 }
121
122 [self updateTransform:encoder transform:transform forceUpdate:forceUpdate];
123 return;
124 }
125
126 // 2. Otherwise update all 'mutable' properties of encoder
127 [self updatePipelineState:encoder
128 paint:paint
129 composite:composite
130 isStencilUsed:[clip isShape]
131 isTexture:isTexture
132 isAA:isAA
133 srcFlags:srcFlags
134 forceUpdate:forceUpdate];
135 [self updateTransform:encoder transform:transform forceUpdate:forceUpdate];
136 [self updateClip:encoder clip:clip forceUpdate:forceUpdate];
137 }
138
139 //
140 // Internal methods that update states when necessary (compare with cached states)
141 //
142
143 // Updates pipelineState (and corresponding buffers) with use of paint+composite+flags
144 - (void)updatePipelineState:(id<MTLRenderCommandEncoder>)encoder
145 paint:(MTLPaint *)paint
146 composite:(MTLComposite *)composite
147 isStencilUsed:(jboolean)isStencilUsed
148 isTexture:(jboolean)isTexture
149 isAA:(jboolean)isAA
150 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
151 forceUpdate:(jboolean)forceUpdate
152 {
153 if (srcFlags == NULL)
154 srcFlags = &defaultRasterFlags;
155
156 if (!forceUpdate
157 && [_paint isEqual:paint]
158 && [_composite isEqual:composite]
159 && _isTexture == isTexture
160 && _isAA == isAA
161 && _srcFlags.isOpaque == srcFlags->isOpaque && _srcFlags.isPremultiplied == srcFlags->isPremultiplied)
162 return;
163
164 [_paint copyFrom:paint];
165 [_composite copyFrom:composite];
166 _isTexture = isTexture;
167 _isAA = isAA;
168 _srcFlags = *srcFlags;
169
170 if ((jint)[composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR) {
171 [paint setXorModePipelineState:encoder
172 composite:_composite
173 isStencilUsed:isStencilUsed
174 isTexture:_isTexture
175 srcFlags:&_srcFlags
176 dstFlags:&_dstFlags
177 pipelineStateStorage:_pipelineStateStorage];
178 } else {
179 [paint setPipelineState:encoder
180 composite:_composite
181 isStencilUsed:isStencilUsed
182 isTexture:_isTexture
183 isAA:isAA
184 srcFlags:&_srcFlags
185 dstFlags:&_dstFlags
186 pipelineStateStorage:_pipelineStateStorage];
187 }
188 }
189
190 - (void) updateClip:(id<MTLRenderCommandEncoder>)encoder clip:(MTLClip *)clip forceUpdate:(jboolean)forceUpdate
191 {
192 if (clip.stencilMaskGenerationInProgress == JNI_TRUE) {
193 // don't set setScissorOrStencil when generateion in progress
194 return;
195 }
196
197 if (!forceUpdate && [_clip isEqual:clip])
198 return;
199
200 [_clip copyFrom:clip];
201 [_clip setScissorOrStencil:encoder
202 destWidth:_destination.width
250 - (void)dealloc {
251 [_encoderStates release];
252 [super dealloc];
253 }
254
255 - (void)setContext:(MTLContex * _Nonnull)mtlc {
256 self->_mtlc = mtlc;
257 [self->_encoderStates setContext:mtlc];
258 }
259
260 - (id<MTLRenderCommandEncoder> _Nonnull) getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps
261 {
262 return [self getRenderEncoder:dstOps->pTexture isDstOpaque:dstOps->isOpaque];
263 }
264
265 - (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps {
266 id<MTLTexture> dstTxt = dstOps->pTexture;
267 return [self getEncoder:dstTxt
268 isOpaque:dstOps->isOpaque
269 isTexture:JNI_FALSE
270 isAA:JNI_TRUE
271 srcFlags:NULL];
272 }
273
274 - (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest
275 isDstOpaque:(bool)isOpaque
276 {
277 return [self getEncoder:dest
278 isOpaque:isOpaque
279 isTexture:JNI_FALSE
280 isAA:JNI_FALSE
281 srcFlags:NULL];
282 }
283
284 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps
285 isSrcOpaque:(bool)isSrcOpaque
286 {
287 return [self getTextureEncoder:dstOps->pTexture isSrcOpaque:isSrcOpaque isDstOpaque:dstOps->isOpaque];
288 }
289
290 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
291 isSrcOpaque:(bool)isSrcOpaque
292 isDstOpaque:(bool)isDstOpaque
293 isAA:(jboolean)isAA
294 {
295 SurfaceRasterFlags srcFlags = { isSrcOpaque, JNI_TRUE };
296 return [self getEncoder:dest
297 isOpaque:isDstOpaque
298 isTexture:JNI_TRUE
299 isAA:isAA
300 srcFlags:&srcFlags];
301 }
302
303 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
304 isSrcOpaque:(bool)isSrcOpaque
305 isDstOpaque:(bool)isDstOpaque
306 {
307 return [self getTextureEncoder:dest isSrcOpaque:isSrcOpaque isDstOpaque:isDstOpaque isAA:JNI_FALSE];
308 }
309
310 - (id<MTLRenderCommandEncoder> _Nonnull)
311 getEncoder:(id<MTLTexture> _Nonnull)dest
312 isOpaque:(jboolean)isOpaque
313 isTexture:(jboolean)isTexture
314 isAA:(jboolean)isAA
315 srcFlags:(const SurfaceRasterFlags *_Nullable)srcFlags {
316 //
317 // 1. check whether it's necessary to call endEncoder
318 //
319 jboolean needEnd = JNI_FALSE;
320 if (_encoder != nil) {
321 if (_destination != dest || isAA != _encoderStates.aa) {
322 J2dTraceLn2(J2D_TRACE_VERBOSE,
323 "end common encoder because of dest change: %p -> %p",
324 _destination, dest);
325 needEnd = JNI_TRUE;
326 } else if ((_useStencil == NO) != ([_mtlc.clip isShape] == NO)) {
327 // 1. When mode changes RECT -> SHAPE we must recreate encoder with
328 // stencilAttachment (todo: consider the case when current encoder already
329 // has stencil)
330 //
331 // 2. When mode changes SHAPE -> RECT it seems that we can use the same
332 // encoder with disabled stencil test, but [encoder
333 // setDepthStencilState:nil] causes crash, so we have to recreate encoder
392 }
393
394 // J2dTraceLn1(J2D_TRACE_VERBOSE, "created render encoder to draw on
395 // tex=%p", dest);
396 _encoder = [[cbw getCommandBuffer] renderCommandEncoderWithDescriptor:rpd];
397 [rpd release];
398
399 [_encoderStates reset:dest
400 isDstOpaque:isOpaque
401 isDstPremultiplied:YES
402 isAA:isAA];
403 }
404
405 //
406 // 3. update encoder states
407 //
408 [_encoderStates updateEncoder:_encoder
409 paint:_mtlc.paint
410 composite:_mtlc.composite
411 isTexture:isTexture
412 isAA:isAA
413 srcFlags:srcFlags
414 clip:_mtlc.clip
415 transform:_mtlc.transform
416 forceUpdate:forceUpdate];
417
418 return _encoder;
419 }
420
421 - (id<MTLBlitCommandEncoder> _Nonnull) createBlitEncoder {
422 [self endEncoder];
423 return [[[_mtlc getCommandBufferWrapper] getCommandBuffer] blitCommandEncoder];
424 }
425
426 - (void) endEncoder {
427 if (_encoder != nil) {
428 [_encoder endEncoding];
429 [_encoder release];
430 _encoder = nil;
431 if (_aaDestination != nil) {
432 id<MTLTexture> aaDest = _aaDestination;
433 _aaDestination = nil;
434 NSUInteger _w = _destination.width;
435 NSUInteger _h = _destination.height;
436 _encoder = [self getTextureEncoder:_destination
437 isSrcOpaque:JNI_FALSE
438 isDstOpaque:JNI_TRUE
439 isAA:JNI_TRUE];
440
441 struct TxtVertex quadTxVerticesBuffer[] = {
442 {{0, 0}, {0, 0}},
443 {{0,_h}, {0, 1}},
444 {{_w, 0},{1, 0}},
445 {{0, _h},{0, 1}},
446 {{_w, _h}, {1, 1}},
447 {{_w, 0}, {1, 0}}
448 };
449
450 [_encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer];
451 [_encoder setFragmentTexture:aaDest atIndex: 0];
452 [_encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
453 [_encoder endEncoding];
454 [_encoder release];
455 }
456
457 _encoder = nil;
458 _destination = nil;
|
23 - (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
24 paint:(MTLPaint *)paint
25 composite:(MTLComposite *)composite
26 isTexture:(jboolean)isTexture
27 isAA:(jboolean)isAA
28 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
29 clip:(MTLClip *)clip
30 transform:(MTLTransform *)transform
31 forceUpdate:(jboolean)forceUpdate;
32 @property jboolean aa;
33 @end
34
35 @implementation EncoderStates {
36 MTLPipelineStatesStorage * _pipelineStateStorage;
37 id<MTLDevice> _device;
38
39 // Persistent encoder properties
40 id<MTLTexture> _destination;
41 SurfaceRasterFlags _dstFlags;
42
43 jboolean _isAA;
44
45 //
46 // Cached 'mutable' states of encoder
47 //
48
49 // Composite rule and source raster flags (it affects the CAD-multipliers (of pipelineState))
50 MTLComposite * _composite;
51 SurfaceRasterFlags _srcFlags;
52
53 // Paint mode (it affects shaders (of pipelineState) and corresponding buffers)
54 MTLPaint * _paint;
55
56 // If true, indicates that encoder is used for texture drawing (user must do [encoder setFragmentTexture:] before drawing)
57 jboolean _isTexture;
58 int _interpolationMode;
59
60 // Clip rect or stencil
61 MTLClip * _clip;
62
63 // Transform (affects transformation inside vertex shader)
64 MTLTransform * _transform;
65 }
66 @synthesize aa = _isAA;
67
68 - (id)init {
69 self = [super init];
70 if (self) {
71 _destination = nil;
72 _composite = [[MTLComposite alloc] init];
73 _paint = [[MTLPaint alloc] init];
74 _transform = [[MTLTransform alloc] init];
75 _clip = [[MTLClip alloc] init];
76 }
77 return self;
78 }
87 - (void)setContext:(MTLContext * _Nonnull)mtlc {
88 self->_pipelineStateStorage = mtlc.pipelineStateStorage;
89 self->_device = mtlc.device;
90 }
91
92 - (void)reset:(id<MTLTexture>)destination
93 isDstOpaque:(jboolean)isDstOpaque
94 isDstPremultiplied:(jboolean)isDstPremultiplied
95 isAA:(jboolean)isAA {
96 _destination = destination;
97 _dstFlags.isOpaque = isDstOpaque;
98 _dstFlags.isPremultiplied = isDstPremultiplied;
99 _isAA = isAA;
100 // NOTE: probably it's better to invalidate/reset all cached states now
101 }
102
103 - (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
104 paint:(MTLPaint *)paint
105 composite:(MTLComposite *)composite
106 isTexture:(jboolean)isTexture
107 interpolation:(int)interpolation
108 isAA:(jboolean)isAA
109 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
110 clip:(MTLClip *)clip
111 transform:(MTLTransform *)transform
112 forceUpdate:(jboolean)forceUpdate
113 {
114 // 1. Process special case for stencil mask generation
115 if (clip.stencilMaskGenerationInProgress == JNI_TRUE) {
116 // use separate pipeline state for stencil generation
117 if (forceUpdate || (_clip.stencilMaskGenerationInProgress != JNI_TRUE)) {
118 [_clip copyFrom:clip];
119 [_clip setMaskGenerationPipelineState:encoder
120 destWidth:_destination.width
121 destHeight:_destination.height
122 pipelineStateStorage:_pipelineStateStorage];
123 }
124
125 [self updateTransform:encoder transform:transform forceUpdate:forceUpdate];
126 return;
127 }
128
129 // 2. Otherwise update all 'mutable' properties of encoder
130 [self updatePipelineState:encoder
131 paint:paint
132 composite:composite
133 isStencilUsed:[clip isShape]
134 isTexture:isTexture
135 interpolation:interpolation
136 isAA:isAA
137 srcFlags:srcFlags
138 forceUpdate:forceUpdate];
139 [self updateTransform:encoder transform:transform forceUpdate:forceUpdate];
140 [self updateClip:encoder clip:clip forceUpdate:forceUpdate];
141 }
142
143 //
144 // Internal methods that update states when necessary (compare with cached states)
145 //
146
147 // Updates pipelineState (and corresponding buffers) with use of paint+composite+flags
148 - (void)updatePipelineState:(id<MTLRenderCommandEncoder>)encoder
149 paint:(MTLPaint *)paint
150 composite:(MTLComposite *)composite
151 isStencilUsed:(jboolean)isStencilUsed
152 isTexture:(jboolean)isTexture
153 interpolation:(int)interpolation
154 isAA:(jboolean)isAA
155 srcFlags:(const SurfaceRasterFlags * _Nullable)srcFlags
156 forceUpdate:(jboolean)forceUpdate
157 {
158 if (srcFlags == NULL)
159 srcFlags = &defaultRasterFlags;
160
161 if (!forceUpdate
162 && [_paint isEqual:paint]
163 && [_composite isEqual:composite]
164 && (_isTexture == isTexture && (!isTexture || _interpolationMode == interpolation)) // interpolation is used only in texture mode
165 && _isAA == isAA
166 && _srcFlags.isOpaque == srcFlags->isOpaque && _srcFlags.isPremultiplied == srcFlags->isPremultiplied)
167 return;
168
169 [_paint copyFrom:paint];
170 [_composite copyFrom:composite];
171 _isTexture = isTexture;
172 _interpolationMode = interpolation;
173 _isAA = isAA;
174 _srcFlags = *srcFlags;
175
176 if ((jint)[composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR) {
177 [paint setXorModePipelineState:encoder
178 composite:_composite
179 isStencilUsed:isStencilUsed
180 isTexture:_isTexture
181 interpolation:interpolation
182 srcFlags:&_srcFlags
183 dstFlags:&_dstFlags
184 pipelineStateStorage:_pipelineStateStorage];
185 } else {
186 [paint setPipelineState:encoder
187 composite:_composite
188 isStencilUsed:isStencilUsed
189 isTexture:_isTexture
190 interpolation:interpolation
191 isAA:isAA
192 srcFlags:&_srcFlags
193 dstFlags:&_dstFlags
194 pipelineStateStorage:_pipelineStateStorage];
195 }
196 }
197
198 - (void) updateClip:(id<MTLRenderCommandEncoder>)encoder clip:(MTLClip *)clip forceUpdate:(jboolean)forceUpdate
199 {
200 if (clip.stencilMaskGenerationInProgress == JNI_TRUE) {
201 // don't set setScissorOrStencil when generateion in progress
202 return;
203 }
204
205 if (!forceUpdate && [_clip isEqual:clip])
206 return;
207
208 [_clip copyFrom:clip];
209 [_clip setScissorOrStencil:encoder
210 destWidth:_destination.width
258 - (void)dealloc {
259 [_encoderStates release];
260 [super dealloc];
261 }
262
263 - (void)setContext:(MTLContex * _Nonnull)mtlc {
264 self->_mtlc = mtlc;
265 [self->_encoderStates setContext:mtlc];
266 }
267
268 - (id<MTLRenderCommandEncoder> _Nonnull) getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps
269 {
270 return [self getRenderEncoder:dstOps->pTexture isDstOpaque:dstOps->isOpaque];
271 }
272
273 - (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps {
274 id<MTLTexture> dstTxt = dstOps->pTexture;
275 return [self getEncoder:dstTxt
276 isOpaque:dstOps->isOpaque
277 isTexture:JNI_FALSE
278 interpolation:INTERPOLATION_NEAREST_NEIGHBOR
279 isAA:JNI_TRUE
280 srcFlags:NULL];
281 }
282
283 - (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest
284 isDstOpaque:(bool)isOpaque
285 {
286 return [self getEncoder:dest
287 isOpaque:isOpaque
288 isTexture:JNI_FALSE
289 interpolation:INTERPOLATION_NEAREST_NEIGHBOR
290 isAA:JNI_FALSE
291 srcFlags:NULL];
292 }
293
294 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps
295 isSrcOpaque:(bool)isSrcOpaque
296 {
297 return [self getTextureEncoder:dstOps->pTexture
298 isSrcOpaque:isSrcOpaque
299 isDstOpaque:dstOps->isOpaque
300 interpolation:INTERPOLATION_NEAREST_NEIGHBOR];
301 }
302
303 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
304 isSrcOpaque:(bool)isSrcOpaque
305 isDstOpaque:(bool)isDstOpaque
306 {
307 return [self getTextureEncoder:dest
308 isSrcOpaque:isSrcOpaque
309 isDstOpaque:isDstOpaque
310 interpolation:INTERPOLATION_NEAREST_NEIGHBOR
311 isAA:JNI_FALSE];
312 }
313
314 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
315 isSrcOpaque:(bool)isSrcOpaque
316 isDstOpaque:(bool)isDstOpaque
317 interpolation:(int)interpolation
318 isAA:(jboolean)isAA
319 {
320 SurfaceRasterFlags srcFlags = { isSrcOpaque, JNI_TRUE };
321 return [self getEncoder:dest
322 isOpaque:isDstOpaque
323 isTexture:JNI_TRUE
324 interpolation:interpolation
325 isAA:isAA
326 srcFlags:&srcFlags];
327 }
328
329 - (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
330 isSrcOpaque:(bool)isSrcOpaque
331 isDstOpaque:(bool)isDstOpaque
332 interpolation:(int)interpolation
333 {
334 return [self getTextureEncoder:dest isSrcOpaque:isSrcOpaque isDstOpaque:isDstOpaque interpolation:interpolation isAA:JNI_FALSE];
335 }
336
337 - (id<MTLRenderCommandEncoder> _Nonnull)
338 getEncoder:(id<MTLTexture> _Nonnull)dest
339 isOpaque:(jboolean)isOpaque
340 isTexture:(jboolean)isTexture
341 interpolation:(int)interpolation
342 isAA:(jboolean)isAA
343 srcFlags:(const SurfaceRasterFlags *_Nullable)srcFlags {
344 //
345 // 1. check whether it's necessary to call endEncoder
346 //
347 jboolean needEnd = JNI_FALSE;
348 if (_encoder != nil) {
349 if (_destination != dest || isAA != _encoderStates.aa) {
350 J2dTraceLn2(J2D_TRACE_VERBOSE,
351 "end common encoder because of dest change: %p -> %p",
352 _destination, dest);
353 needEnd = JNI_TRUE;
354 } else if ((_useStencil == NO) != ([_mtlc.clip isShape] == NO)) {
355 // 1. When mode changes RECT -> SHAPE we must recreate encoder with
356 // stencilAttachment (todo: consider the case when current encoder already
357 // has stencil)
358 //
359 // 2. When mode changes SHAPE -> RECT it seems that we can use the same
360 // encoder with disabled stencil test, but [encoder
361 // setDepthStencilState:nil] causes crash, so we have to recreate encoder
420 }
421
422 // J2dTraceLn1(J2D_TRACE_VERBOSE, "created render encoder to draw on
423 // tex=%p", dest);
424 _encoder = [[cbw getCommandBuffer] renderCommandEncoderWithDescriptor:rpd];
425 [rpd release];
426
427 [_encoderStates reset:dest
428 isDstOpaque:isOpaque
429 isDstPremultiplied:YES
430 isAA:isAA];
431 }
432
433 //
434 // 3. update encoder states
435 //
436 [_encoderStates updateEncoder:_encoder
437 paint:_mtlc.paint
438 composite:_mtlc.composite
439 isTexture:isTexture
440 interpolation:interpolation
441 isAA:isAA
442 srcFlags:srcFlags
443 clip:_mtlc.clip
444 transform:_mtlc.transform
445 forceUpdate:forceUpdate];
446
447 return _encoder;
448 }
449
450 - (id<MTLBlitCommandEncoder> _Nonnull) createBlitEncoder {
451 [self endEncoder];
452 return [[[_mtlc getCommandBufferWrapper] getCommandBuffer] blitCommandEncoder];
453 }
454
455 - (void) endEncoder {
456 if (_encoder != nil) {
457 [_encoder endEncoding];
458 [_encoder release];
459 _encoder = nil;
460 if (_aaDestination != nil) {
461 id<MTLTexture> aaDest = _aaDestination;
462 _aaDestination = nil;
463 NSUInteger _w = _destination.width;
464 NSUInteger _h = _destination.height;
465 _encoder = [self getTextureEncoder:_destination
466 isSrcOpaque:JNI_FALSE
467 isDstOpaque:JNI_TRUE
468 interpolation:INTERPOLATION_NEAREST_NEIGHBOR
469 isAA:JNI_TRUE];
470
471 struct TxtVertex quadTxVerticesBuffer[] = {
472 {{0, 0}, {0, 0}},
473 {{0,_h}, {0, 1}},
474 {{_w, 0},{1, 0}},
475 {{0, _h},{0, 1}},
476 {{_w, _h}, {1, 1}},
477 {{_w, 0}, {1, 0}}
478 };
479
480 [_encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer];
481 [_encoder setFragmentTexture:aaDest atIndex: 0];
482 [_encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
483 [_encoder endEncoding];
484 [_encoder release];
485 }
486
487 _encoder = nil;
488 _destination = nil;
|