Bug 1403198 - support WR native font handles in blob image. r=jrmuizel
authorLee Salzman <lsalzman@mozilla.com>
Mon, 06 Nov 2017 20:21:25 -0500
changeset 390478 5a38089c03751d5b123b41645167d5858c3a6a5f
parent 390477 8e450204ab2ea252f370020a936c92cc9a90dc7f
child 390479 996440f4c25776f30092caa38051e25d6008faca
push id32830
push userarchaeopteryx@coole-files.de
push dateTue, 07 Nov 2017 10:56:46 +0000
treeherdermozilla-central@923836aebbc3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1403198
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1403198 - support WR native font handles in blob image. r=jrmuizel MozReview-Commit-ID: 1n0z2xNZDxp
gfx/webrender_bindings/Moz2DImageRenderer.cpp
gfx/webrender_bindings/moz.build
gfx/webrender_bindings/src/moz2d_renderer.rs
--- a/gfx/webrender_bindings/Moz2DImageRenderer.cpp
+++ b/gfx/webrender_bindings/Moz2DImageRenderer.cpp
@@ -10,18 +10,23 @@
 #include "mozilla/gfx/InlineTranslator.h"
 #include "mozilla/gfx/RecordedEvent.h"
 #include "WebRenderTypes.h"
 #include "webrender_ffi.h"
 
 #include <iostream>
 #include <unordered_map>
 
-#ifdef MOZ_ENABLE_FREETYPE
+#ifdef XP_MACOSX
+#include "mozilla/gfx/UnscaledFontMac.h"
+#elif defined(XP_WIN)
+#include "mozilla/gfx/UnscaledFontDWrite.h"
+#elif defined(MOZ_ENABLE_FREETYPE)
 #include "mozilla/ThreadLocal.h"
