Skip to content

Instantly share code, notes, and snippets.

@sbrki
Last active July 24, 2024 16:58
Show Gist options
  • Save sbrki/efe8b94444946bde1bd3fa241071c8b2 to your computer and use it in GitHub Desktop.
Save sbrki/efe8b94444946bde1bd3fa241071c8b2 to your computer and use it in GitHub Desktop.

GSoC 2018. -- Improve Core Animation implementation and integrate it into AppKit (GNU/GNUstep)

1. Project goals (taken from proposal)

Although GNUstep has an implementation of both AppKit and CoreAnimation, they are not integrated. The goal of the project would be to allow AppKit’s views to draw into Core Animation layers, and therefore to be better animatable.

The main goal would be to implement automatic creation of CALayer tree from the existing NSView tree, as well as to implement creation of a CARenderer and OpenGL view in the appropriate place.

2. Project status

Unfortunately I have not managed to completely finish the project due to a mysterious bug somewhere in Opal (more on that later).

2.1 Finished tasks

  • Created new class GSCAData which holds data neccesarry to implement core animation methods on NSView instances
  • Implement setWantsLayer, getWantsLayer, makeBackingLayer
  • Implement GNUstep specific methods: _gsAddCARenderer, _gsRemoveCARenderer, _gsCreateOpenGLContext, _gsSetOpenGLContext

With all of the above methods implemented, you can currently create a CALayer tree that backs the NSView subtree of the initial instance that recieved setWantsLayer(YES).

You can also attach/remove a CARenderer instance to the NSView in question.

This system was proven to work when I managed to draw some custom graphics into a CALayer instance, which is then drawn into a NSView-managed OpenGL context.

The issues started when I wanted to get the actual NSView contents drawn into its corresponding CALayer (instead of some custom graphics).

With graphicsContextWithCGContext:flipped: method I did manage to "convert" the Core Graphics context which CALayer is provided with to a NSGraphicsContext in which NSViewcan draw its contents with a call to displayRectIgnoringOpacity:inContext: method.

However, it simply doesn't draw. I've spent last couple of weeks trying to find the cause of this. My mentors Ivan and Fred helped a lot, but we have had no success.

2.2 The bug that prevents the drawing

The issue is present during a call to displaIgnoringOpacity:inContext: method on NSView. All the code in that method works correctly. All the contexts that are eventually passed to it are being used correctly. The issue may be that something is "reseting" the global context to the context of the window, thus rendering in the wrong place. The issue was followed back to the DPSrectfill function inside of the Opal backend, where it finally draws into the wrong context.

After hours and hours of staring in gdb, the cause of this issue is still not clear.

2.3 Unfinished tasks

Currently the project sits at ~80% completion. If the stated bug gets fixed, it is just a couple of days work to finish the project.

It remains to implement automatic creation of CARenderer instance in the right place, and to handle/synchronise the CALayer tree if the NSView tree changes after the initial call to setWantsLayer:YES.

3. Additional info

The project currently lives as a folder in the libs-quartzcore library.

Some of the work that didn't make it can be found in my fork.

Spreadsheet containing commits

If you wish to, you can download the .tar.gz archive of the project files here (from my fork).

You can also read my blog posts which contain more technical details and can be found here.

@ethanc8
Copy link

ethanc8 commented Jul 24, 2024

@sbrki Do you have your blog posts? It looks like your blog is no longer accessible, and I might want to look into finishing up the CAAppKitBridge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment