From 6540d0635b3ac93a2689f5f8ef51cb9a3eb16aeb Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 5 Feb 2020 09:26:46 +0300 Subject: [PATCH] IOSurface render target for sw-rendering --- native/Avalonia.Native/inc/avalonia-native.h | 3 - native/Avalonia.Native/inc/rendertarget.h | 12 ++ .../project.pbxproj | 12 ++ .../Avalonia.Native/src/OSX/rendertarget.mm | 105 +++++++++++ native/Avalonia.Native/src/OSX/window.mm | 172 +++++------------- .../AvaloniaNativeDeferredRendererLock.cs | 42 ----- src/Avalonia.Native/AvaloniaNativePlatform.cs | 7 +- src/Avalonia.Native/DeferredFramebuffer.cs | 2 +- src/Avalonia.Native/WindowImplBase.cs | 55 ++---- 9 files changed, 197 insertions(+), 213 deletions(-) create mode 100644 native/Avalonia.Native/inc/rendertarget.h create mode 100644 native/Avalonia.Native/src/OSX/rendertarget.mm delete mode 100644 src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h index 677fa2f4c5..24607c26cb 100644 --- a/native/Avalonia.Native/inc/avalonia-native.h +++ b/native/Avalonia.Native/inc/avalonia-native.h @@ -219,15 +219,12 @@ AVNCOM(IAvnWindowBase, 02) : IUnknown virtual HRESULT SetTopMost (bool value) = 0; virtual HRESULT SetCursor(IAvnCursor* cursor) = 0; virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret) = 0; - virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) = 0; virtual HRESULT SetMainMenu(IAvnAppMenu* menu) = 0; virtual HRESULT ObtainMainMenu(IAvnAppMenu** retOut) = 0; virtual HRESULT ObtainNSWindowHandle(void** retOut) = 0; virtual HRESULT ObtainNSWindowHandleRetained(void** retOut) = 0; virtual HRESULT ObtainNSViewHandle(void** retOut) = 0; virtual HRESULT ObtainNSViewHandleRetained(void** retOut) = 0; - virtual bool TryLock() = 0; - virtual void Unlock() = 0; }; AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase diff --git a/native/Avalonia.Native/inc/rendertarget.h b/native/Avalonia.Native/inc/rendertarget.h new file mode 100644 index 0000000000..00d4b4bd4a --- /dev/null +++ b/native/Avalonia.Native/inc/rendertarget.h @@ -0,0 +1,12 @@ + +@protocol IRenderTarget +-(void) setNewLayer: (CALayer*) layer; +-(HRESULT) setSwFrame: (AvnFramebuffer*) fb; +-(void) resize: (AvnPixelSize) size withScale: (float) scale; +-(AvnPixelSize) pixelSize; +@end + +@interface IOSurfaceRenderTarget : NSObject +-(IOSurfaceRenderTarget*) init; +@end + diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj index c0a49382a7..686c37bc24 100644 --- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj +++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj @@ -8,6 +8,9 @@ /* Begin PBXBuildFile section */ 1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; }; + 1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; }; + 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */; }; + 1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */; }; 37155CE4233C00EB0034DCE9 /* menu.h in Headers */ = {isa = PBXBuildFile; fileRef = 37155CE3233C00EB0034DCE9 /* menu.h */; }; 37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; }; 37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; }; @@ -26,6 +29,9 @@ /* Begin PBXFileReference section */ 1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = ""; }; + 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = ""; }; + 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; }; + 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 37155CE3233C00EB0034DCE9 /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = ""; }; 379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = ""; }; 37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = ""; }; @@ -54,6 +60,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */, + 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */, AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */, AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */, ); @@ -65,6 +73,8 @@ AB661C1C2148230E00291242 /* Frameworks */ = { isa = PBXGroup; children = ( + 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */, + 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */, AB1E522B217613570091CD71 /* OpenGL.framework */, AB661C1D2148230F00291242 /* AppKit.framework */, ); @@ -91,6 +101,7 @@ AB00E4F62147CA920032A60A /* main.mm */, 37155CE3233C00EB0034DCE9 /* menu.h */, 520624B222973F4100C4DCEF /* menu.mm */, + 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */, 37A517B22159597E00FBA241 /* Screens.mm */, 37C09D8721580FE4006A6758 /* SystemDialogs.mm */, AB7A61F02147C815003C5833 /* Products */, @@ -180,6 +191,7 @@ 5B21A982216530F500CEE36E /* cursor.mm in Sources */, 37DDA9B0219330F8002E132B /* AvnString.mm in Sources */, AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */, + 1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */, 37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */, 520624B322973F4100C4DCEF /* menu.mm in Sources */, 37A517B32159597E00FBA241 /* Screens.mm in Sources */, diff --git a/native/Avalonia.Native/src/OSX/rendertarget.mm b/native/Avalonia.Native/src/OSX/rendertarget.mm new file mode 100644 index 0000000000..3a86339496 --- /dev/null +++ b/native/Avalonia.Native/src/OSX/rendertarget.mm @@ -0,0 +1,105 @@ +#include "common.h" +#include "rendertarget.h" +#import +#import + +@implementation IOSurfaceRenderTarget +{ + CALayer* _layer; + IOSurfaceRef _surface; + AvnPixelSize _size; + float _scale; + NSObject* _lock; +} + +- (IOSurfaceRenderTarget*) init +{ + self = [super init]; + _lock = [NSObject new]; + _surface = nil; + [self resize:{1,1} withScale: 1]; + + return self; +} + +- (AvnPixelSize) pixelSize { + return {1, 1}; +} + +- (CALayer *)layer { + return _layer; +} + +- (void)resize:(AvnPixelSize)size withScale: (float) scale;{ + @synchronized (_lock) { + if(_surface != nil) + { + IOSurfaceDecrementUseCount(_surface); + _surface = nil; + } + NSDictionary* options = @{ + (id)kIOSurfaceWidth: @(size.Width), + (id)kIOSurfaceHeight: @(size.Height), + (id)kIOSurfacePixelFormat: @((uint)'BGRA'), + (id)kIOSurfaceBytesPerElement: @(4), + //(id)kIOSurfaceBytesPerRow: @(bytesPerRow), + //(id)kIOSurfaceAllocSize: @(m_totalBytes), + + //(id)kIOSurfaceCacheMode: @(kIOMapWriteCombineCache), + (id)kIOSurfaceElementWidth: @(1), + (id)kIOSurfaceElementHeight: @(1) + }; + + _surface = IOSurfaceCreate((CFDictionaryRef)options); + _scale = scale; + _size = size; + } +} + +- (void)updateLayer { + if ([NSThread isMainThread]) + { + @synchronized (_lock) { + if(_layer == nil) + return; + [_layer setContentsScale: _scale]; + [_layer setContents: nil]; + [_layer setContents: (__bridge IOSurface* )_surface]; + } + } + else + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateLayer]; + }); +} + +- (void) setNewLayer:(CALayer *)layer { + _layer = layer; + [self updateLayer]; +} + +- (HRESULT)setSwFrame:(AvnFramebuffer *)fb { + @synchronized (_lock) { + if(fb->PixelFormat == AvnPixelFormat::kAvnRgb565) + return E_INVALIDARG; + if(IOSurfaceLock(_surface, 0, nil)) + return E_FAIL; + size_t w = MIN(fb->Width, IOSurfaceGetWidth(_surface)); + size_t h = MIN(fb->Height, IOSurfaceGetHeight(_surface)); + size_t wbytes = w*4; + size_t sstride = IOSurfaceGetBytesPerRow(_surface); + size_t fstride = fb->Stride; + char*pSurface = (char*)IOSurfaceGetBaseAddress(_surface); + char*pFb = (char*)fb->Data; + for(size_t y = 0; y +#include "rendertarget.h" + -class SoftwareDrawingOperation -{ -public: - void* Data = 0; - AvnFramebuffer Desc; - void Alloc(NSView* view) - { - auto logicalSize = [view frame].size; - auto pixelSize = [view convertSizeToBacking:logicalSize]; - int w = pixelSize.width; - int h = pixelSize.height; - int stride = w * 4; - Data = malloc(h * stride); - Desc = { - .Data = Data, - .Stride = stride, - .Width = w, - .Height = h, - .PixelFormat = kAvnRgba8888, - .Dpi = AvnVector { .X = w / logicalSize.width * 96, .Y = h / logicalSize.height * 96} - }; - } - - void Dealloc() - { - if(Data != NULL) - { - free(Data); - Data = NULL; - } - } - - ~SoftwareDrawingOperation() - { - Dealloc(); - } -}; class WindowBaseImpl : public virtual ComSingleObject, public INSWindowHolder { @@ -61,7 +26,7 @@ public: AvnView* View; AvnWindow* Window; ComPtr BaseEvents; - SoftwareDrawingOperation CurrentSwDrawingOperation; + NSObject* renderTarget; AvnPoint lastPositionSet; NSString* _lastTitle; IAvnAppMenu* _mainMenu; @@ -70,6 +35,7 @@ public: { _mainMenu = nullptr; BaseEvents = events; + renderTarget = [IOSurfaceRenderTarget new]; View = [[AvnView alloc] initWithParent:this]; Window = [[AvnWindow alloc] initWithParent:this]; @@ -291,29 +257,6 @@ public: return S_OK; } - virtual bool TryLock() override - { - @autoreleasepool - { - @try - { - return [View lockFocusIfCanDraw] == YES; - } - @catch (NSException*) - { - return NO; - } - } - } - - virtual void Unlock() override - { - @autoreleasepool - { - [View unlockFocus]; - } - } - virtual HRESULT BeginMoveDrag () override { @autoreleasepool @@ -408,16 +351,6 @@ public: return S_OK; } - virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) override - { - if(![[NSThread currentThread] isMainThread]) - return E_FAIL; - if(CurrentSwDrawingOperation.Data == NULL) - CurrentSwDrawingOperation.Alloc(View); - *ret = CurrentSwDrawingOperation.Desc; - return S_OK; - } - virtual HRESULT SetCursor(IAvnCursor* cursor) override { @autoreleasepool @@ -731,6 +664,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent NSEvent* _lastMouseDownEvent; bool _lastKeyHandled; AvnPixelSize _lastPixelSize; + NSObject* _renderTarget; } - (void)onClosed @@ -741,6 +675,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent } } +/* - (BOOL)lockFocusIfCanDraw { @synchronized (self) @@ -752,7 +687,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent } return [super lockFocusIfCanDraw]; -} +}*/ -(AvnPixelSize) getPixelSize { @@ -764,18 +699,47 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent return _lastMouseDownEvent; } +- (void) updateRenderTarget +{ + [_renderTarget resize:_lastPixelSize withScale: [[self window] backingScaleFactor]]; + [self setNeedsDisplayInRect:[self frame]]; +} + -(AvnView*) initWithParent: (WindowBaseImpl*) parent { self = [super init]; - [self setWantsBestResolutionOpenGLSurface:true]; + _renderTarget = parent->renderTarget; [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; + _parent = parent; _area = nullptr; _lastPixelSize.Height = 100; _lastPixelSize.Width = 100; +/* uncomment to verify that embedding isn't broken + NSTextField* txt = [NSTextField new]; + [self addSubview:txt]; + [txt setFrame:{0,0, 100,100}]; + */ return self; } +- (BOOL)isFlipped +{ + return YES; +} + +- (BOOL)wantsUpdateLayer +{ + return YES; +} + +- (void)setLayer:(CALayer *)layer +{ + [_renderTarget setNewLayer: layer]; + [super setLayer: layer]; +} + - (BOOL)isOpaque { return YES; @@ -823,56 +787,24 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent auto fsize = [self convertSizeToBacking: [self frame].size]; _lastPixelSize.Width = (int)fsize.width; _lastPixelSize.Height = (int)fsize.height; - + [self updateRenderTarget]; _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}); } -- (void) drawFb: (AvnFramebuffer*) fb -{ - auto colorSpace = CGColorSpaceCreateDeviceRGB(); - auto dataProvider = CGDataProviderCreateWithData(NULL, fb->Data, fb->Height*fb->Stride, NULL); - - auto image = CGImageCreate(fb->Width, fb->Height, 8, 32, fb->Stride, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, - dataProvider, nullptr, false, kCGRenderingIntentDefault); - - auto ctx = [NSGraphicsContext currentContext]; - - [ctx saveGraphicsState]; - auto cgc = [ctx CGContext]; - - CGContextDrawImage(cgc, CGRect{0,0, fb->Width/(fb->Dpi.X/96), fb->Height/(fb->Dpi.Y/96)}, image); - CGImageRelease(image); - CGColorSpaceRelease(colorSpace); - CGDataProviderRelease(dataProvider); - - [ctx restoreGraphicsState]; - -} - -- (void)drawRect:(NSRect)dirtyRect +- (void)updateLayer { if (_parent == nullptr) { return; } - - _parent->BaseEvents->RunRenderPriorityJobs(); - - @synchronized (self) { - if(_swRenderedFrame != NULL) - { - [self drawFb: &_swRenderedFrameBuffer]; - return; - } - } - auto swOp = &_parent->CurrentSwDrawingOperation; + _parent->BaseEvents->RunRenderPriorityJobs(); _parent->BaseEvents->Paint(); - if(swOp->Data != NULL) - [self drawFb: &swOp->Desc]; - - swOp->Dealloc(); +} + +- (void)drawRect:(NSRect)dirtyRect +{ return; } @@ -886,24 +818,16 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent return; _queuedDisplayFromThread = false; } - [self setNeedsDisplayInRect:[self frame]]; + [self setNeedsDisplayInRect: [self frame]]; [self display]; - } } -(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose { @autoreleasepool { - @synchronized (self) { - _swRenderedFrame = dispose; - _swRenderedFrameBuffer = *fb; - if(!_queuedDisplayFromThread) - { - _queuedDisplayFromThread = true; - [self performSelector:@selector(redrawSelf) onThread:[NSThread mainThread] withObject:NULL waitUntilDone:false modes: AllLoopModes]; - } - } + [_renderTarget setSwFrame:fb]; + dispose->Release(); } } @@ -928,7 +852,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent auto fsize = [self convertSizeToBacking: [self frame].size]; _lastPixelSize.Width = (int)fsize.width; _lastPixelSize.Height = (int)fsize.height; - + [self updateRenderTarget]; _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]); [super viewDidChangeBackingProperties]; diff --git a/src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs b/src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs deleted file mode 100644 index ce2b03e355..0000000000 --- a/src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Threading; -using Avalonia.Native.Interop; -using Avalonia.Rendering; - -namespace Avalonia.Native -{ - public class AvaloniaNativeDeferredRendererLock : IDeferredRendererLock - { - private readonly IAvnWindowBase _window; - - public AvaloniaNativeDeferredRendererLock(IAvnWindowBase window) - { - _window = window; - } - - public IDisposable TryLock() - { - if (_window.TryLock()) - return new UnlockDisposable(_window); - return null; - } - - private sealed class UnlockDisposable : IDisposable - { - private IAvnWindowBase _window; - - public UnlockDisposable(IAvnWindowBase window) - { - _window = window; - } - - public void Dispose() - { - Interlocked.Exchange(ref _window, null)?.Unlock(); - } - } - } -} diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs index 756619fa9f..825666b909 100644 --- a/src/Avalonia.Native/AvaloniaNativePlatform.cs +++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.Runtime.InteropServices; +using System.Security.Cryptography; using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; @@ -88,6 +89,8 @@ namespace Avalonia.Native _factory.MacOptions.ShowInDock = macOpts?.ShowInDock != false ? 1 : 0; } + _options.UseGpu = false; + AvaloniaLocator.CurrentMutable .Bind() .ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface())) @@ -100,9 +103,11 @@ namespace Avalonia.Native .Bind().ToConstant(new RenderLoop()) .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs())) - .Bind().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature())) .Bind().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta)) .Bind().ToConstant(new MacOSMountedVolumeInfoProvider()); + if (_options.UseGpu) + AvaloniaLocator.CurrentMutable.Bind() + .ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature())); } public IWindowImpl CreateWindow() diff --git a/src/Avalonia.Native/DeferredFramebuffer.cs b/src/Avalonia.Native/DeferredFramebuffer.cs index adc721de42..0c32bce145 100644 --- a/src/Avalonia.Native/DeferredFramebuffer.cs +++ b/src/Avalonia.Native/DeferredFramebuffer.cs @@ -21,7 +21,7 @@ namespace Avalonia.Native Size = new PixelSize(width, height); RowBytes = width * 4; Dpi = dpi; - Format = PixelFormat.Rgba8888; + Format = PixelFormat.Bgra8888; } public IntPtr Address { get; set; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 5d701dc8df..a2148f6782 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -103,25 +103,20 @@ namespace Avalonia.Native public ILockedFramebuffer Lock() { - if(_deferredRendering) + var w = _savedLogicalSize.Width * _savedScaling; + var h = _savedLogicalSize.Height * _savedScaling; + var dpi = _savedScaling * 96; + return new DeferredFramebuffer(cb => { - var w = _savedLogicalSize.Width * _savedScaling; - var h = _savedLogicalSize.Height * _savedScaling; - var dpi = _savedScaling * 96; - return new DeferredFramebuffer(cb => + lock (_syncRoot) { - lock (_syncRoot) - { - if (_native == null) - return false; - cb(_native); - _lastRenderedLogicalSize = _savedLogicalSize; - return true; - } - }, (int)w, (int)h, new Vector(dpi, dpi)); - } - - return new FramebufferWrapper(_native.GetSoftwareFramebuffer()); + if (_native == null) + return false; + cb(_native); + _lastRenderedLogicalSize = _savedLogicalSize; + return true; + } + }, (int)w, (int)h, new Vector(dpi, dpi)); } public Action Paint { get; set; } @@ -130,28 +125,6 @@ namespace Avalonia.Native public IMouseDevice MouseDevice => _mouse; public abstract IPopupImpl CreatePopup(); - - class FramebufferWrapper : ILockedFramebuffer - { - public FramebufferWrapper(AvnFramebuffer fb) - { - Address = fb.Data; - Size = new PixelSize(fb.Width, fb.Height); - RowBytes = fb.Stride; - Dpi = new Vector(fb.Dpi.X, fb.Dpi.Y); - Format = (PixelFormat)fb.PixelFormat; - } - public IntPtr Address { get; set; } - public PixelSize Size { get; set; } - public int RowBytes {get;set;} - public Vector Dpi { get; set; } - public PixelFormat Format { get; } - public void Dispose() - { - // Do nothing - } - } - protected class WindowBaseEvents : CallbackBase, IAvnWindowBaseEvents { private readonly WindowBaseImpl _parent; @@ -278,9 +251,7 @@ namespace Avalonia.Native public IRenderer CreateRenderer(IRenderRoot root) { if (_deferredRendering) - return new DeferredRenderer(root, AvaloniaLocator.Current.GetService(), - rendererLock: - _gpu ? new AvaloniaNativeDeferredRendererLock(_native) : null); + return new DeferredRenderer(root, AvaloniaLocator.Current.GetService()); return new ImmediateRenderer(root); }