-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose bindings to support efficiently authoring ICanvasEffect objects #894
Comments
This was referenced Dec 29, 2022
This was referenced Jan 8, 2023
All proposed features have been approved, implemented, and we just merged the PRs in the internal repo 🎉 |
getrou
pushed a commit
that referenced
this issue
Apr 20, 2023
…tLease APIs > Public tracking issue: #894 This PR implements the `ID2D1DeviceContextPool` APIs. Part of overall improved support for `ICanvasImageInterop`. The new pool is useful whenever a device context is needed but only an `ICanvasDevice` is available. For instance, that can often be the case when `ICanvasImageInterop.GetD2DImage` is called back from Win2D. ### API breakdown The following new APIs are added in this PR (in the public header): ```cpp class __declspec(uuid("A0928F38-F7D5-44DD-A5C9-E23D94734BBB")) ID2D1DeviceContextLease : public IUnknown { public: IFACEMETHOD(GetD2DDeviceContext)(ID2D1DeviceContext** deviceContext) = 0; }; class __declspec(uuid("454A82A1-F024-40DB-BD5B-8F527FD58AD0")) ID2D1DeviceContextPool : public IUnknown { public: IFACEMETHOD(GetDeviceContextLease)(ID2D1DeviceContextLease** lease) = 0; }; ``` ## Additional notes Other than tests here, I've also validated this end-to-end through ComputeSharp.D2D1.Uwp. Integration work for this new APIs into ComputeSharp is in [ComputeSharp/dev/device-context-pool.](https://github.com/Sergio0694/ComputeSharp/tree/dev/device-context-pool).
getrou
pushed a commit
that referenced
this issue
Apr 20, 2023
…implementations > Public tracking issue: #894 This PR implements the new C exports to allow external developers implementing `ICanvasImageInterop` to also properly implement `ICanvasEffect`. This PR includes two main changes: - Refactor the internal `ICanvasEffect` methods to all point to 3 shared stubs. - Implement the 3 new public APIs that also just use those same 3 shared stubs. This allows all these APIs to reuse the same exact implementation within Win2D, and it's just a matter how they're exposed: either as instance methods on the WinRT `ICanvasEffect` API, or as static C exports. ### API breakdown The following new APIs are added in this PR (in the public header): ```cpp // // Exported methods to allow ICanvasImageInterop implementors to implement ICanvasEffect properly. // extern "C" __declspec(nothrow, dllexport) HRESULT __stdcall InvalidateSourceRectangleForICanvasImageInterop( ICanvasResourceCreatorWithDpi* resourceCreator, ICanvasImageInterop* image, uint32_t sourceIndex, Rect const* invalidRectangle); extern "C" __declspec(nothrow, dllexport) HRESULT __stdcall GetInvalidRectanglesForICanvasImageInterop( ICanvasResourceCreatorWithDpi* resourceCreator, ICanvasImageInterop* image, uint32_t* valueCount, Rect** valueElements); extern "C" __declspec(nothrow, dllexport) HRESULT __stdcall GetRequiredSourceRectanglesForICanvasImageInterop( ICanvasResourceCreatorWithDpi* resourceCreator, ICanvasImageInterop* image, Rect const* outputRectangle, uint32_t sourceEffectCount, ICanvasEffect* const* sourceEffects, uint32_t sourceIndexCount, uint32_t const* sourceIndices, uint32_t sourceBoundsCount, Rect const* sourceBounds, uint32_t valueCount, Rect* valueElements); ```
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Background and motivation
The changes in #888 allow developers to implement their own custom
ICanvasImage
objects that can then be used with Win2D to eg. be drawn onto a drawing session. For an example one one such custom effect, see Sergio0694/ComputeSharp#451. Win2D supports all that's needed to make this possible once that PR is merged, but we can take things one step further to also allow developers to efficiently implementICanvasEffect
. This can also lay the foundation to potentially allow these effects to be used in a composition brush in the future, if WinUI 3 allowed externally implemented effects in a graph passed to Compositor.CreateEffectFactory.The issue
Right now, developers already have all the tools they need to implement this interface. But they have no way of efficiently doing so. The crux of the problem is that in order to implement the ICanvasEffect interface, effect authors need access to an ID2D1DeviceContext object. From within any of the
ICanvasEffect
methods, they have the following options:CanvasDevice
from the inputICanvasResourceCreatorWithDpi
object, then get the underlyingID2D1Device
(it can be done by jumping through theICanvasResourceWrapperNative
interface), and then from there callingCreateDeviceContext
. This works, but it's fairly inefficient as creating a device is expensive.CanvasDevice
object.Even ignoring these two points, there's still the other issue that implementing these methods involves some additional work that is error prone, and that Win2D is already doing anyway internally, since it also implements those methods for all built-in effects. So the proposal is to simply expose 3 more C exports to allow developers to simply call back into these and let Win2D do the work for them, by just reusing the already existing internal implementation. These would be supporting methods for
ICanvasImageInterop
.API proposal
Three new APIs will be added to
ABI.Microsoft.Graphics.Canvas
inwinrt/published/Microsoft.Graphics.Canvas.native.h
:There would follow the same pattern as
GetBoundsForICanvasImageInterop
, and they would support authors ofICanvasImageInterop
objects to then also easily implementICanvasEffect
. They'd just implement the WinRT interface and then pass the arguments back into Win2D to perform the computation of the results. Win2D would know how to realizeICanvasImageInterop
objects, so the same logic it uses internally today would apply as well (it'd just be extended to also supportICanvasImageInterop
and not justICanvasImageInternal
).Going further
To support other scenarios as well and generally to give external authors the ability to efficiently access Win2D's device context pool, it would also be useful to expose that in some capacity. One example could be by allowing developers to retrieve a lease for a device context (in much the same way as Win2D does internally), so they could use it and then simply return. Something like:
ID2D1DeviceContextPool
would be added to the set of interfaces thatCanvasDevice
implements. Developers would then be able to justQueryInterface
a device forID2D1DeviceContextPool
, and then get a lease from there. From it, they can retrieve the context, use it, then release the lease once they're done. When the lease is released, it'll automatically return the context into the pool. This would allow for efficiently getting a context whenever one is needed and only a device is available (for instance, fromICanvasImageInterop
, which doesn't always have an available context).I've asked @jkoritzinsky who confirmed this is a relatively common pattern in COM for this scenario, so there's precedent 🙂
The text was updated successfully, but these errors were encountered: