Browse Source

Merge branch 'master' into update-obsolete-api-usages

pull/3524/head
Dariusz Komosiński 6 years ago
committed by GitHub
parent
commit
dde979280d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build/SharedVersion.props
  2. 28
      native/Avalonia.Native/inc/avalonia-native.h
  3. 13
      native/Avalonia.Native/inc/comimpl.h
  4. 12
      native/Avalonia.Native/inc/rendertarget.h
  5. 20
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  6. 166
      native/Avalonia.Native/src/OSX/cgl.mm
  7. 7
      native/Avalonia.Native/src/OSX/common.h
  8. 261
      native/Avalonia.Native/src/OSX/gl.mm
  9. 12
      native/Avalonia.Native/src/OSX/main.mm
  10. 284
      native/Avalonia.Native/src/OSX/rendertarget.mm
  11. 207
      native/Avalonia.Native/src/OSX/window.mm
  12. 13
      src/Avalonia.Controls.DataGrid/Themes/Default.xaml
  13. 2
      src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml
  14. 42
      src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs
  15. 10
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  16. 2
      src/Avalonia.Native/DeferredFramebuffer.cs
  17. 31
      src/Avalonia.Native/GlPlatformFeature.cs
  18. 12
      src/Avalonia.Native/PopupImpl.cs
  19. 10
      src/Avalonia.Native/WindowImpl.cs
  20. 63
      src/Avalonia.Native/WindowImplBase.cs
  21. 1
      src/Avalonia.OpenGL/EglGlPlatformSurface.cs
  22. 1
      src/Avalonia.OpenGL/IGlPlatformSurfaceRenderingSession.cs
  23. 1
      src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs
  24. 2
      src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
  25. 2
      src/Skia/Avalonia.Skia/GlRenderTarget.cs
  26. 1
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

2
build/SharedVersion.props

@ -3,7 +3,7 @@
<PropertyGroup>
<Product>Avalonia</Product>
<Version>0.9.999</Version>
<Copyright>Copyright 2019 &#169; The AvaloniaUI Project</Copyright>
<Copyright>Copyright 2020 &#169; The AvaloniaUI Project</Copyright>
<PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl>
<RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

28
native/Avalonia.Native/inc/avalonia-native.h

@ -177,14 +177,14 @@ AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown
public:
virtual HRESULT Initialize() = 0;
virtual IAvnMacOptions* GetMacOptions() = 0;
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0;
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0;
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) = 0;
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) = 0;
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0;
virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0;
virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0;
virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 0;
virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) = 0;
virtual HRESULT ObtainAppMenu(IAvnAppMenu** retOut) = 0;
virtual HRESULT SetAppMenu(IAvnAppMenu* menu) = 0;
virtual HRESULT CreateMenu (IAvnAppMenu** ppv) = 0;
@ -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
@ -360,24 +357,21 @@ AVNCOM(IAvnCursorFactory, 11) : IUnknown
virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0;
};
AVNCOM(IAvnGlFeature, 12) : IUnknown
{
virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) = 0;
virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) = 0;
};
AVNCOM(IAvnGlDisplay, 13) : IUnknown
{
virtual HRESULT GetSampleCount(int* ret) = 0;
virtual HRESULT GetStencilSize(int* ret) = 0;
virtual HRESULT ClearContext() = 0;
virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) = 0;
virtual void LegacyClearCurrentContext() = 0;
virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) = 0;
virtual void* GetProcAddress(char* proc) = 0;
};
AVNCOM(IAvnGlContext, 14) : IUnknown
{
virtual HRESULT MakeCurrent() = 0;
virtual HRESULT MakeCurrent(IUnknown** ppv) = 0;
virtual HRESULT LegacyMakeCurrent() = 0;
virtual int GetSampleCount() = 0;
virtual int GetStencilSize() = 0;
virtual void* GetNativeHandle() = 0;
};
AVNCOM(IAvnGlSurfaceRenderTarget, 15) : IUnknown

13
native/Avalonia.Native/inc/comimpl.h

@ -162,6 +162,19 @@ public:
return _obj;
}
TInterface* getRetainedReference()
{
if(_obj == NULL)
return NULL;
_obj->AddRef();
return _obj;
}
TInterface** getPPV()
{
return &_obj;
}
operator TInterface*() const
{
return _obj;

12
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;
-(IAvnGlSurfaceRenderTarget*) createSurfaceRenderTarget;
@end
@interface IOSurfaceRenderTarget : NSObject<IRenderTarget>
-(IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context;
@end

20
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -8,6 +8,10 @@
/* 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 */; };
1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */; };
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 */; };
@ -18,7 +22,6 @@
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; };
AB573DC4217605E400D389A2 /* gl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB573DC3217605E400D389A2 /* gl.mm */; };
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; };
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; };
@ -26,6 +29,10 @@
/* Begin PBXFileReference section */
1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; };
1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = "<group>"; };
1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; };
1A3E5EAD23E9FB1300EDE661 /* cgl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cgl.mm; sourceTree = "<group>"; };
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 = "<group>"; };
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; };
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; };
@ -41,7 +48,6 @@
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
AB573DC3217605E400D389A2 /* gl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gl.mm; sourceTree = "<group>"; };
AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = "<group>"; };
AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
@ -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 */,
);
@ -78,7 +88,7 @@
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
AB573DC3217605E400D389A2 /* gl.mm */,
1A3E5EAD23E9FB1300EDE661 /* cgl.mm */,
5BF943652167AD1D009CAE35 /* cursor.h */,
5B21A981216530F500CEE36E /* cursor.mm */,
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */,
@ -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,12 +191,13 @@
5B21A982216530F500CEE36E /* cursor.mm in Sources */,
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */,
1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */,
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
520624B322973F4100C4DCEF /* menu.mm in Sources */,
37A517B32159597E00FBA241 /* Screens.mm in Sources */,
AB00E4F72147CA920032A60A /* main.mm in Sources */,
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,
AB573DC4217605E400D389A2 /* gl.mm in Sources */,
AB661C202148286E00291242 /* window.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

166
native/Avalonia.Native/src/OSX/cgl.mm

@ -0,0 +1,166 @@
#include "common.h"
#include <dlfcn.h>
static CGLContextObj CreateCglContext(CGLContextObj share)
{
int attributes[] = {
kCGLPFAAccelerated,
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
kCGLPFADepthSize, 8,
kCGLPFAStencilSize, 8,
kCGLPFAColorSize, 32,
0
};
CGLPixelFormatObj pix;
CGLError errorCode;
GLint num; // stores the number of possible pixel formats
errorCode = CGLChoosePixelFormat( (CGLPixelFormatAttribute*)attributes, &pix, &num );
if(errorCode != 0)
return nil;
CGLContextObj ctx = nil;
errorCode = CGLCreateContext(pix, share, &ctx );
CGLDestroyPixelFormat( pix );
if(errorCode != 0)
return nil;
return ctx;
};
class AvnGlContext : public virtual ComSingleObject<IAvnGlContext, &IID_IAvnGlContext>
{
// Debug
int _usageCount = 0;
public:
CGLContextObj Context;
int SampleCount = 0, StencilBits = 0;
FORWARD_IUNKNOWN()
class SavedGlContext : public virtual ComUnknownObject
{
CGLContextObj _savedContext;
ComPtr<AvnGlContext> _parent;
public:
SavedGlContext(CGLContextObj saved, AvnGlContext* parent)
{
_savedContext = saved;
_parent = parent;
_parent->_usageCount++;
}
~SavedGlContext()
{
if(_parent->Context == CGLGetCurrentContext())
CGLSetCurrentContext(_savedContext);
_parent->_usageCount--;
CGLUnlockContext(_parent->Context);
}
};
AvnGlContext(CGLContextObj context)
{
Context = context;
CGLPixelFormatObj fmt = CGLGetPixelFormat(context);
CGLDescribePixelFormat(fmt, 0, kCGLPFASamples, &SampleCount);
CGLDescribePixelFormat(fmt, 0, kCGLPFAStencilSize, &StencilBits);
}
virtual HRESULT LegacyMakeCurrent() override
{
if(CGLSetCurrentContext(Context) != 0)
return E_FAIL;
return S_OK;
}
virtual HRESULT MakeCurrent(IUnknown** ppv) override
{
CGLContextObj saved = CGLGetCurrentContext();
CGLLockContext(Context);
if(CGLSetCurrentContext(Context) != 0)
{
CGLUnlockContext(Context);
return E_FAIL;
}
*ppv = new SavedGlContext(saved, this);
return S_OK;
}
virtual int GetSampleCount() override
{
return SampleCount;
}
virtual int GetStencilSize() override
{
return StencilBits;
}
virtual void* GetNativeHandle() override
{
return Context;
}
~AvnGlContext()
{
CGLReleaseContext(Context);
}
};
class AvnGlDisplay : public virtual ComSingleObject<IAvnGlDisplay, &IID_IAvnGlDisplay>
{
void* _libgl;
public:
FORWARD_IUNKNOWN()
AvnGlDisplay()
{
_libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", RTLD_LAZY);
}
virtual void* GetProcAddress(char* proc) override
{
return dlsym(_libgl, proc);
}
virtual HRESULT CreateContext(IAvnGlContext* share, IAvnGlContext**ppv) override
{
CGLContextObj shareContext = nil;
if(share != nil)
{
AvnGlContext* shareCtx = dynamic_cast<AvnGlContext*>(share);
if(shareCtx != nil)
shareContext = shareCtx->Context;
}
CGLContextObj ctx = ::CreateCglContext(shareContext);
if(ctx == nil)
return E_FAIL;
*ppv = new AvnGlContext(ctx);
return S_OK;
}
virtual HRESULT WrapContext(void* native, IAvnGlContext**ppv) override
{
if(native == nil)
return E_INVALIDARG;
*ppv = new AvnGlContext((CGLContextObj) native);
return S_OK;
}
virtual void LegacyClearCurrentContext() override
{
CGLSetCurrentContext(nil);
}
};
static IAvnGlDisplay* GlDisplay = new AvnGlDisplay();
extern IAvnGlDisplay* GetGlDisplay()
{
return GlDisplay;
};

7
native/Avalonia.Native/src/OSX/common.h

@ -11,14 +11,13 @@
#include <pthread.h>
extern IAvnPlatformThreadingInterface* CreatePlatformThreading();
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events);
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl);
extern IAvnSystemDialogs* CreateSystemDialogs();
extern IAvnScreens* CreateScreens();
extern IAvnClipboard* CreateClipboard();
extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlFeature* GetGlFeature();
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view);
extern IAvnGlDisplay* GetGlDisplay();
extern IAvnAppMenu* CreateAppMenu();
extern IAvnAppMenuItem* CreateAppMenuItem();
extern IAvnAppMenuItem* CreateAppMenuItemSeperator();

261
native/Avalonia.Native/src/OSX/gl.mm

@ -1,261 +0,0 @@
#include "common.h"
#include <OpenGL/gl.h>
#include <dlfcn.h>
#include "window.h"
template <typename T, size_t N> char (&ArrayCounter(T (&a)[N]))[N];
#define ARRAY_COUNT(a) (sizeof(ArrayCounter(a)))
NSOpenGLPixelFormat* CreateFormat()
{
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFADepthSize, 8,
0
};
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
}
class AvnGlContext : public virtual ComSingleObject<IAvnGlContext, &IID_IAvnGlContext>
{
public:
FORWARD_IUNKNOWN()
NSOpenGLContext* GlContext;
GLuint Framebuffer, RenderBuffer, StencilBuffer;
AvnGlContext(NSOpenGLContext* gl, bool offscreen)
{
Framebuffer = 0;
RenderBuffer = 0;
StencilBuffer = 0;
GlContext = gl;
if(offscreen)
{
[GlContext makeCurrentContext];
glGenFramebuffersEXT(1, &Framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer);
glGenRenderbuffersEXT(1, &RenderBuffer);
glGenRenderbuffersEXT(1, &StencilBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer);
}
}
virtual HRESULT MakeCurrent() override
{
[GlContext makeCurrentContext];/*
glBindFramebufferEXT(GL_FRAMEBUFFER, Framebuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER, RenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RenderBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER, StencilBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, StencilBuffer);*/
return S_OK;
}
};
class AvnGlDisplay : public virtual ComSingleObject<IAvnGlDisplay, &IID_IAvnGlDisplay>
{
int _sampleCount, _stencilSize;
void* _libgl;
public:
FORWARD_IUNKNOWN()
AvnGlDisplay(int sampleCount, int stencilSize)
{
_sampleCount = sampleCount;
_stencilSize = stencilSize;
_libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", RTLD_LAZY);
}
virtual HRESULT GetSampleCount(int* ret) override
{
*ret = _sampleCount;
return S_OK;
}
virtual HRESULT GetStencilSize(int* ret) override
{
*ret = _stencilSize;
return S_OK;
}
virtual HRESULT ClearContext() override
{
[NSOpenGLContext clearCurrentContext];
return S_OK;
}
virtual void* GetProcAddress(char* proc) override
{
return dlsym(_libgl, proc);
}
};
class GlFeature : public virtual ComSingleObject<IAvnGlFeature, &IID_IAvnGlFeature>
{
IAvnGlDisplay* _display;
AvnGlContext *_immediate;
NSOpenGLContext* _shared;
public:
FORWARD_IUNKNOWN()
NSOpenGLPixelFormat* _format;
GlFeature(IAvnGlDisplay* display, AvnGlContext* immediate, NSOpenGLPixelFormat* format)
{
_display = display;
_immediate = immediate;
_format = format;
_shared = [[NSOpenGLContext alloc] initWithFormat:_format shareContext:_immediate->GlContext];
}
NSOpenGLContext* CreateContext()
{
return _shared;
//return [[NSOpenGLContext alloc] initWithFormat:_format shareContext:nil];
}
virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) override
{
*retOut = _display;
_display->AddRef();
return S_OK;
}
virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) override
{
*retOut = _immediate;
_immediate->AddRef();
return S_OK;
}
};
static GlFeature* Feature;
GlFeature* CreateGlFeature()
{
auto format = CreateFormat();
if(format == nil)
{
NSLog(@"Unable to choose pixel format");
return NULL;
}
auto immediateContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
if(immediateContext == nil)
{
NSLog(@"Unable to create NSOpenGLContext");
return NULL;
}
int stencilBits = 0, sampleCount = 0;
auto fmt = CGLGetPixelFormat([immediateContext CGLContextObj]);
CGLDescribePixelFormat(fmt, 0, kCGLPFASamples, &sampleCount);
CGLDescribePixelFormat(fmt, 0, kCGLPFAStencilSize, &stencilBits);
auto offscreen = new AvnGlContext(immediateContext, true);
auto display = new AvnGlDisplay(sampleCount, stencilBits);
return new GlFeature(display, offscreen, format);
}
static GlFeature* GetFeature()
{
if(Feature == nil)
Feature = CreateGlFeature();
return Feature;
}
extern IAvnGlFeature* GetGlFeature()
{
return GetFeature();
}
class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSession, &IID_IAvnGlSurfaceRenderingSession>
{
AvnView* _view;
AvnWindow* _window;
NSOpenGLContext* _context;
public:
FORWARD_IUNKNOWN()
AvnGlRenderingSession(AvnWindow*window, AvnView* view, NSOpenGLContext* context)
{
_context = context;
_window = window;
_view = view;
}
virtual HRESULT GetPixelSize(AvnPixelSize* ret) override
{
*ret = [_view getPixelSize];
return S_OK;
}
virtual HRESULT GetScaling(double* ret) override
{
*ret = [_window getScaling];
return S_OK;
}
virtual ~AvnGlRenderingSession()
{
[_context flushBuffer];
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext([_context CGLContextObj]);
[_view unlockFocus];
}
};
class AvnGlRenderTarget : public ComSingleObject<IAvnGlSurfaceRenderTarget, &IID_IAvnGlSurfaceRenderTarget>
{
NSView* _view;
NSWindow* _window;
NSOpenGLContext* _context;
public:
FORWARD_IUNKNOWN()
AvnGlRenderTarget(NSWindow* window, NSView*view)
{
_window = window;
_view = view;
_context = GetFeature()->CreateContext();
}
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override
{
auto f = GetFeature();
if(f == NULL)
return E_FAIL;
@try
{
if(![_view lockFocusIfCanDraw])
return E_ABORT;
}
@catch(NSException* exception)
{
return E_ABORT;
}
auto gl = _context;
CGLLockContext([_context CGLContextObj]);
[gl setView: _view];
[gl update];
[gl makeCurrentContext];
*ret = new AvnGlRenderingSession(_window, _view, gl);
return S_OK;
}
};
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view)
{
return new AvnGlRenderTarget(window, view);
}

12
native/Avalonia.Native/src/OSX/main.mm

@ -174,20 +174,20 @@ public:
return (IAvnMacOptions*)new MacOptions();
}
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) override
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) override
{
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnWindow(cb);
*ppv = CreateAvnWindow(cb, gl);
return S_OK;
};
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv) override
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) override
{
if(cb == nullptr || ppv == nullptr)
return E_POINTER;
*ppv = CreateAvnPopup(cb);
*ppv = CreateAvnPopup(cb, gl);
return S_OK;
}
@ -221,9 +221,9 @@ public:
return S_OK;
}
virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) override
virtual HRESULT ObtainGlDisplay(IAvnGlDisplay** ppv) override
{
auto rv = ::GetGlFeature();
auto rv = ::GetGlDisplay();
if(rv == NULL)
return E_FAIL;
rv->AddRef();

284
native/Avalonia.Native/src/OSX/rendertarget.mm

@ -0,0 +1,284 @@
#include "common.h"
#include "rendertarget.h"
#import <IOSurface/IOSurface.h>
#import <IOSurface/IOSurfaceObjC.h>
#include <OpenGL/CGLIOSurface.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/glext.h>
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
@interface IOSurfaceHolder : NSObject
@end
@implementation IOSurfaceHolder
{
@public IOSurfaceRef surface;
@public AvnPixelSize size;
@public float scale;
ComPtr<IAvnGlContext> _context;
GLuint _framebuffer, _texture, _renderbuffer;
}
- (IOSurfaceHolder*) initWithSize: (AvnPixelSize) size
withScale: (float)scale
withOpenGlContext: (IAvnGlContext*) context
{
long bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, size.Width * 4);
long allocSize = IOSurfaceAlignProperty(kIOSurfaceAllocSize, size.Height * bytesPerRow);
NSDictionary* options = @{
(id)kIOSurfaceWidth: @(size.Width),
(id)kIOSurfaceHeight: @(size.Height),
(id)kIOSurfacePixelFormat: @((uint)'BGRA'),
(id)kIOSurfaceBytesPerElement: @(4),
(id)kIOSurfaceBytesPerRow: @(bytesPerRow),
(id)kIOSurfaceAllocSize: @(allocSize),
//(id)kIOSurfaceCacheMode: @(kIOMapWriteCombineCache),
(id)kIOSurfaceElementWidth: @(1),
(id)kIOSurfaceElementHeight: @(1)
};
surface = IOSurfaceCreate((CFDictionaryRef)options);
self->scale = scale;
self->size = size;
self->_context = context;
return self;
}
-(HRESULT) prepareForGlRender
{
if(_context == nil)
return E_FAIL;
if(CGLGetCurrentContext() != _context->GetNativeHandle())
return E_FAIL;
if(_framebuffer == 0)
glGenFramebuffersEXT(1, &_framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _framebuffer);
if(_texture == 0)
{
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
CGLError res = CGLTexImageIOSurface2D((CGLContextObj)_context->GetNativeHandle(),
GL_TEXTURE_RECTANGLE_EXT, GL_RGBA8,
size.Width, size.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
if(res != 0)
{
glDeleteTextures(1, &_texture);
_texture = 0;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return E_FAIL;
}
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, _texture, 0);
}
if(_renderbuffer == 0)
{
glGenRenderbuffers(1, &_renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.Width, size.Height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderbuffer);
}
return S_OK;
}
-(void) finishDraw
{
ComPtr<IUnknown> release;
_context->MakeCurrent(release.getPPV());
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glFlush();
}
-(void) dealloc
{
if(_framebuffer != 0)
{
ComPtr<IUnknown> release;
_context->MakeCurrent(release.getPPV());
glDeleteFramebuffers(1, &_framebuffer);
if(_texture != 0)
glDeleteTextures(1, &_texture);
if(_renderbuffer != 0)
glDeleteRenderbuffers(1, &_renderbuffer);
}
IOSurfaceDecrementUseCount(surface);
}
@end
static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target);
@implementation IOSurfaceRenderTarget
{
CALayer* _layer;
@public IOSurfaceHolder* surface;
@public NSObject* lock;
ComPtr<IAvnGlContext> _glContext;
}
- (IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context;
{
self = [super init];
_glContext = context;
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
|| surface->size.Width != size.Width
|| surface->size.Height != size.Height
|| surface->scale != scale)
surface = [[IOSurfaceHolder alloc] initWithSize:size withScale:scale withOpenGlContext:_glContext.getRaw()];
}
}
- (void)updateLayer {
if ([NSThread isMainThread])
{
@synchronized (lock) {
if(_layer == nil)
return;
[_layer setContents: nil];
if(surface != nil)
{
[_layer setContentsScale: surface->scale];
[_layer setContents: (__bridge IOSurface*) surface->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(surface == nil)
return E_FAIL;
IOSurfaceRef surf = surface->surface;
if(IOSurfaceLock(surf, 0, nil))
return E_FAIL;
size_t w = MIN(fb->Width, IOSurfaceGetWidth(surf));
size_t h = MIN(fb->Height, IOSurfaceGetHeight(surf));
size_t wbytes = w*4;
size_t sstride = IOSurfaceGetBytesPerRow(surf);
size_t fstride = fb->Stride;
char*pSurface = (char*)IOSurfaceGetBaseAddress(surf);
char*pFb = (char*)fb->Data;
for(size_t y = 0; y < h; y++)
{
memcpy(pSurface + y*sstride, pFb + y*fstride, wbytes);
}
IOSurfaceUnlock(surf, 0, nil);
[self updateLayer];
return S_OK;
}
}
-(IAvnGlSurfaceRenderTarget*) createSurfaceRenderTarget
{
return CreateGlRenderTarget(self);
}
@end
class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSession, &IID_IAvnGlSurfaceRenderingSession>
{
ComPtr<IUnknown> _releaseContext;
IOSurfaceRenderTarget* _target;
IOSurfaceHolder* _surface;
public:
FORWARD_IUNKNOWN()
AvnGlRenderingSession(IOSurfaceRenderTarget* target, ComPtr<IUnknown> releaseContext)
{
_target = target;
// This happens in a synchronized block set up by AvnRenderTarget, so we take the current surface for this
// particular render session
_surface = _target->surface;
_releaseContext = releaseContext;
}
virtual HRESULT GetPixelSize(AvnPixelSize* ret) override
{
if(!_surface)
return E_FAIL;
*ret = _surface->size;
return S_OK;
}
virtual HRESULT GetScaling(double* ret) override
{
if(!_surface)
return E_FAIL;
*ret = _surface->scale;
return S_OK;
}
virtual ~AvnGlRenderingSession()
{
[_surface finishDraw];
[_target updateLayer];
_releaseContext = nil;
}
};
class AvnGlRenderTarget : public ComSingleObject<IAvnGlSurfaceRenderTarget, &IID_IAvnGlSurfaceRenderTarget>
{
IOSurfaceRenderTarget* _target;
public:
FORWARD_IUNKNOWN()
AvnGlRenderTarget(IOSurfaceRenderTarget* target)
{
_target = target;
}
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override
{
ComPtr<IUnknown> releaseContext;
@synchronized (_target->lock) {
if(_target->surface == nil)
return E_FAIL;
_target->_glContext->MakeCurrent(releaseContext.getPPV());
HRESULT res = [_target->surface prepareForGlRender];
if(res)
return res;
*ret = new AvnGlRenderingSession(_target, releaseContext);
return S_OK;
}
}
};
static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target)
{
return new AvnGlRenderTarget(target);
}

207
native/Avalonia.Native/src/OSX/window.mm

@ -7,44 +7,9 @@
#include "cursor.h"
#include "menu.h"
#include <OpenGL/gl.h>
#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<IAvnWindowBase, &IID_IAvnWindowBase>, public INSWindowHolder
{
@ -61,15 +26,18 @@ public:
AvnView* View;
AvnWindow* Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents;
SoftwareDrawingOperation CurrentSwDrawingOperation;
ComPtr<IAvnGlContext> _glContext;
NSObject<IRenderTarget>* renderTarget;
AvnPoint lastPositionSet;
NSString* _lastTitle;
IAvnAppMenu* _mainMenu;
WindowBaseImpl(IAvnWindowBaseEvents* events)
WindowBaseImpl(IAvnWindowBaseEvents* events, IAvnGlContext* gl)
{
_mainMenu = nullptr;
BaseEvents = events;
_glContext = gl;
renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: gl];
View = [[AvnView alloc] initWithParent:this];
Window = [[AvnWindow alloc] initWithParent:this];
@ -291,29 +259,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 +353,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
@ -451,8 +386,8 @@ public:
{
if(View == NULL)
return E_FAIL;
*ppv = ::CreateGlRenderTarget(Window, View);
return S_OK;
*ppv = [renderTarget createSurfaceRenderTarget];
return *ppv == nil ? E_FAIL : S_OK;
}
protected:
@ -490,7 +425,7 @@ private:
}
ComPtr<IAvnWindowEvents> WindowEvents;
WindowImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{
WindowEvents = events;
[Window setCanBecomeKeyAndMain];
@ -731,6 +666,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
NSEvent* _lastMouseDownEvent;
bool _lastKeyHandled;
AvnPixelSize _lastPixelSize;
NSObject<IRenderTarget>* _renderTarget;
}
- (void)onClosed
@ -741,19 +677,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
}
}
- (BOOL)lockFocusIfCanDraw
{
@synchronized (self)
{
if(_parent == nullptr)
{
return NO;
}
}
return [super lockFocusIfCanDraw];
}
-(AvnPixelSize) getPixelSize
{
return _lastPixelSize;
@ -764,18 +687,43 @@ 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;
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,87 +771,32 @@ 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();
return;
}
-(void) redrawSelf
- (void)drawRect:(NSRect)dirtyRect
{
@autoreleasepool
{
@synchronized(self)
{
if(!_queuedDisplayFromThread)
return;
_queuedDisplayFromThread = false;
}
[self setNeedsDisplayInRect:[self frame]];
[self display];
}
return;
}
-(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 +821,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];
@ -1478,7 +1371,7 @@ private:
END_INTERFACE_MAP()
virtual ~PopupImpl(){}
ComPtr<IAvnWindowEvents> WindowEvents;
PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
@ -1502,20 +1395,20 @@ protected:
}
};
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events)
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
{
@autoreleasepool
{
IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events));
IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl));
return ptr;
}
}
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl)
{
@autoreleasepool
{
IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl);
return ptr;
}
}

13
src/Avalonia.Controls.DataGrid/Themes/Default.xaml

@ -45,7 +45,7 @@
<Path Name="SortIcon"
Grid.Column="1"
Fill="#FF444444"
Fill="{TemplateBinding Foreground}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Stretch="Uniform"
@ -113,7 +113,7 @@
<Style Selector="DataGridRow /template/ Rectangle#BackgroundRectangle">
<Setter Property="IsVisible" Value="False"/>
<Setter Property="Fill" Value="#FFBADDE9" />
<Setter Property="Fill" Value="{DynamicResource HighlightBrush}" />
</Style>
<Style Selector="DataGridRow:pointerover /template/ Rectangle#BackgroundRectangle">
@ -126,6 +126,10 @@
<Setter Property="Opacity" Value="1"/>
</Style>
<Style Selector="DataGridRow:selected">
<Setter Property="Foreground" Value="{DynamicResource HighlightForegroundBrush}" />
</Style>
<Style Selector="DataGridRowHeader">
<Setter Property="Template">
<ControlTemplate>
@ -139,7 +143,7 @@
</Style>
<Style Selector="DataGridRowGroupHeader">
<Setter Property="Background" Value="#FFE4E8EA" />
<Setter Property="Background" Value="{DynamicResource ThemeControlMidHighBrush}" />
<Setter Property="Height" Value="20"/>
<Setter Property="Template">
<ControlTemplate>
@ -148,7 +152,6 @@
ColumnDefinitions="Auto,Auto,Auto,Auto"
RowDefinitions="Auto,*,Auto">
<Rectangle Grid.Column="1" Grid.ColumnSpan="5" Fill="#FFFFFFFF" Height="1"/>
<Rectangle Grid.Column="1" Grid.Row="1" Name="IndentSpacer" />
<ToggleButton Grid.Column="2" Grid.Row="1" Name="ExpanderButton" Margin="2,0,0,0"/>
@ -169,7 +172,7 @@
<Setter Property="Template">
<ControlTemplate>
<Border Grid.Column="0" Width="20" Height="20" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Fill="Black"
<Path Fill="{TemplateBinding Foreground}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 2 L 4 6 L 0 10 Z" />

2
src/Avalonia.Dialogs/AboutAvaloniaDialog.xaml

@ -99,7 +99,7 @@
</StackPanel>
</StackPanel>
<StackPanel VerticalAlignment="Bottom" Margin="10">
<TextBlock Text="© 2019 The Avalonia Project" TextWrapping="Wrap" HorizontalAlignment="Center" />
<TextBlock Text="© 2020 The Avalonia Project" TextWrapping="Wrap" HorizontalAlignment="Center" />
</StackPanel>
</Grid>
</Window>

42
src/Avalonia.Native/AvaloniaNativeDeferredRendererLock.cs

@ -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();
}
}
}
}

10
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;
@ -17,6 +18,7 @@ namespace Avalonia.Native
{
private readonly IAvaloniaNativeFactory _factory;
private AvaloniaNativePlatformOptions _options;
private GlPlatformFeature _glFeature;
[DllImport("libAvaloniaNative")]
static extern IntPtr CreateAvaloniaNative();
@ -87,7 +89,7 @@ namespace Avalonia.Native
_factory.MacOptions.ShowInDock = macOpts?.ShowInDock != false ? 1 : 0;
}
AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>()
.ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
@ -100,14 +102,16 @@ namespace Avalonia.Native
.Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta))
.Bind<IMountedVolumeInfoProvider>().ToConstant(new MacOSMountedVolumeInfoProvider());
if (_options.UseGpu)
AvaloniaLocator.CurrentMutable.Bind<IWindowingPlatformGlFeature>()
.ToConstant(_glFeature = new GlPlatformFeature(_factory.ObtainGlDisplay()));
}
public IWindowImpl CreateWindow()
{
return new WindowImpl(_factory, _options);
return new WindowImpl(_factory, _options, _glFeature);
}
public IEmbeddableWindowImpl CreateEmbeddableWindow()

2
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; }

31
src/Avalonia.Native/GlPlatformFeature.cs

@ -8,24 +8,31 @@ namespace Avalonia.Native
{
class GlPlatformFeature : IWindowingPlatformGlFeature
{
public GlPlatformFeature(IAvnGlFeature feature)
public GlPlatformFeature(IAvnGlDisplay display)
{
Display = new GlDisplay(feature.ObtainDisplay());
ImmediateContext = new GlContext(Display, feature.ObtainImmediateContext());
var immediate = display.CreateContext(null);
var deferred = display.CreateContext(immediate);
GlDisplay = new GlDisplay(display, immediate.SampleCount, immediate.StencilSize);
ImmediateContext = new GlContext(Display, immediate);
DeferredContext = new GlContext(Display, deferred);
}
public IGlContext ImmediateContext { get; }
public GlDisplay Display { get; }
internal GlContext DeferredContext { get; }
internal GlDisplay GlDisplay;
public GlDisplay Display => GlDisplay;
}
class GlDisplay : IGlDisplay
{
private readonly IAvnGlDisplay _display;
public GlDisplay(IAvnGlDisplay display)
public GlDisplay(IAvnGlDisplay display, int sampleCount, int stencilSize)
{
_display = display;
SampleCount = sampleCount;
StencilSize = stencilSize;
GlInterface = new GlInterface((name, optional) =>
{
var rv = _display.GetProcAddress(name);
@ -39,11 +46,11 @@ namespace Avalonia.Native
public GlInterface GlInterface { get; }
public int SampleCount => _display.GetSampleCount();
public int SampleCount { get; }
public int StencilSize => _display.GetStencilSize();
public int StencilSize { get; }
public void ClearContext() => _display.ClearContext();
public void ClearContext() => _display.LegacyClearCurrentContext();
}
class GlContext : IGlContext
@ -60,7 +67,7 @@ namespace Avalonia.Native
public void MakeCurrent()
{
Context.MakeCurrent();
Context.LegacyMakeCurrent();
}
}
@ -109,6 +116,9 @@ namespace Avalonia.Native
public double Scaling => _session.GetScaling();
public bool IsYFlipped => true;
public void Dispose()
{
_session?.Dispose();
@ -128,5 +138,6 @@ namespace Avalonia.Native
{
return new GlPlatformSurfaceRenderTarget(_window.CreateGlRenderTarget());
}
}
}

12
src/Avalonia.Native/PopupImpl.cs

@ -8,19 +8,23 @@ using Avalonia.Platform;
namespace Avalonia.Native
{
public class PopupImpl : WindowBaseImpl, IPopupImpl
class PopupImpl : WindowBaseImpl, IPopupImpl
{
private readonly IAvaloniaNativeFactory _factory;
private readonly AvaloniaNativePlatformOptions _opts;
private readonly GlPlatformFeature _glFeature;
public PopupImpl(IAvaloniaNativeFactory factory,
AvaloniaNativePlatformOptions opts,
IWindowBaseImpl parent) : base(opts)
GlPlatformFeature glFeature,
IWindowBaseImpl parent) : base(opts, glFeature)
{
_factory = factory;
_opts = opts;
_glFeature = glFeature;
using (var e = new PopupEvents(this))
{
Init(factory.CreatePopup(e), factory.CreateScreens());
Init(factory.CreatePopup(e, _opts.UseGpu ? glFeature?.DeferredContext.Context : null), factory.CreateScreens());
}
PopupPositioner = new ManagedPopupPositioner(new OsxManagedPopupPositionerPopupImplHelper(parent, MoveResize));
}
@ -51,7 +55,7 @@ namespace Avalonia.Native
}
}
public override IPopupImpl CreatePopup() => new PopupImpl(_factory, _opts, this);
public override IPopupImpl CreatePopup() => new PopupImpl(_factory, _opts, _glFeature, this);
public IPopupPositioner PopupPositioner { get; }
}
}

10
src/Avalonia.Native/WindowImpl.cs

@ -14,14 +14,18 @@ namespace Avalonia.Native
{
private readonly IAvaloniaNativeFactory _factory;
private readonly AvaloniaNativePlatformOptions _opts;
private readonly GlPlatformFeature _glFeature;
IAvnWindow _native;
public WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
internal WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts,
GlPlatformFeature glFeature) : base(opts, glFeature)
{
_factory = factory;
_opts = opts;
_glFeature = glFeature;
using (var e = new WindowEvents(this))
{
Init(_native = factory.CreateWindow(e), factory.CreateScreens());
Init(_native = factory.CreateWindow(e,
_opts.UseGpu ? glFeature?.DeferredContext.Context : null), factory.CreateScreens());
}
NativeMenuExporter = new AvaloniaNativeMenuExporter(_native, factory);
@ -113,6 +117,6 @@ namespace Avalonia.Native
public void Move(PixelPoint point) => Position = point;
public override IPopupImpl CreatePopup() =>
_opts.OverlayPopups ? null : new PopupImpl(_factory, _opts, this);
_opts.OverlayPopups ? null : new PopupImpl(_factory, _opts, _glFeature, this);
}
}

63
src/Avalonia.Native/WindowImplBase.cs

@ -60,9 +60,9 @@ namespace Avalonia.Native
private double _savedScaling;
private GlPlatformSurface _glSurface;
public WindowBaseImpl(AvaloniaNativePlatformOptions opts)
internal WindowBaseImpl(AvaloniaNativePlatformOptions opts, GlPlatformFeature glFeature)
{
_gpu = opts.UseGpu;
_gpu = opts.UseGpu && glFeature != null;
_deferredRendering = opts.UseDeferredRendering;
_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
@ -75,8 +75,8 @@ namespace Avalonia.Native
_native = window;
Handle = new MacOSTopLevelWindowHandle(window);
_glSurface = new GlPlatformSurface(window);
if (_gpu)
_glSurface = new GlPlatformSurface(window);
Screen = new ScreenImpl(screens);
_savedLogicalSize = ClientSize;
_savedScaling = Scaling;
@ -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<Rect> 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<IRenderLoop>(),
rendererLock:
_gpu ? new AvaloniaNativeDeferredRendererLock(_native) : null);
return new DeferredRenderer(root, AvaloniaLocator.Current.GetService<IRenderLoop>());
return new ImmediateRenderer(root);
}

