Bug 1339683 - Utility function to create WebRenderCommands from Glyphs. r=mchang draft
authorMorris Tseng <mtseng@mozilla.com>
Wed, 15 Feb 2017 14:05:49 +0800
changeset 485768 c0ec82d8ef3e1ac825c36be8bb4927bb6be04aa8
parent 485767 b15dd9820922fa9b6ca33adaa4729886e9c5b3f6
child 485769 9793319f4082e4eacfb35de2f332d26c3adf1aea
push id45837
push userbmo:mtseng@mozilla.com
push dateFri, 17 Feb 2017 04:14:52 +0000
reviewersmchang
bugs1339683
milestone54.0a1
Bug 1339683 - Utility function to create WebRenderCommands from Glyphs. r=mchang MozReview-Commit-ID: 7p8LkxE3QYn
gfx/layers/wr/WebRenderTextLayer.cpp
gfx/layers/wr/WebRenderTextLayer.h
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
--- a/gfx/layers/wr/WebRenderTextLayer.cpp
+++ b/gfx/layers/wr/WebRenderTextLayer.cpp
@@ -10,82 +10,38 @@
 
 #include "mozilla/gfx/2D.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
-static void
-WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
-                  float aGlyphSize, uint32_t aVariationCount,
-                  const ScaledFont::VariationSetting* aVariations, void* aBaton)
-{
-    WebRenderTextLayer* layer = static_cast<WebRenderTextLayer*>(aBaton);
-
-    uint8_t* fontData = (uint8_t*)malloc(aLength * sizeof(uint8_t));
-    memcpy(fontData, aData, aLength * sizeof(uint8_t));
-
-    layer->mFontData = fontData;
-    layer->mFontDataLength = aLength;
-    layer->mIndex = aIndex;
-    layer->mGlyphSize = aGlyphSize;
-}
-
 void
 WebRenderTextLayer::RenderLayer()
 {
     if (mBounds.IsEmpty()) {
         return;
     }
 
     gfx::Rect rect = RelativeToParent(GetTransform().TransformBounds(IntRectToRect(mBounds)));
     gfx::Rect clip;
     if (GetClipRect().isSome()) {
       clip = RelativeToParent(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
     } else {
       clip = rect;
     }
 
-    MOZ_ASSERT((mFont->GetType() == FontType::DWRITE) ||
-                (mFont->GetType() == FontType::MAC));
-    mFont->GetFontFileData(&WriteFontFileData, this);
-    wr::ByteBuffer fontBuffer(mFontDataLength, mFontData);
-
-    nsTArray<WrGlyphArray> wr_glyphs;
-    wr_glyphs.SetLength(mGlyphs.Length());
-
-    for (size_t i = 0; i < mGlyphs.Length(); i++) {
-        GlyphArray glyph_array = mGlyphs[i];
-        nsTArray<Glyph>& glyphs = glyph_array.glyphs();
-
-        nsTArray<WrGlyphInstance>& wr_glyph_instances = wr_glyphs[i].glyphs;
-        wr_glyph_instances.SetLength(glyphs.Length());
-        wr_glyphs[i].color = glyph_array.color().value();
-
-        for (size_t j = 0; j < glyphs.Length(); j++) {
-            wr_glyph_instances[j].index = glyphs[j].mIndex;
-            wr_glyph_instances[j].x = glyphs[j].mPosition.x;
-            wr_glyph_instances[j].y = glyphs[j].mPosition.y;
-        }
-    }
-
     if (gfxPrefs::LayersDump()) {
         printf_stderr("TextLayer %p using rect=%s, clip=%s\n",
                       this->GetLayer(),
                       Stringify(rect).c_str(),
                       Stringify(clip).c_str());
     }
 
-    WrBridge()->AddWebRenderCommand(OpDPPushText(
-        wr::ToWrRect(rect),
-        wr::ToWrRect(clip),
-        wr_glyphs,
-        mIndex,
-        mGlyphSize,
-        fontBuffer,
-        mFontDataLength
-    ));
+    nsTArray<WebRenderCommand> commands;
+    mGlyphHelper.BuildWebRenderCommands(commands, mGlyphs, mFont,
+                                        GetOffsetToParent(), rect, clip);
+    WrBridge()->AddWebRenderCommands(commands);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderTextLayer.h
+++ b/gfx/layers/wr/WebRenderTextLayer.h
@@ -2,50 +2,42 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef GFX_WEBRENDERTEXTLAYER_H
 #define GFX_WEBRENDERTEXTLAYER_H
 
+#include "gfxUtils.h"
 #include "Layers.h"
 #include "WebRenderLayerManager.h"
 
 namespace mozilla {
 namespace layers {
 
 class WebRenderTextLayer : public WebRenderLayer,
                            public TextLayer {
 public:
     explicit WebRenderTextLayer(WebRenderLayerManager* aLayerManager)
         : TextLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
-        , mFontData(nullptr)
-        , mFontDataLength(0)
-        , mIndex(0)
-        , mGlyphSize(0.0)
     {
         MOZ_COUNT_CTOR(WebRenderTextLayer);
     }
 
 protected:
     virtual ~WebRenderTextLayer()
     {
         MOZ_COUNT_DTOR(WebRenderTextLayer);
-        if (mFontData) {
-            free(mFontData);
-        }
     }
 
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer() override;
 
-  uint8_t* mFontData;
-  uint32_t mFontDataLength;
-  uint32_t mIndex;
-  float mGlyphSize;
+protected:
+  gfx::WebRenderGlyphHelper mGlyphHelper;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERTEXTLAYER_H
\ No newline at end of file
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -16,20 +16,22 @@
 #include "mozilla/dom/ImageEncoder.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/gfx/Swizzle.h"
+#include "mozilla/layers/WebRenderMessages.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/Vector.h"
+#include "mozilla/webrender/WebRenderTypes.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIClipboardHelper.h"
 #include "nsIFile.h"
 #include "nsIGfxInfo.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRegion.h"
 #include "nsServiceManagerUtils.h"
@@ -1434,10 +1436,70 @@ Color ToDeviceColor(Color aColor)
   return aColor;
 }
 
 Color ToDeviceColor(nscolor aColor)
 {
   return ToDeviceColor(Color::FromABGR(aColor));
 }
 
+static void
+WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
+                  float aGlyphSize, uint32_t aVariationCount,
+                  const ScaledFont::VariationSetting* aVariations, void* aBaton)
+{
+  WebRenderGlyphHelper* helper = static_cast<WebRenderGlyphHelper*>(aBaton);
+
+  uint8_t* fontData = (uint8_t*)malloc(aLength * sizeof(uint8_t));
+  memcpy(fontData, aData, aLength * sizeof(uint8_t));
+
+  helper->mFontData = fontData;
+  helper->mFontDataLength = aLength;
+  helper->mIndex = aIndex;
+  helper->mGlyphSize = aGlyphSize;
+}
+
+void
+WebRenderGlyphHelper::BuildWebRenderCommands(nsTArray<WebRenderCommand>& aCommands,
+                                             const nsTArray<GlyphArray>& aGlyphs,
+                                             ScaledFont* aFont,
+                                             const Point& aOffset,
+                                             const Rect& aBounds,
+                                             const Rect& aClip)
+{
+  MOZ_ASSERT(aFont);
+  MOZ_ASSERT(!aGlyphs.IsEmpty());
+  MOZ_ASSERT((aFont->GetType() == gfx::FontType::DWRITE) ||
+              (aFont->GetType() == gfx::FontType::MAC));
+
+  aFont->GetFontFileData(&WriteFontFileData, this);
+  wr::ByteBuffer fontBuffer(mFontDataLength, mFontData);
+
+  nsTArray<WrGlyphArray> wr_glyphs;
+  wr_glyphs.SetLength(aGlyphs.Length());
+
+  for (size_t i = 0; i < aGlyphs.Length(); i++) {
+    GlyphArray glyph_array = aGlyphs[i];
+    nsTArray<gfx::Glyph>& glyphs = glyph_array.glyphs();
+
+    nsTArray<WrGlyphInstance>& wr_glyph_instances = wr_glyphs[i].glyphs;
+    wr_glyph_instances.SetLength(glyphs.Length());
+    wr_glyphs[i].color = glyph_array.color().value();
+
+    for (size_t j = 0; j < glyphs.Length(); j++) {
+      wr_glyph_instances[j].index = glyphs[j].mIndex;
+      wr_glyph_instances[j].x = glyphs[j].mPosition.x - aOffset.x;
+      wr_glyph_instances[j].y = glyphs[j].mPosition.y - aOffset.y;
+    }
+  }
+
+  aCommands.AppendElement(OpDPPushText(
+                            wr::ToWrRect(aBounds),
+                            wr::ToWrRect(aClip),
+                            wr_glyphs,
+                            mIndex,
+                            mGlyphSize,
+                            fontBuffer,
+                            mFontDataLength));
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -21,17 +21,19 @@
 class gfxASurface;
 class gfxDrawable;
 class nsIInputStream;
 class nsIGfxInfo;
 class nsIPresShell;
 
 namespace mozilla {
 namespace layers {
+class GlyphArray;
 struct PlanarYCbCrData;
+class WebRenderCommand;
 } // namespace layers
 namespace image {
 class ImageRegion;
 } // namespace image
 } // namespace mozilla
 
 class gfxUtils {
 public:
@@ -301,12 +303,43 @@ static inline CheckedInt<uint32_t>
 SafeBytesForBitmap(uint32_t aWidth, uint32_t aHeight, unsigned aBytesPerPixel)
 {
   MOZ_ASSERT(aBytesPerPixel > 0);
   CheckedInt<uint32_t> width = uint32_t(aWidth);
   CheckedInt<uint32_t> height = uint32_t(aHeight);
   return width * height * aBytesPerPixel;
 }
 
+class WebRenderGlyphHelper final {
+public:
+  WebRenderGlyphHelper()
+    : mFontData(nullptr)
+    , mFontDataLength(0)
+    , mIndex(0)
+    , mGlyphSize(0.0)
+  {
+  }
+
+  ~WebRenderGlyphHelper()
+  {
+    if (mFontData) {
+      free(mFontData);
+    }
+  }
+
+  void BuildWebRenderCommands(nsTArray<layers::WebRenderCommand>& aCommands,
+                              const nsTArray<layers::GlyphArray>& aGlyphs,
+                              ScaledFont* aFont,
+                              const Point& aOffset,
+                              const Rect& aBounds,
+                              const Rect& aClip);
+
+public:
+  uint8_t* mFontData;
+  uint32_t mFontDataLength;
+  uint32_t mIndex;
+  float mGlyphSize;
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif