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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] Add STB text backend. #44887

Merged
merged 12 commits into from
Aug 23, 2023
Merged

Conversation

bdero
Copy link
Member

@bdero bdero commented Aug 21, 2023

Pull the STB text backend into the engine from impeller-cmake.

Depends on: #44884
Requires buildroot bump: flutter/buildroot#754

Originally authored by @johnoneil in bdero/impeller-cmake#12

Diff: f39f4e9

  • Upgrade past recent text refactors.
  • Engine-fy the style.
  • Switch the rect packer to our new skyline rect packer.
  • Add a TextFrame shaper factory that uses STB's metrics/kerning. Behaves similarly to Skia text blob conversion.
  • Add an Aiks golden.

Screenshot 2023-08-20 at 9 24 25 PM

Screenshot 2023-08-20 at 9 42 53 PM

@bdero
Copy link
Member Author

bdero commented Aug 21, 2023

The golden reproduces the slight alignment issues that @johnoneil showed us, and so we should be able to get it nailed down pretty easily from here.

One thing that's gone is the crunchiness that looked like we were skipping over pixel columns when sampling, but I suspect that's thanks to #40912.

It's hard to see in the screenshot, but some characters have a pixel cut off on right and/or bottom (see the o for example), and sometimes characters are jumping 1 pixel above the baseline.

The cutoff issue appears to be an issue while the glyphs themselves are being rendered to the atlas, since the cutoff is also visible in the atlas. Not sure if the bouncing around the baseline is an issue with the text shaping routine I added (https://github.com/flutter/engine/pull/44887/files#diff-9074fefbe9c66b53a5be2a73f54e7f92ddf6f579889a63df5c8f3fadde62bec6R11-R59) or something else.

@bdero bdero force-pushed the bdero/add-stb-text-backend branch from cc8b996 to 077d879 Compare August 21, 2023 16:40
@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

Changes reported for pull request #44887 at sha 077d879

bool OpenPlaygroundHere(const Picture& picture);
bool OpenPlaygroundHere(const Picture& picture,
std::unique_ptr<TextRenderContext>
text_render_context_override = nullptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as the other patch about making these be shared pointers to text render contexts and having a setter on the fixture itself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


namespace impeller {

class TextRenderContextSTB : public TextRenderContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call these TypographerContexts? Like AiksContext, RendererContext, etc.. That is, the component name is the prefix with Context.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done.

size_t GetSize() const { return width_ * height_ * bytes_per_pixel_; }

private:
size_t width_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere, zero these out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

size_t width_;
size_t height_;
size_t bytes_per_pixel_;
std::unique_ptr<uint8_t[]> pixels_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just std::vector<uint8_t>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Analogous to the bitmaps (one for each type) stored in each Atlas context.
static auto alpha_bitmap =
std::make_shared<STBBitmap>(MIN_GLYPH_ATLAS_SIZE, MIN_GLYPH_ATLAS_SIZE, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere, constants follow the kMinGlyphAtlasSize convention.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed these macros.

MIN_GLYPH_ATLAS_SIZE,
COLOR_FONT_BPP);

static std::shared_ptr<STBBitmap> get_atlas_bitmap(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: PascalCase per style gyide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and elsewhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up removing these along with the globals they're accessing.

// Analogous to the bitmaps (one for each type) stored in each Atlas context.
static auto alpha_bitmap =
std::make_shared<STBBitmap>(MIN_GLYPH_ATLAS_SIZE, MIN_GLYPH_ATLAS_SIZE, 1);
static auto color_bitmap = std::make_shared<STBBitmap>(MIN_GLYPH_ATLAS_SIZE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: gColorBitmap per convention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, I don't think we have static globals elsewhere for objects as large as these. These look like leaks and on engine teardown and are hard to track down. Can we do this API right™?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Yeah, it turns out the GlyphAtlasContext still had an SkBitmap. I suspect that's the reason these were globals.

I reworked it to make backend-specific versions and got rid of the static stuff, so now both backends are storing their bitmap data in the atlas context.


// Function returns the count of "remaining pairs" not packed into rect of given
// size.
static size_t PairsFitInAtlasOfSize(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really need a generic rect packer ready to go in //impeller/core. Can we file an issue for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return true;
}

namespace {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static instead of anonymous namespace

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return texture;
}

std::shared_ptr<GlyphAtlas> TextRenderContextSTB::CreateGlyphAtlas(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a later patch, we can dry this up with the Skia typographer context. Can we file a followup issue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, especially now that these globals aren't floating around. flutter/flutter#133029

@bdero bdero force-pushed the bdero/add-stb-text-backend branch from 2e510ec to c6d7d87 Compare August 22, 2023 17:39
@bdero
Copy link
Member Author

bdero commented Aug 22, 2023

Need to work out a new segfault happening in the tests.

@bdero
Copy link
Member Author

bdero commented Aug 23, 2023

Fixed. :)

Copy link
Member

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not familiar with stb but did my best. Some nits we can address later if need be. But LGTM.

is_valid_(false) {
// We need an "offset" into the ttf file
auto offset = stbtt_GetFontOffsetForIndex(typeface_mapping_->GetMapping(), 0);
if (stbtt_InitFont(font_info_.get(), typeface_mapping_->GetMapping(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a de-init font? Is this a leak?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, it just initializes the stbtt_fontinfo (first param).

Docstring:

// Given an offset into the file that defines a font, this function builds
// the necessary cached info for the rest of the system. You must allocate
// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
// need to do anything special to free it, because the contents are pure
// value data with no additional data structures. Returns 0 on failure.


namespace impeller {

TypefaceSTB::~TypefaceSTB() = default;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dtor after ctor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// This assumes a constant pixels per em.
static constexpr float kPointsToPixels = 96.0 / 72.0;

TypefaceSTB() = delete;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ool this dtor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this because it's already implicitly deleted.

@bdero bdero added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 23, 2023
@bdero bdero merged commit d3172a0 into flutter:main Aug 23, 2023
27 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 23, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 23, 2023
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Aug 23, 2023
…133211)

flutter/engine@58dc868...27d75f6

2023-08-23 skia-flutter-autoroll@skia.org Roll Skia from 76898dad9fda to a631fefdba37 (2 revisions) (flutter/engine#45027)
2023-08-23 zanderso@users.noreply.github.com Revert "FontVariation.lerp, custom FontVariation constructors, and more documentation" (flutter/engine#45023)
2023-08-23 bdero@google.com [Impeller] Dat rvalue reference (fix engine head) (flutter/engine#45024)
2023-08-23 bdero@google.com Revert "Enable clang-tidy for pre-push (opt-out), exclude `performance-unnecessary-value-param`" (flutter/engine#45020)
2023-08-23 skia-flutter-autoroll@skia.org Roll Skia from 4e42b51cfe27 to 76898dad9fda (1 revision) (flutter/engine#45019)
2023-08-23 bdero@google.com [Impeller] Add STB text backend. (flutter/engine#44887)
2023-08-23 reidbaker@google.com Followup to flutter/engine#44982 (flutter/engine#45018)
2023-08-23 skia-flutter-autoroll@skia.org Roll Skia from 5428f147e632 to 4e42b51cfe27 (4 revisions) (flutter/engine#45016)
2023-08-23 reidbaker@google.com Eliminate android test log spam (flutter/engine#44982)
2023-08-23 mdebbar@google.com [web] Remove some unused functions (flutter/engine#44505)
2023-08-23 lhkbob@gmail.com Use decal TileMode in blur image_filter_test.dart (flutter/engine#45004)
2023-08-23 ian@hixie.ch FontVariation.lerp, custom FontVariation constructors, and more documentation (flutter/engine#44996)
2023-08-23 jonahwilliams@google.com [impeller] combine sampler and texture maps. (flutter/engine#44990)
2023-08-23 bdero@google.com [Impeller] Flutter GPU: Add HostBuffer. (flutter/engine#44696)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jimgraham@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
gaaclarke pushed a commit to gaaclarke/engine that referenced this pull request Aug 30, 2023
Pull the STB text backend into the engine from impeller-cmake.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller will affect goldens
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants