|
|
Created:
4 years, 6 months ago by drott Modified:
4 years, 5 months ago CC:
ajuma+watch_chromium.org, blink-reviews, blink-reviews-platform-graphics_chromium.org, Rik, chromium-reviews, danakj+watch_chromium.org, dshwang, drott+blinkwatch_chromium.org, krit, jbroman, Justin Novosad, pdr+graphicswatchlist_chromium.org, rwlbuis, Stephen Chennney Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionZero-copy font table access for HarfBuzz
Our previous implementation relied on the copy function
harfBuzzSkiaGetTable() to create a font table copy, which is held by
hb_face_t and hb_font_t in turn. This allocation is additional overhead
in terms of memory consumption and allocation cost.
Using Skia's openStream() API we can retrieve the SkStreamAsset for the
SkTypeface. On desktop Linux, on Android and on Windows my
experimentation shows that this SkStreamAsset is available from memory
most of the time and calling getMemoryBase() returns a valid
address. The openStream() call itself duplicates and SkStream
internally, but does not duplicate the underlying in-memory data.
From The SkStreamAsset we can wrap the font data into an hb_blob_t for
consumption by hb_face_create. openStream() transfers ownerships of the
returned SkStreaAsset to the caller, so we have to specifiy a
destruction function to HarfBuzz when hb_face_t releases the hb_blob_t.
This CL saves all time and space for additional table allocations
required for text shaping, which can range from a few kilobytes for a
set of Latin fonts to hundreds of kilobytes for multiple fonts with
large tables accessed by HarfBuzz.
BUG=621878
Committed: https://crrev.com/264e1435dc66fbc7029d5472f334d185d70aea49
Cr-Commit-Position: refs/heads/master@{#402262}
Patch Set 1 #Patch Set 2 : Mac compile fix #Patch Set 3 : Fix leaking hb_blob_t #Patch Set 4 : Simplify fallback case #
Total comments: 4
Patch Set 5 : Do not oversimplify fallback case #
Total comments: 1
Patch Set 6 : Transfer ttc index to HB #Messages
Total messages: 49 (19 generated)
The CQ bit was checked by drott@chromium.org to run a CQ dry run
Mac compile fix
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2080243002/20001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_asan_rel_ng on tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
Fix leaking hb_blob_t
The CQ bit was checked by drott@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2080243002/40001
Description was changed from ========== Access font tables in memory BUG= ========== to ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is always accessible in memory, since the getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ==========
drott@chromium.org changed reviewers: + behdad@chromium.org, bungeman@chromium.org, eae@chromium.org, fmalita@chromium.org, tzik@chromium.org
This is ready for review now, although I need to work out and discuss with Behdad the two glyph choice failures on Windows. It might only be trybot flakiness.
Simplify fallback case
The CQ bit was checked by drott@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2080243002/60001
LGTM Awesome!
Description was changed from ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is always accessible in memory, since the getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ========== to ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ==========
Thank you! I'd like to hear an opinion from the Skia team as well, thanks in advance for taking a look, fmalita@ or bungeman@.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_asan_rel_ng on tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
kulshin@chromium.org changed reviewers: + kulshin@chromium.org
https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp (right): https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:334: reinterpret_cast<const char*>(typefaceStream->getMemoryBase()), I'm not familiar with how harfbuzz handles object lifetime, but I wanted to point out that the pointer returned from getMemoryBase is only valid as long as the underlying SkDWriteFontFileStream remains alive. If there's any chance that memory might be used after the SkStreamAsset is destroyed, it's worth doublechecking. https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:344: face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platformData->typeface(), 0); Doesn't this always overwrite |face| and ignore the result of the new code?
Do not oversimplify fallback case
On 2016/06/21 at 15:43:42, kulshin wrote: > https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... > File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp (right): > > https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... > third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:334: reinterpret_cast<const char*>(typefaceStream->getMemoryBase()), > I'm not familiar with how harfbuzz handles object lifetime, but I wanted to point out that the pointer returned from getMemoryBase is only valid as long as the underlying SkDWriteFontFileStream remains alive. If there's any chance that memory might be used after the SkStreamAsset is destroyed, it's worth doublechecking. > > https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... > third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:344: face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platformData->typeface(), 0); > Doesn't this always overwrite |face| and ignore the result of the new code?
Thanks for the review, Ilya. https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp (right): https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:334: reinterpret_cast<const char*>(typefaceStream->getMemoryBase()), On 2016/06/21 at 15:43:42, Ilya Kulshin wrote: > I'm not familiar with how harfbuzz handles object lifetime, but I wanted to point out that the pointer returned from getMemoryBase is only valid as long as the underlying SkDWriteFontFileStream remains alive. If there's any chance that memory might be used after the SkStreamAsset is destroyed, it's worth doublechecking. Thanks for pointing that out. The hb_face_create() call references the hb_blobt_t and keeps it alive until the hb_face_t itself gets destroyed. Then, the destruction function deleteTypeFaceStream is called, which destroys the SkStreamAsset. So the lifetime of the SkStreamAsset is coupled to the hb_face_t. So, as long as we have a FontPlatformData (with an SkTypeface member) we have a HarfBuzzFace, which has the hb_font_t, which keeps the hb_face_t. So, it looks to me like the lifecycle of the SkStreamAsset is sound. https://codereview.chromium.org/2080243002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:344: face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platformData->typeface(), 0); On 2016/06/21 at 15:43:42, Ilya Kulshin wrote: > Doesn't this always overwrite |face| and ignore the result of the new code? Oups, yes, my bad. There was an "if (face)" in my first version and I "simplified" that away.
The CQ bit was checked by drott@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2080243002/80001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: win_chromium_rel_ng on tryserver.chromium.win (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.win/builders/win_chromium_rel_...)
lgtm
https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp (right): https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:340: face = hb_face_create(faceBlob.get(), 0); Instead of 0, you need the TTC index of the face. Does Skia have that readily?
On 2016/06/23 at 13:27:37, behdad wrote: > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp (right): > > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:340: face = hb_face_create(faceBlob.get(), 0); > Instead of 0, you need the TTC index of the face. Does Skia have that readily? The parameter to open stream is an out parameter. More correctly, i should specify a nullptr there since we're not interested in it, but: * If ttcIndex is not null, it is set to the TrueTypeCollection index * of this typeface within the stream, or 0 if the stream is not a * collection. So it might still be somehow related to ttc's but specifying an argument is not the fix. Ilya, any other idea why we see failures on Windows? "Cambria Math" (used in the SVG test) is indeed a .ttc.
Description was changed from ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ========== to ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ==========
fmalita@chromium.org changed reviewers: + reed@google.com
On 2016/06/27 08:59:28, drott wrote: > On 2016/06/23 at 13:27:37, behdad wrote: > > > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > > File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp > (right): > > > > > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > > third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:340: face = > hb_face_create(faceBlob.get(), 0); > > Instead of 0, you need the TTC index of the face. Does Skia have that > readily? > > The parameter to open stream is an out parameter. More correctly, i should > specify a nullptr there since we're not interested in it, but: > > * If ttcIndex is not null, it is set to the TrueTypeCollection index > * of this typeface within the stream, or 0 if the stream is not a > * collection. I'm not very familiar with either API, but SkTypeface::openStream() returns a TTC index, and hb_face_create() wants one - don't we just need to pass the former to the latter? I.e. int ttcIndex; SkStreamAsset* typefaceStream = typeface->openStream(&ttcIndex); ... face = hb_face_create(faceBlob.get(), ttcIndex);
On 2016/06/27 at 13:35:12, fmalita wrote: > On 2016/06/27 08:59:28, drott wrote: > > On 2016/06/23 at 13:27:37, behdad wrote: > > > > > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > > > File third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp > > (right): > > > > > > > > https://codereview.chromium.org/2080243002/diff/80001/third_party/WebKit/Sour... > > > third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp:340: face = > > hb_face_create(faceBlob.get(), 0); > > > Instead of 0, you need the TTC index of the face. Does Skia have that > > readily? > > > > The parameter to open stream is an out parameter. More correctly, i should > > specify a nullptr there since we're not interested in it, but: > > > > * If ttcIndex is not null, it is set to the TrueTypeCollection index > > * of this typeface within the stream, or 0 if the stream is not a > > * collection. > > I'm not very familiar with either API, but SkTypeface::openStream() returns a TTC index, and hb_face_create() wants one - don't we just need to pass the former to the latter? I.e. > > int ttcIndex; > SkStreamAsset* typefaceStream = typeface->openStream(&ttcIndex); > ... > face = hb_face_create(faceBlob.get(), ttcIndex); Ugh, yes, that is probably it, thank you! Disregard my previous comment, I blame it on post midsummer Monday morning sleepiness. I'll try with what you're suggesting. It makes a lot more sense.
Transfer ttc index to HB
The CQ bit was checked by drott@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
lgtm w ttc fix.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by drott@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from eae@chromium.org, kulshin@chromium.org Link to the patchset: https://codereview.chromium.org/2080243002/#ps100001 (title: "Transfer ttc index to HB")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ========== to ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ==========
Message was sent while issue was closed.
Committed patchset #6 (id:100001)
Message was sent while issue was closed.
Description was changed from ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 ========== to ========== Zero-copy font table access for HarfBuzz Our previous implementation relied on the copy function harfBuzzSkiaGetTable() to create a font table copy, which is held by hb_face_t and hb_font_t in turn. This allocation is additional overhead in terms of memory consumption and allocation cost. Using Skia's openStream() API we can retrieve the SkStreamAsset for the SkTypeface. On desktop Linux, on Android and on Windows my experimentation shows that this SkStreamAsset is available from memory most of the time and calling getMemoryBase() returns a valid address. The openStream() call itself duplicates and SkStream internally, but does not duplicate the underlying in-memory data. From The SkStreamAsset we can wrap the font data into an hb_blob_t for consumption by hb_face_create. openStream() transfers ownerships of the returned SkStreaAsset to the caller, so we have to specifiy a destruction function to HarfBuzz when hb_face_t releases the hb_blob_t. This CL saves all time and space for additional table allocations required for text shaping, which can range from a few kilobytes for a set of Latin fonts to hundreds of kilobytes for multiple fonts with large tables accessed by HarfBuzz. BUG=621878 Committed: https://crrev.com/264e1435dc66fbc7029d5472f334d185d70aea49 Cr-Commit-Position: refs/heads/master@{#402262} ==========
Message was sent while issue was closed.
Patchset 6 (id:??) landed as https://crrev.com/264e1435dc66fbc7029d5472f334d185d70aea49 Cr-Commit-Position: refs/heads/master@{#402262}
Message was sent while issue was closed.
On 2016/06/27 at 20:01:09, commit-bot wrote: > Committed patchset #6 (id:100001) Great! Thanks for your help, fmalita@ and behdad@. |