+#include "mozilla/gfx/UnscaledFontFreeType.h"
 #endif
 
 namespace std {
   template <>
     struct hash<mozilla::wr::FontKey>{
       public :
         size_t operator()(const mozilla::wr::FontKey &key ) const
         {
@@ -63,38 +68,63 @@ AddFontData(WrFontKey aKey, const uint8_
     font.mSize = aSize;
     font.mIndex = aIndex;
     font.mVec = wr_add_ref_arc(aVec);
     sFontDataTable[aKey] = font;
   }
 }
 
 void
+AddNativeFontHandle(WrFontKey aKey, void* aHandle, uint32_t aIndex) {
+  auto i = sFontDataTable.find(aKey);
+  if (i == sFontDataTable.end()) {
+    FontTemplate font;
+    font.mData = nullptr;
+    font.mSize = 0;
+    font.mIndex = 0;
+    font.mVec = nullptr;
+#ifdef XP_MACOSX
+    font.mUnscaledFont = new UnscaledFontMac(reinterpret_cast<CGFontRef>(aHandle), true);
+#elif defined(XP_WIN)
+    font.mUnscaledFont = new UnscaledFontDWrite(reinterpret_cast<IDWriteFontFace*>(aHandle), nullptr);
+#elif defined(ANDROID)
+    font.mUnscaledFont = new UnscaledFontFreeType(reinterpret_cast<const char*>(aHandle), aIndex);
+#else
+    font.mUnscaledFont = new UnscaledFontFontconfig(reinterpret_cast<const char*>(aHandle), aIndex);
+#endif
+    sFontDataTable[aKey] = font;
+  }
+}
+
+void
 DeleteFontData(WrFontKey aKey) {
   auto i = sFontDataTable.find(aKey);
   if (i != sFontDataTable.end()) {
-    wr_dec_ref_arc(i->second.mVec);
+    if (i->second.mVec) {
+      wr_dec_ref_arc(i->second.mVec);
+    }
     sFontDataTable.erase(i);
   }
 }
 }
 
 RefPtr<UnscaledFont>
 GetUnscaledFont(Translator *aTranslator, wr::FontKey key) {
   MOZ_ASSERT(sFontDataTable.find(key) != sFontDataTable.end());
   auto &data = sFontDataTable[key];
   if (data.mUnscaledFont) {
     return data.mUnscaledFont;
   }
+  MOZ_ASSERT(data.mData);
   FontType type =
 #ifdef XP_MACOSX
     FontType::MAC;
-#elif XP_WIN
+#elif defined(XP_WIN)
     FontType::DWRITE;
-#elif ANDROID
+#elif defined(ANDROID)
     FontType::FREETYPE;
 #else
     FontType::FONTCONFIG;
 #endif
   // makes a copy of the data
   RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource((uint8_t*)data.mData, data.mSize,
                                                                               aTranslator->GetReferenceDrawTarget()->GetBackendType(),
                                                                               type,
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -43,11 +43,16 @@ if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
     DEFINES['MOZ_ENABLE_D3D10_LAYER'] = True
     EXPORTS.mozilla.webrender += [
         'RenderD3D11TextureHostOGL.h',
     ]
     UNIFIED_SOURCES += [
         'RenderD3D11TextureHostOGL.cpp',
     ]
 
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3'):
+    DEFINES['MOZ_ENABLE_FREETYPE'] = True
+    CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+    CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS']
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/gfx/webrender_bindings/src/moz2d_renderer.rs
+++ b/gfx/webrender_bindings/src/moz2d_renderer.rs
@@ -1,19 +1,29 @@
 #![allow(improper_ctypes)] // this is needed so that rustc doesn't complain about passing the &Arc<Vec> to an extern function
 use webrender_api::*;
 use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb, ArcVecU8};
 use rayon::ThreadPool;
 
 use std::collections::hash_map::{HashMap, Entry};
 use std::mem;
+use std::os::raw::c_void;
 use std::ptr;
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::sync::Arc;
 
+#[cfg(target_os = "windows")]
+use dwrote;
+
+#[cfg(target_os = "macos")]
+use core_foundation::base::TCFType;
+
+#[cfg(not(any(target_os = "macos", target_os = "windows")))]
+use std::ffi::CString;
+
 pub struct Moz2dImageRenderer {
     blob_commands: HashMap<ImageKey, (Arc<BlobImageData>, Option<TileSize>)>,
 
     // The images rendered in the current frame (not kept here between frames)
     rendered_images: HashMap<BlobImageRequest, Option<BlobImageResult>>,
 
     tx: Sender<(BlobImageRequest, BlobImageResult)>,
     rx: Receiver<(BlobImageRequest, BlobImageResult)>,
@@ -99,24 +109,47 @@ impl BlobImageRenderer for Moz2dImageRen
         self.rendered_images.insert(request, None);
 
         let tx = self.tx.clone();
         let descriptor = descriptor.clone();
         let blob = &self.blob_commands[&request.key];
         let tile_size = blob.1;
         let commands = Arc::clone(&blob.0);
 
+        #[cfg(target_os = "windows")]
+        fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
+            let system_fc = dwrote::FontCollection::system();
+            let font = system_fc.get_font_from_descriptor(handle).unwrap();
+            let face = font.create_font_face();
+            unsafe { AddNativeFontHandle(key, face.as_ptr() as *mut c_void, 0) };
+        }
+
+        #[cfg(target_os = "macos")]
+        fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
+            unsafe { AddNativeFontHandle(key, handle.0.as_concrete_TypeRef() as *mut c_void, 0) };
+        }
+
+        #[cfg(not(any(target_os = "macos", target_os = "windows")))]
+        fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
+            let cstr = CString::new(handle.pathname.clone()).unwrap();
+            unsafe { AddNativeFontHandle(key, cstr.as_ptr() as *mut c_void, handle.index) };
+        }
 
         fn process_fonts(mut extra_data: BufReader, resources: &BlobImageResources) {
             let font_count = extra_data.read_usize();
             for _ in 0..font_count {
                 let key = extra_data.read_font_key();
                 let template = resources.get_font_data(key);
-                if let &FontTemplate::Raw(ref data, ref index) = template {
-                    unsafe { AddFontData(key, data.as_ptr(), data.len(), *index, data); }
+                match template {
+                    &FontTemplate::Raw(ref data, ref index) => {
+                        unsafe { AddFontData(key, data.as_ptr(), data.len(), *index, data); }
+                    }
+                    &FontTemplate::Native(ref handle) => {
+                        process_native_font_handle(key, handle);
+                    }
                 }
                 resources.get_font_data(key);
             }
         }
         let index_offset_pos = commands.len()-mem::size_of::<usize>();
 
         let index_offset = to_usize(&commands[index_offset_pos..]);
         {
@@ -194,16 +227,17 @@ impl BlobImageRenderer for Moz2dImageRen
     fn delete_font_instance(&mut self, _key: FontInstanceKey) {
     }
 }
 
 use bindings::WrFontKey;
 extern "C" {
     #[allow(improper_ctypes)]
     fn AddFontData(key: WrFontKey, data: *const u8, size: usize, index: u32, vec: &ArcVecU8);
+    fn AddNativeFontHandle(key: WrFontKey, handle: *mut c_void, index: u32);
     fn DeleteFontData(key: WrFontKey);
 }
 
 impl Moz2dImageRenderer {
     pub fn new(workers: Arc<ThreadPool>) -> Self {
         let (tx, rx) = channel();
         Moz2dImageRenderer {
             blob_commands: HashMap::new(),