1
src/Avalonia.OpenGL/EglGlPlatformSurface.cs

@ -107,6 +107,7 @@ namespace Avalonia.OpenGL
public IGlDisplay Display => _context.Display;
public PixelSize Size => _info.Size;
public double Scaling => _info.Scaling;
public bool IsYFlipped { get; }
}
}
}

1
src/Avalonia.OpenGL/IGlPlatformSurfaceRenderingSession.cs

@ -7,5 +7,6 @@ namespace Avalonia.OpenGL
IGlDisplay Display { get; }
PixelSize Size { get; }
double Scaling { get; }
bool IsYFlipped { get; }
}
}

1
src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs

@ -80,6 +80,7 @@ namespace Avalonia.X11.Glx
public IGlDisplay Display => _context.Display;
public PixelSize Size => _info.Size;
public double Scaling => _info.Scaling;
public bool IsYFlipped { get; }
}
}
}

2
src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs

@ -234,6 +234,8 @@ namespace Avalonia.LinuxFramebuffer.Output
public PixelSize Size => _parent._mode.Resolution;
public double Scaling => _parent.Scaling;
public bool IsYFlipped { get; }
}
public IGlPlatformSurfaceRenderingSession BeginDraw()

2
src/Skia/Avalonia.Skia/GlRenderTarget.cs

@ -54,7 +54,7 @@ namespace Avalonia.Skia
new GRBackendRenderTarget(size.Width, size.Height, disp.SampleCount, disp.StencilSize,
new GRGlFramebufferInfo((uint)fb, GRPixelConfig.Rgba8888.ToGlSizedFormat()));
var surface = SKSurface.Create(_grContext, renderTarget,
GRSurfaceOrigin.BottomLeft,
session.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft,
GRPixelConfig.Rgba8888.ToColorType());
var nfo = new DrawingContextImpl.CreateInfo

1
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -43,6 +43,7 @@ namespace Avalonia.Skia
{
GrContext = GRContext.Create(GRBackend.OpenGL, iface);
}
display.ClearContext();
}
}

Loading…
Cancel
Save