< prev index next >

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

Print this page

 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;
< prev index next >