@@ -37,6 +37,7 @@ @interface CWebViewPlugin : NSObject<WKUIDelegate, WKNavigationDelegate, WKScrip
37
37
WKWebView *webView;
38
38
NSString *gameObject;
39
39
NSBitmapImageRep *bitmap;
40
+ NSBitmapImageRep *bitmaps[2 ];
40
41
BOOL needsDisplay;
41
42
NSMutableDictionary *customRequestHeader;
42
43
NSMutableArray *messages;
@@ -217,6 +218,8 @@ - (void)dispose
217
218
[window close ];
218
219
}
219
220
gameObject = nil ;
221
+ bitmaps[1 ] = nil ;
222
+ bitmaps[0 ] = nil ;
220
223
bitmap = nil ;
221
224
window = nil ;
222
225
windowController = nil ;
@@ -417,17 +420,15 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
417
420
418
421
- (void )addMessage : (NSString *)msg
419
422
{
420
- @synchronized (messages)
421
- {
423
+ @synchronized (messages) {
422
424
[messages addObject: msg];
423
425
}
424
426
}
425
427
426
428
- (NSString *)getMessage
427
429
{
428
430
NSString *ret = nil ;
429
- @synchronized (messages)
430
- {
431
+ @synchronized (messages) {
431
432
if ([messages count ] > 0 ) {
432
433
ret = [messages[0 ] copy ];
433
434
[messages removeObjectAtIndex: 0 ];
@@ -446,9 +447,9 @@ - (void)setRect:(int)width height:(int)height
446
447
frame.origin .x = 0 ;
447
448
frame.origin .y = 0 ;
448
449
webView.frame = frame;
449
- if (bitmap ! = nil ) {
450
- bitmap = nil ;
451
- }
450
+ bitmaps[ 1 ] = nil ;
451
+ bitmaps[ 0 ] = nil ;
452
+ bitmap = nil ;
452
453
if (window != nil ) {
453
454
frame.origin = window.frame .origin ;
454
455
[window setFrame: frame display: YES ];
@@ -601,9 +602,7 @@ - (void)sendMouseEvent:(int)x y:(int)y deltaY:(float)deltaY mouseState:(int)mous
601
602
return ;
602
603
NSView *view = webView;
603
604
NSGraphicsContext *context = [NSGraphicsContext currentContext ];
604
- dispatch_async (
605
- dispatch_get_main_queue (),
606
- ^{
605
+ [self runBlock: ^{
607
606
NSEvent *event;
608
607
switch (mouseState) {
609
608
case 1 :
@@ -636,7 +635,7 @@ - (void)sendMouseEvent:(int)x y:(int)y deltaY:(float)deltaY mouseState:(int)mous
636
635
CFRelease (cgEvent);
637
636
[view scrollWheel: scrollEvent];
638
637
}
639
- }) ;
638
+ }] ;
640
639
}
641
640
642
641
- (void )sendKeyEvent : (int )x y : (int )y keyChars : (char *)keyChars keyCode : (unsigned short )keyCode keyState : (int )keyState
@@ -650,51 +649,58 @@ - (void)sendKeyEvent:(int)x y:(int)y keyChars:(char *)keyChars keyCode:(unsigned
650
649
if (0xf700 <= keyCode && keyCode <= 0xf8ff
651
650
&& _nskey2cgkey.find (keyCode) != _nskey2cgkey.end ())
652
651
cgKeyCode = _nskey2cgkey.at (keyCode);
653
- dispatch_async (
654
- dispatch_get_main_queue (),
655
- ^{
652
+ [self runBlock: ^{
656
653
NSEvent *event;
657
654
switch (keyState) {
658
655
case 1 :
659
- if (cgKeyCode == 0 || CGEventSourceKeyState (kCGEventSourceStateCombinedSessionState , cgKeyCode)) {
660
- event = [NSEvent keyEventWithType: NSEventTypeKeyDown
661
- location: NSMakePoint (x, y) modifierFlags: 0
662
- timestamp: GetCurrentEventTime () windowNumber: 0
663
- context: context
664
- characters: characters
665
- charactersIgnoringModifiers: characters
666
- isARepeat: NO keyCode: 0 ];
667
- [view keyDown: event];
668
- }
656
+ event = [NSEvent keyEventWithType: NSEventTypeKeyDown
657
+ location: NSMakePoint (x, y) modifierFlags: 0
658
+ timestamp: GetCurrentEventTime () windowNumber: 0
659
+ context: context
660
+ characters: characters
661
+ charactersIgnoringModifiers: characters
662
+ isARepeat: NO keyCode: keyCode];
663
+ [view interpretKeyEvents: [NSArray arrayWithObject: event]];
664
+ // if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, cgKeyCode)) {
665
+ // [view keyDown:event];
666
+ // } else {
667
+ // [view interpretKeyEvents:[NSArray arrayWithObject:event]];
668
+ // }
669
669
break ;
670
670
case 2 :
671
- if (cgKeyCode == 0 || CGEventSourceKeyState (kCGEventSourceStateCombinedSessionState , cgKeyCode)) {
672
- event = [NSEvent keyEventWithType: NSEventTypeKeyDown
673
- location: NSMakePoint (x, y) modifierFlags: 0
674
- timestamp: GetCurrentEventTime () windowNumber: 0
675
- context: context
676
- characters: characters
677
- charactersIgnoringModifiers: characters
678
- isARepeat: YES keyCode: 0 ];
679
- [view keyDown: event];
680
- }
671
+ event = [NSEvent keyEventWithType: NSEventTypeKeyDown
672
+ location: NSMakePoint (x, y) modifierFlags: 0
673
+ timestamp: GetCurrentEventTime () windowNumber: 0
674
+ context: context
675
+ characters: characters
676
+ charactersIgnoringModifiers: characters
677
+ isARepeat: YES keyCode: keyCode];
678
+ [view interpretKeyEvents: [NSArray arrayWithObject: event]];
679
+ // if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, cgKeyCode)) {
680
+ // [view keyDown:event];
681
+ // } else {
682
+ // [view interpretKeyEvents:[NSArray arrayWithObject:event]];
683
+ // }
681
684
break ;
682
685
case 3 :
683
- if (cgKeyCode == 0 || !CGEventSourceKeyState (kCGEventSourceStateCombinedSessionState , cgKeyCode)) {
684
- event = [NSEvent keyEventWithType: NSEventTypeKeyUp
685
- location: NSMakePoint (x, y) modifierFlags: 0
686
- timestamp: GetCurrentEventTime () windowNumber: 0
687
- context: context
688
- characters: characters
689
- charactersIgnoringModifiers: characters
690
- isARepeat: NO keyCode: 0 ];
691
- [view keyUp: event];
692
- }
686
+ event = [NSEvent keyEventWithType: NSEventTypeKeyUp
687
+ location: NSMakePoint (x, y) modifierFlags: 0
688
+ timestamp: GetCurrentEventTime () windowNumber: 0
689
+ context: context
690
+ characters: characters
691
+ charactersIgnoringModifiers: characters
692
+ isARepeat: NO keyCode: keyCode];
693
+ [view interpretKeyEvents: [NSArray arrayWithObject: event]];
694
+ // if (CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, cgKeyCode)) {
695
+ // [view keyDown:event];
696
+ // } else {
697
+ // [view interpretKeyEvents:[NSArray arrayWithObject:event]];
698
+ // }
693
699
break ;
694
700
default :
695
701
break ;
696
702
}
697
- }) ;
703
+ }] ;
698
704
}
699
705
700
706
- (void )update : (BOOL )refreshBitmap
@@ -704,11 +710,15 @@ - (void)update:(BOOL)refreshBitmap
704
710
@synchronized (self) {
705
711
if (inRendering)
706
712
return ;
707
- if (refreshBitmap) {
708
- // [webView cacheDisplayInRect:webView.frame toBitmapImageRep:bitmap];
709
- NSRect rect = webView.frame ;
710
- if (bitmap == nil ) {
711
- bitmap
713
+ inRendering = YES ;
714
+ }
715
+ if (refreshBitmap) {
716
+ // [webView cacheDisplayInRect:webView.frame toBitmapImageRep:bitmap];
717
+ // bitmap = [webView bitmapImageRepForCachingDisplayInRect:webView.frame];
718
+ NSRect rect = webView.frame ;
719
+ if (bitmaps[0 ] == nil || bitmaps[1 ] == nil ) {
720
+ for (int i = 0 ; i < 2 ; i++) {
721
+ bitmaps[i]
712
722
= [[NSBitmapImageRep alloc ] initWithBitmapDataPlanes: nil
713
723
pixelsWide: rect.size.width
714
724
pixelsHigh: rect.size.height
@@ -720,42 +730,53 @@ - (void)update:(BOOL)refreshBitmap
720
730
bitmapFormat: 0
721
731
bytesPerRow: (4 * rect.size.width)
722
732
bitsPerPixel: 32 ];
723
- // bitmap = [webView bitmapImageRepForCachingDisplayInRect:webView.frame];
724
- needsDisplay = true ;
725
733
}
726
- inRendering = YES ;
727
- if (window != nil ) {
728
- memset ([bitmap bitmapData ], 128 , [bitmap bytesPerRow ] * [bitmap pixelsHigh ]);
729
- needsDisplay = true ;
734
+ bitmap = bitmaps[0 ];
735
+ }
736
+ NSBitmapImageRep *bitmap1 = (bitmap == bitmaps[0 ]) ? bitmaps[1 ] : bitmaps[0 ];
737
+ if (window != nil ) {
738
+ memset ([bitmap1 bitmapData ], 128 , [bitmap1 bytesPerRow ] * [bitmap1 pixelsHigh ]);
739
+ @synchronized (self) {
740
+ bitmap = bitmap1;
741
+ needsDisplay = YES ;
730
742
inRendering = NO ;
731
- } else {
732
- [webView takeSnapshotWithConfiguration: [WKSnapshotConfiguration new ]
733
- completionHandler: ^(NSImage *nsImg, NSError *err) {
734
- dispatch_async (
735
- dispatch_get_main_queue (),
736
- ^{
743
+ }
744
+ } else {
745
+ [self runBlock: ^{
746
+ [self ->webView takeSnapshotWithConfiguration: [WKSnapshotConfiguration new ]
747
+ completionHandler: ^(NSImage *nsImg, NSError *err) {
748
+ if (err == nil ) {
749
+ NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep: bitmap1];
750
+ [NSGraphicsContext saveGraphicsState ];
751
+ [NSGraphicsContext setCurrentContext: ctx];
752
+ [nsImg drawAtPoint: CGPointZero
753
+ fromRect: CGRectMake (0 , 0 , [bitmap1 pixelsWide ], [bitmap1 pixelsHigh ])
754
+ operation: NSCompositingOperationCopy
755
+ fraction: 1.0 ];
756
+ [[NSGraphicsContext currentContext ] flushGraphics ];
757
+ [NSGraphicsContext restoreGraphicsState ];
758
+ }
737
759
@synchronized (self) {
738
- if (err == nil && self->bitmap != nil ) {
739
- NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep: self ->bitmap];
740
- [NSGraphicsContext saveGraphicsState ];
741
- [NSGraphicsContext setCurrentContext: ctx];
742
- [nsImg drawAtPoint: CGPointZero
743
- fromRect: CGRectMake (0 , 0 , [self ->bitmap pixelsWide ], [self ->bitmap pixelsHigh ])
744
- operation: NSCompositingOperationCopy
745
- fraction: 1.0 ];
746
- [[NSGraphicsContext currentContext ] flushGraphics ];
747
- [NSGraphicsContext restoreGraphicsState ];
748
- }
749
- self->needsDisplay = true ;
760
+ self->bitmap = bitmap1;
761
+ self->needsDisplay = YES ;
750
762
self->inRendering = NO ;
751
763
}
752
- }) ;
764
+ }] ;
753
765
}];
754
- }
755
766
}
756
767
}
757
768
}
758
769
770
+ - (void )runBlock : (void (^)())block
771
+ {
772
+ block ();
773
+ // if ([NSThread isMainThread]) {
774
+ // block();
775
+ // } else {
776
+ // dispatch_sync(dispatch_get_main_queue(), block);
777
+ // }
778
+ }
779
+
759
780
- (int )bitmapWide
760
781
{
761
782
@synchronized (self) {
@@ -772,44 +793,29 @@ - (int)bitmapHigh
772
793
773
794
- (void )render : (void *)textureBuffer
774
795
{
796
+ if (webView == nil )
797
+ return ;
798
+ NSBitmapImageRep *bitmap0;
775
799
@synchronized (self) {
776
- if (webView == nil )
777
- return ;
778
800
if (!needsDisplay)
779
801
return ;
780
802
if (bitmap == nil )
781
803
return ;
782
- int w = (int )[bitmap pixelsWide ];
783
- int h = (int )[bitmap pixelsHigh ];
784
- int p = (int )[bitmap samplesPerPixel ];
785
- int r = (int )[bitmap bytesPerRow ];
786
- uint8_t *s0 = (uint8_t *)[bitmap bitmapData ];
787
- uint32_t *d0 = (uint32_t *)textureBuffer;
788
- if (p == 3 ) {
789
- for (int y = 0 ; y < h; y++) {
790
- uint8_t *s = s0 + y * r;
791
- uint32_t *d = d0 + y * w;
792
- for (int x = 0 ; x < w; x++) {
793
- uint32_t r = *s++;
794
- uint32_t g = *s++;
795
- uint32_t b = *s++;
796
- *d++ = (0xff << 24 ) | (b << 16 ) | (g << 8 ) | r;
797
- }
798
- }
799
- } else if (p == 4 ) {
800
- for (int y = 0 ; y < h; y++) {
801
- uint8_t *s = s0 + y * r;
802
- uint32_t *d = d0 + y * w;
803
- for (int x = 0 ; x < w; x++) {
804
- uint32_t r = *s++;
805
- uint32_t g = *s++;
806
- uint32_t b = *s++;
807
- uint32_t a = *s++;
808
- *d++ = (a << 24 ) | (b << 16 ) | (g << 8 ) | r;
809
- }
810
- }
804
+ needsDisplay = NO ;
805
+ bitmap0 = bitmap;
806
+ }
807
+ int w = (int )[bitmap0 pixelsWide ];
808
+ int h = (int )[bitmap0 pixelsHigh ];
809
+ // int p = (int)[bitmap0 samplesPerPixel]; // should be 4.
810
+ int r = (int )[bitmap0 bytesPerRow ];
811
+ uint32_t *s0 = (uint32_t *)[bitmap0 bitmapData ];
812
+ uint32_t *d0 = (uint32_t *)textureBuffer;
813
+ for (int y = 0 ; y < h; y++) {
814
+ uint32_t *s = (uint32_t *)((uint8_t *)s0 + y * r);
815
+ uint32_t *d = d0 + y * w;
816
+ for (int x = 0 ; x < w; x++) {
817
+ *d++ = *s++;
811
818
}
812
- needsDisplay = false ;
813
819
}
814
820
}
815
821
0 commit comments