зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1348980 - use UnscaledFont to track WebRender font keys. r=jrmuizel
This commit is contained in:
Родитель
a168dcdbf3
Коммит
22fb7629b8
|
@ -46,6 +46,7 @@ parent:
|
|||
SurfaceFormat aFormat, ByteBuffer aBytes);
|
||||
sync DeleteImage(ImageKey aImageKey);
|
||||
async AddRawFont(FontKey aFontKey, ByteBuffer aBytes, uint32_t aFontIndex);
|
||||
async DeleteFont(FontKey aFontKey);
|
||||
async DPBegin(IntSize aSize);
|
||||
async DPEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
|
||||
ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
|
||||
|
|
|
@ -24,6 +24,7 @@ WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId)
|
|||
, mPipelineId(aPipelineId)
|
||||
, mIPCOpen(false)
|
||||
, mDestroyed(false)
|
||||
, mFontKeysDeleted(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -151,6 +152,112 @@ WebRenderBridgeChild::DeallocExternalImageId(uint64_t aImageId)
|
|||
SendRemoveExternalImageId(aImageId);
|
||||
}
|
||||
|
||||
struct FontFileData
|
||||
{
|
||||
wr::ByteBuffer mFontBuffer;
|
||||
uint32_t mFontIndex;
|
||||
float mGlyphSize;
|
||||
};
|
||||
|
||||
static void
|
||||
WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
|
||||
float aGlyphSize, uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations, void* aBaton)
|
||||
{
|
||||
FontFileData* data = static_cast<FontFileData*>(aBaton);
|
||||
|
||||
if (!data->mFontBuffer.Allocate(aLength)) {
|
||||
return;
|
||||
}
|
||||
memcpy(data->mFontBuffer.mData, aData, aLength);
|
||||
|
||||
data->mFontIndex = aIndex;
|
||||
data->mGlyphSize = aGlyphSize;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
|
||||
gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
|
||||
const gfx::Rect& aClip)
|
||||
{
|
||||
MOZ_ASSERT(aFont);
|
||||
MOZ_ASSERT(!aGlyphs.IsEmpty());
|
||||
|
||||
WrFontKey key = GetFontKeyForScaledFont(aFont);
|
||||
MOZ_ASSERT(key.mNamespace && key.mHandle);
|
||||
|
||||
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(aClip));
|
||||
|
||||
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_glyph_instances.SetLength(glyphs.Length());
|
||||
|
||||
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;
|
||||
}
|
||||
aBuilder.PushText(wr::ToWrRect(aBounds),
|
||||
clipRegion,
|
||||
glyph_array.color().value(),
|
||||
key,
|
||||
Range<const WrGlyphInstance>(wr_glyph_instances.Elements(), wr_glyph_instances.Length()),
|
||||
aFont->GetSize());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
wr::FontKey
|
||||
WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
MOZ_ASSERT(aScaledFont);
|
||||
MOZ_ASSERT((aScaledFont->GetType() == gfx::FontType::DWRITE) ||
|
||||
(aScaledFont->GetType() == gfx::FontType::MAC) ||
|
||||
(aScaledFont->GetType() == gfx::FontType::FONTCONFIG));
|
||||
|
||||
RefPtr<UnscaledFont> unscaled = aScaledFont->GetUnscaledFont();
|
||||
MOZ_ASSERT(unscaled);
|
||||
|
||||
wr::FontKey key = {0, 0};
|
||||
if (mFontKeys.Get(unscaled, &key)) {
|
||||
return key;
|
||||
}
|
||||
|
||||
FontFileData data;
|
||||
if (!aScaledFont->GetFontFileData(WriteFontFileData, &data) ||
|
||||
!data.mFontBuffer.mData) {
|
||||
return key;
|
||||
}
|
||||
|
||||
key.mNamespace = GetNamespace();
|
||||
key.mHandle = GetNextResourceId();
|
||||
|
||||
SendAddRawFont(key, data.mFontBuffer, data.mFontIndex);
|
||||
|
||||
mFontKeys.Put(unscaled, key);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::RemoveExpiredFontKeys()
|
||||
{
|
||||
uint32_t counter = UnscaledFont::DeletionCounter();
|
||||
if (mFontKeysDeleted != counter) {
|
||||
mFontKeysDeleted = counter;
|
||||
for (auto iter = mFontKeys.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (!iter.Key()) {
|
||||
SendDeleteFont(iter.Data());
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompositorBridgeChild*
|
||||
WebRenderBridgeChild::GetCompositorBridgeChild()
|
||||
{
|
||||
|
|
|
@ -26,6 +26,28 @@ class CompositableClient;
|
|||
class CompositorBridgeChild;
|
||||
class TextureForwarder;
|
||||
|
||||
class UnscaledFontHashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef gfx::UnscaledFont* KeyType;
|
||||
typedef const gfx::UnscaledFont* KeyTypePointer;
|
||||
|
||||
explicit UnscaledFontHashKey(KeyTypePointer aKey) : mKey(const_cast<KeyType>(aKey)) {}
|
||||
|
||||
KeyType GetKey() const { return mKey; }
|
||||
bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey)
|
||||
{
|
||||
return NS_PTR_TO_UINT32(aKey) >> 2;
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
private:
|
||||
WeakPtr<gfx::UnscaledFont> mKey;
|
||||
};
|
||||
|
||||
class WebRenderBridgeChild final : public PWebRenderBridgeChild
|
||||
, public CompositableForwarder
|
||||
{
|
||||
|
@ -67,6 +89,14 @@ public:
|
|||
mIdNamespace = aIdNamespace;
|
||||
}
|
||||
|
||||
void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
|
||||
gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
|
||||
const gfx::Rect& aClip);
|
||||
|
||||
wr::FontKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
|
||||
|
||||
void RemoveExpiredFontKeys();
|
||||
|
||||
private:
|
||||
friend class CompositorBridgeChild;
|
||||
|
||||
|
@ -123,6 +153,9 @@ private:
|
|||
|
||||
bool mIPCOpen;
|
||||
bool mDestroyed;
|
||||
|
||||
uint32_t mFontKeysDeleted;
|
||||
nsDataHashtable<UnscaledFontHashKey, wr::FontKey> mFontKeys;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -226,7 +226,16 @@ WebRenderBridgeParent::RecvAddRawFont(const wr::FontKey& aFontKey,
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvDeleteFont(const wr::FontKey& aFontKey)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
MOZ_ASSERT(mApi);
|
||||
mApi->DeleteFont(aFontKey);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
|
||||
|
|
|
@ -73,14 +73,15 @@ public:
|
|||
const uint32_t& aStride,
|
||||
const gfx::SurfaceFormat& aFormat,
|
||||
const ByteBuffer& aBuffer) override;
|
||||
mozilla::ipc::IPCResult RecvAddRawFont(const wr::FontKey& aFontKey,
|
||||
const ByteBuffer& aBuffer,
|
||||
const uint32_t& aFontIndex) override;
|
||||
mozilla::ipc::IPCResult RecvUpdateImage(const wr::ImageKey& aImageKey,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::SurfaceFormat& aFormat,
|
||||
const ByteBuffer& aBuffer) override;
|
||||
mozilla::ipc::IPCResult RecvDeleteImage(const wr::ImageKey& a1) override;
|
||||
mozilla::ipc::IPCResult RecvAddRawFont(const wr::FontKey& aFontKey,
|
||||
const ByteBuffer& aBuffer,
|
||||
const uint32_t& aFontIndex) override;
|
||||
mozilla::ipc::IPCResult RecvDeleteFont(const wr::FontKey& aFontKey) override;
|
||||
mozilla::ipc::IPCResult RecvDPBegin(const gfx::IntSize& aSize) override;
|
||||
mozilla::ipc::IPCResult RecvDPEnd(const gfx::IntSize& aSize,
|
||||
InfallibleTArray<WebRenderParentCommand>&& aCommands,
|
||||
|
|
|
@ -288,6 +288,7 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
|||
EndTransactionFlags aFlags)
|
||||
{
|
||||
DiscardImages();
|
||||
WrBridge()->RemoveExpiredFontKeys();
|
||||
|
||||
mPaintedLayerCallback = aCallback;
|
||||
mPaintedLayerCallbackData = aCallbackData;
|
||||
|
|
|
@ -39,8 +39,7 @@ WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
|
|||
Stringify(clip).c_str());
|
||||
}
|
||||
|
||||
mGlyphHelper.BuildWebRenderCommands(WrBridge(), aBuilder, mGlyphs, mFont,
|
||||
GetOffsetToParent(), rect, clip);
|
||||
WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, GetOffsetToParent(), rect, clip);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -33,8 +33,6 @@ public:
|
|||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
|
||||
|
||||
protected:
|
||||
gfx::WebRenderGlyphHelper mGlyphHelper;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -21,14 +21,10 @@
|
|||
#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 "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIClipboardHelper.h"
|
||||
#include "nsIFile.h"
|
||||
|
@ -1443,68 +1439,5 @@ 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(WebRenderBridgeChild* aBridge,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
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);
|
||||
|
||||
WrFontKey key;
|
||||
key.mNamespace = aBridge->GetNamespace();
|
||||
key.mHandle = aBridge->GetNextResourceId();
|
||||
|
||||
aBridge->SendAddRawFont(key, fontBuffer, mIndex);
|
||||
|
||||
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(aClip));
|
||||
|
||||
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_glyph_instances.SetLength(glyphs.Length());
|
||||
|
||||
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;
|
||||
}
|
||||
aBuilder.PushText(wr::ToWrRect(aBounds),
|
||||
clipRegion,
|
||||
glyph_array.color().value(),
|
||||
key,
|
||||
Range<const WrGlyphInstance>(wr_glyph_instances.Elements(), wr_glyph_instances.Length()),
|
||||
mGlyphSize);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "nsRegionFwd.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
|
||||
class gfxASurface;
|
||||
class gfxDrawable;
|
||||
|
@ -313,38 +313,6 @@ SafeBytesForBitmap(uint32_t aWidth, uint32_t aHeight, unsigned aBytesPerPixel)
|
|||
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(layers::WebRenderBridgeChild* aChild,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
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
|
||||
|
||||
|
|
|
@ -445,7 +445,7 @@ WebRenderAPI::AddRawFont(wr::FontKey key, Range<uint8_t> aBytes)
|
|||
void
|
||||
WebRenderAPI::DeleteFont(wr::FontKey aKey)
|
||||
{
|
||||
printf("XXX - WebRender does not seem to implement deleting a font! Leaking it...\n");
|
||||
wr_api_delete_font(mWrApi, aKey);
|
||||
}
|
||||
|
||||
class EnableProfiler : public RendererEvent
|
||||
|
|
|
@ -941,6 +941,13 @@ pub extern "C" fn wr_api_add_raw_font(api: &mut RenderApi,
|
|||
api.add_raw_font(key, font_vector);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_api_delete_font(api: &mut RenderApi, key: FontKey)
|
||||
{
|
||||
assert!( unsafe { is_in_compositor_thread() });
|
||||
api.delete_font(key);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wr_api_get_namespace(api: &mut RenderApi) -> IdNamespace {
|
||||
api.id_namespace
|
||||
|
|
|
@ -601,6 +601,10 @@ WR_INLINE void
|
|||
wr_api_add_raw_font(WrAPI* api, WrFontKey key, uint8_t* font_buffer, size_t buffer_size)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE void
|
||||
wr_api_delete_font(WrAPI* api, WrFontKey key)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE WrIdNamespace
|
||||
wr_api_get_namespace(WrAPI* api)
|
||||
WR_FUNC;
|
||||
|
|
|
@ -309,7 +309,6 @@ private:
|
|||
nsPoint mPoint;
|
||||
RefPtr<ScaledFont> mFont;
|
||||
nsTArray<layers::GlyphArray> mGlyphs;
|
||||
WebRenderGlyphHelper mGlyphHelper;
|
||||
|
||||
// Store the type of list-style-type.
|
||||
int32_t mListStyleType;
|
||||
|
@ -506,8 +505,8 @@ BulletRenderer::CreateWebRenderCommandsForText(nsDisplayItem* aItem,
|
|||
NSRectToRect(aItem->GetBounds(builder, &dummy), appUnitsPerDevPixel);
|
||||
Rect destRectTransformed = aLayer->RelativeToParent(destRect);
|
||||
|
||||
mGlyphHelper.BuildWebRenderCommands(layer->WrBridge(), aBuilder, mGlyphs, mFont, aLayer->GetOffsetToParent(),
|
||||
destRectTransformed, destRectTransformed);
|
||||
layer->WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, aLayer->GetOffsetToParent(),
|
||||
destRectTransformed, destRectTransformed);
|
||||
}
|
||||
|
||||
class nsDisplayBullet final : public nsDisplayItem {
|
||||
|
|
Загрузка…
Ссылка в новой задаче