Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC: Initial tests regarding Skia #8558

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

misl6
Copy link
Member

@misl6 misl6 commented Jan 11, 2024

Maintainer merge checklist

  • Title is descriptive/clear for inclusion in release notes.
  • Applied a Component: xxx label.
  • Applied the api-deprecation or api-break label.
  • Applied the release-highlight label to be highlighted in release notes.
  • Added to the milestone version it was merged into.
  • Unittests are included in PR.
  • Properly documented, including versionadded, versionchanged as needed.

Skia is a popular 2D graphics library which provides common APIs that work across a variety of hardware and software platforms.

As an example, it serves as the graphics engine for Google Chrome and many other products.

Even if the first tests solely focused on the SkParagraph feature, that will simplify and fix a ton of long-standing issues regarding text rendering (RTL, font fallback, BiDi, proper alignment, ...) if merged in Kivy, Skia could also be an opportunity to introduce other nice features (like a Lottie player, via SKottie).

In simple words: From the first tests, Skia is what we were waiting for. A long restructuring and renaming for 3.0.0 series will be needed, and that's the proper time to introduce Skia in our codebase.

With Skia we can easily render into an OpenGL texture and OpenGL FBO (and looks ANGLE is supported for #8534).

This code is absolutely not intended to be merged as-is, but it's more like an handover to bi0noid, so I can focus on other things. (being an admin, Roadmap, ... etc).

IMPORTANT:

  • Needs Skia dynamic libraries to be built externally, and in the correct folder (check setup.py). I will work on a tool similar to https://github.com/kivy/angle-builder to automagically handle all the builds. (The macOS one, have a visibility issue, that will be reported to Skia team).

Sketchy example code:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.clock import Clock

from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle

from kivy.properties import StringProperty, ObjectProperty

from kivy.core.text.text_skia import TextSkia


class SkiaTextWidget(Widget):
    text = StringProperty("")
    tex = ObjectProperty(None)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._prepare_texture()

    def on_text(self, *args):
        self._skia_render()

    def on_size(self, *args):
        self._prepare_texture()

    def _prepare_texture(self):
        print("recreating texture, size:", self.size)
        self.tex = Texture.create(size=self.size, colorfmt="rgba")
        self.tex.flip_vertical()
        self.tex.bind()

        self._skia_render()

    def _skia_render(self, tex=None):
        self.skia_text_render = TextSkia(
            self.tex.id, self.tex.size[0], self.tex.size[1]
        )
        self.skia_text_render.render(self.text, 0, "font_name", "fg_color")

        self.canvas.clear()
        with self.canvas:
            Rectangle(size=self.tex.size, texture=self.tex)


class NewTextLayoutApp(App):
    def build(self):
        self.skia_text_wid = SkiaTextWidget()

        self.lorem_ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue."
        self.mix_lorem_ipsum_and_emoji = "Lorem 馃帀 ipsum 馃審 dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec 馃帀 consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue."

        Clock.schedule_interval(self._update_skia_text, 1)

        return self.skia_text_wid

    def _update_skia_text(self, dt):
        if self.skia_text_wid.text == self.lorem_ipsum:
            self.skia_text_wid.text = self.mix_lorem_ipsum_and_emoji
        else:
            self.skia_text_wid.text = self.lorem_ipsum


if __name__ == "__main__":
    NewTextLayoutApp().run()

Current output:

Screen.Recording.2024-01-11.at.13.37.36.mov

@HeaTTheatR
Copy link

Skia is the engine for the Flutter framework. Does this mean that Kivy will run on this engine in the future?

@baseplate-admin
Copy link
Contributor

Yep i think kivy is moving into that future

@misl6
Copy link
Member Author

misl6 commented Jan 11, 2024

Skia is also used by Flutter (and it makes sense since both are backed by Google).

And Skia is not flutter-engine, but the 2D graphics library used by them.

We're still evaluating it, but that looks like the best option at the moment.

BTW Kivy will keep its core provider strategy, so Skia will be just one (and likely the default) core provider for specific scenarios.

@Samael-TLB
Copy link
Contributor

Just trying to bring some attention to some information... Flutter in its latest releases is moving away from Skia to their own rewritten graphics engine impeller due to several issues and performance constraints with Skia. So may be we need to take that into account too before having significant investment is Skia... though we can always have it as one of the supported core providers as suggested by @misl6

@Samael-TLB
Copy link
Contributor

Samael-TLB commented Jan 11, 2024

BTW Kivy will keep its core provider strategy, so Skia will be just one (and likely the default) core provider for specific scenarios.

Do you mean by default we will be moving away from SDL2/3 and be on Skia or it will be SDL2/3 and angle and for some specific things like text the default will be Skia?

@misl6
Copy link
Member Author

misl6 commented Jan 11, 2024

Just trying to bring some attention to some information... Flutter in its latest releases is moving away from Skia to their own rewritten graphics engine impeller due to several issues and performance constraints with Skia. So may be we need to take that into account too before having significant investment is Skia... though we can always have it as one of the supported core providers as suggested by @misl6

As said on Discord, not for our (first) use case, cause:

However, while Impeller still performs text rendering, text layout and shaping needs to be done by a separate component. This component happens to be SkParagraph which is part of Skia.

And SkParagraph is the major reason that made us to test Skia

@misl6
Copy link
Member Author

misl6 commented Jan 11, 2024

BTW Kivy will keep its core provider strategy, so Skia will be just one (and likely the default) core provider for specific scenarios.

Do you mean by default we will be moving away from SDL2/3 and be on Skia or it will be SDL2/3 and angle and for some specific things like text the default will be Skia?

ATM we do not have plans to move away from SDL2/SDL3 as a Window provider, as Skia (as a 2D graphics library) is not a replacement for that.

@tito
Copy link
Member

tito commented Jan 11, 2024

Came here to say this is awesome road. Skia has been a lot used for inspiration at the starts, and always wanted to use it !

@Samael-TLB
Copy link
Contributor

Came here to say this is awesome road. Skia has been a lot used for inspiration at the starts, and always wanted to use it !

We shall have a lot of opportunities to incorporate in kivy. Great initiative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants