1 module skia.DelegateProxies; 2 3 import std.experimental.logger; 4 import skia.Definitions; 5 import skia.SkiaApi; 6 import skia.SKMatrix; 7 8 import core.memory; 9 import std.functional; 10 import skia.DelegateProxies; 11 12 // delegates 13 14 alias SKBitmapReleaseDelegate = void delegate (void* address, void* context); 15 16 alias SKDataReleaseDelegate = void delegate (void* address, void* context); 17 18 alias SKImageRasterReleaseDelegate = void delegate (void* pixels, void* context); 19 20 alias SKImageTextureReleaseDelegate = void delegate (void* context); 21 22 alias SKSurfaceReleaseDelegate = void delegate (void* address, void* context); 23 24 alias GRGlGetProcDelegate = void* delegate (void* context, string name); 25 26 alias GRGlGetProcedureAddressDelegate = void* delegate (string name); 27 28 alias GRVkGetProcedureAddressDelegate = void* delegate (string name, void* instance, void* device); 29 30 // TODO: Tasks pending completion -@Administrator at 2021-01-18T11:39:32+08:00 31 // 32 // alias SKGlyphPathDelegate = void delegate (SKPath path, SKMatrix matrix); 33 34 35 alias UserDataDelegate = Object delegate(); 36 37 // delegate wrappers 38 39 /** 40 * 41 */ 42 struct DelegateWrapper(T) { 43 T del; 44 45 this(T del) { 46 this.del = del; 47 } 48 49 } 50 51 alias SKBitmapReleaseDelegateWrapper = DelegateWrapper!SKBitmapReleaseDelegate; 52 alias SKDataReleaseDelegateWrapper = DelegateWrapper!SKDataReleaseDelegate; 53 alias GRGlGetProcedureAddressDelegateWrapper = DelegateWrapper!GRGlGetProcedureAddressDelegate; 54 alias GRVkGetProcedureAddressDelegateWrapper = DelegateWrapper!GRVkGetProcedureAddressDelegate; 55 56 57 struct DelegateProxies 58 { 59 // references to the proxy implementations 60 61 static SKBitmapReleaseProxyDelegate SKBitmapReleaseDelegateProxy () { return &SKBitmapReleaseDelegateProxyImplementation; } 62 static SKDataReleaseProxyDelegate SKDataReleaseDelegateProxy () { return &SKDataReleaseDelegateProxyImplementation; } 63 static SKImageRasterReleaseProxyDelegate SKImageRasterReleaseDelegateProxy () { return &SKImageRasterReleaseDelegateProxyImplementation; } 64 static SKImageRasterReleaseProxyDelegate SKImageRasterReleaseDelegateProxyForCoTaskMem () { return &SKImageRasterReleaseDelegateProxyImplementationForCoTaskMem; } 65 static SKImageTextureReleaseProxyDelegate SKImageTextureReleaseDelegateProxy () { return &SKImageTextureReleaseDelegateProxyImplementation; } 66 static SKSurfaceRasterReleaseProxyDelegate SKSurfaceReleaseDelegateProxy () { return &SKSurfaceReleaseDelegateProxyImplementation; } 67 static GRGlGetProcProxyDelegate GRGlGetProcDelegateProxy () { return &GRGlGetProcDelegateProxyImplementation; } 68 static GRVkGetProcProxyDelegate GRVkGetProcDelegateProxy () { return &GRVkGetProcDelegateProxyImplementation; } 69 static SKGlyphPathProxyDelegate SKGlyphPathDelegateProxy () { return &SKGlyphPathDelegateProxyImplementation; } 70 71 // proxy implementations 72 extern(C) private static void SKBitmapReleaseDelegateProxyImplementation (void* address, void* context) 73 { 74 warning("TODO - start"); 75 76 SKBitmapReleaseDelegateWrapper* wrapper = cast(SKBitmapReleaseDelegateWrapper*)context; 77 78 SKBitmapReleaseDelegate del = wrapper.del; 79 if(del !is null) { 80 scope(exit) { 81 // Assuming that the callback is invoked only once, the 82 // added root can be removed again now to allow the GC 83 // to collect it later. 84 GC.removeRoot(context); 85 GC.clrAttr(context, GC.BlkAttr.NO_MOVE); 86 } 87 88 try { 89 del(address, null); 90 } catch(Throwable t) { 91 warning(t); 92 } 93 } 94 95 warning("TODO - done"); 96 // auto del = Get<SKBitmapReleaseDelegate> ((void*)context, out var gch); 97 // try { 98 // del.Invoke ((void*)address, null); 99 // } finally { 100 // gch.Free (); 101 // } 102 } 103 extern(C) private static void SKDataReleaseDelegateProxyImplementation (void* address, void* context) 104 { 105 warning("TODO - start"); 106 107 SKDataReleaseDelegateWrapper* wrapper = cast(SKDataReleaseDelegateWrapper*)context; 108 109 SKDataReleaseDelegate del = wrapper.del; 110 if(del !is null) { 111 scope(exit) { 112 GC.removeRoot(context); 113 GC.clrAttr(context, GC.BlkAttr.NO_MOVE); 114 } 115 116 try { 117 del(address, null); 118 } catch(Throwable t) { 119 warning(t); 120 } 121 } 122 123 warning("TODO - done"); 124 } 125 126 extern(C) private static void SKImageRasterReleaseDelegateProxyImplementationForCoTaskMem (void* pixels, void* context) 127 { 128 warning("TODO"); 129 // Marshal.FreeCoTaskMem ((void*)pixels); 130 } 131 132 extern(C) private static void SKImageRasterReleaseDelegateProxyImplementation (void* pixels, void* context) 133 { 134 warning("TODO"); 135 // auto del = Get<SKImageRasterReleaseDelegate> ((void*)context, out var gch); 136 // try { 137 // del.Invoke ((void*)pixels, null); 138 // } finally { 139 // gch.Free (); 140 // } 141 } 142 143 extern(C) private static void SKImageTextureReleaseDelegateProxyImplementation (void* context) 144 { 145 146 warning("TODO"); 147 148 // auto del = Get<SKImageTextureReleaseDelegate> ((void*)context, out var gch); 149 // try { 150 // del.Invoke (null); 151 // } finally { 152 // gch.Free (); 153 // } 154 } 155 156 extern(C) private static void SKSurfaceReleaseDelegateProxyImplementation (void* address, void* context) 157 { 158 warning("TODO"); 159 // auto del = Get<SKSurfaceReleaseDelegate> ((void*)context, out var gch); 160 // try { 161 // del.Invoke ((void*)address, null); 162 // } finally { 163 // gch.Free (); 164 // } 165 } 166 167 extern(C) private static void* GRGlGetProcDelegateProxyImplementation (void* context, void* name) 168 { 169 warning("TODO"); 170 return null; 171 172 // auto del = Get<GRGlGetProcedureAddressDelegate> ((void*)context, out _); 173 // return del.Invoke (Marshal.PtrToStringAnsi ((void*)name)); 174 } 175 176 extern(C) private static void* GRVkGetProcDelegateProxyImplementation (void* context, void* name, void* instance, void* device) 177 { 178 warning("TODO"); 179 return null; 180 // auto del = Get<GRVkGetProcedureAddressDelegate> ((void*)context, out _); 181 182 // return del.Invoke (Marshal.PtrToStringAnsi ((void*)name), instance, device); 183 } 184 185 extern(C) private static void SKGlyphPathDelegateProxyImplementation (void* pathOrNull, SKMatrix* matrix, void* context) 186 { 187 warning("TODO"); 188 // auto del = Get<SKGlyphPathDelegate> ((void*)context, out _); 189 // auto path = SKPath.GetObject (pathOrNull, false); 190 // del.Invoke (path, *matrix); 191 } 192 193 194 static T Create(T) (T nativeDel, void* context) 195 { 196 if (context is null) { 197 return T.init; 198 } 199 200 // Make sure that it is not collected even if it is no 201 // longer referenced from D code (stack, GC heap, …). 202 GC.addRoot(cast(void*)context); 203 204 // Also ensure that a moving collector does not relocate 205 // the object. 206 GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE); 207 208 // gch = GCHandle.Alloc (managedDel); 209 // GCHandle.ToIntPtr (gch); 210 return nativeDel; 211 } 212 213 // static void Create (T nativeDel, void* context) 214 // { 215 // if (context is null) { 216 // return T.init; 217 // } 218 219 // // Make sure that it is not collected even if it is no 220 // // longer referenced from D code (stack, GC heap, …). 221 // GC.addRoot(cast(void*)context); 222 223 // // Also ensure that a moving collector does not relocate 224 // // the object. 225 // GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE); 226 227 // // gch = GCHandle.Alloc (managedDel); 228 // // GCHandle.ToIntPtr (gch); 229 // return nativeDel; 230 // } 231 232 // user data delegates 233 234 // static void* CreateUserData (Object userData, bool makeWeak = false) 235 // { 236 // UserDataDelegate del = () { return userData; } ; 237 238 // void* ctx ; 239 // Create (del, out _, ctx); 240 // return ctx; 241 // } 242 }