зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: 2ZpDkstVKjg
This commit is contained in:
Коммит
aa280593d3
|
@ -127,6 +127,8 @@
|
|||
#include "mozilla/StyleSetHandle.h"
|
||||
#include "mozilla/StyleSetHandleInlines.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
#include "mozilla/layers/WebRenderCanvasRenderer.h"
|
||||
#include "mozilla/ServoCSSParser.h"
|
||||
|
||||
#undef free // apparently defined by some windows header, clashing with a free()
|
||||
|
@ -6217,6 +6219,64 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
return canvasLayer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasRenderingContext2D::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
if (mOpaque || mIsSkiaGL) {
|
||||
// If we're opaque then make sure we have a surface so we paint black
|
||||
// instead of transparent.
|
||||
// If we're using SkiaGL, then SkiaGLTex() below needs the target to
|
||||
// be accessible.
|
||||
EnsureTarget();
|
||||
}
|
||||
|
||||
// Don't call EnsureTarget() ... if there isn't already a surface, then
|
||||
// we have nothing to paint and there is no need to create a surface just
|
||||
// to paint nothing. Also, EnsureTarget() can cause creation of a persistent
|
||||
// layer manager which must NOT happen during a paint.
|
||||
if (!mBufferProvider && !IsTargetValid()) {
|
||||
// No DidTransactionCallback will be received, so mark the context clean
|
||||
// now so future invalidations will be dispatched.
|
||||
MarkContextClean();
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
CanvasInitializeData data;
|
||||
|
||||
if (mIsSkiaGL) {
|
||||
GLuint skiaGLTex = SkiaGLTex();
|
||||
if (skiaGLTex) {
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
MOZ_ASSERT(glue);
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mFrontbufferGLTex = skiaGLTex;
|
||||
}
|
||||
}
|
||||
data.mBufferProvider = mBufferProvider;
|
||||
|
||||
if (renderer->IsDataValid(data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasRenderingContext2D::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
|
|
@ -467,6 +467,10 @@ public:
|
|||
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
Layer* aOldLayer,
|
||||
LayerManager* aManager) override;
|
||||
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) override;
|
||||
virtual bool ShouldForceInactiveLayer(LayerManager* aManager) override;
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "ScopedGLHelpers.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
#include "mozilla/layers/WebRenderCanvasRenderer.h"
|
||||
|
||||
// Local
|
||||
#include "CanvasUtils.h"
|
||||
|
@ -1350,6 +1352,28 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
|
|||
return canvasLayer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
|
|
@ -434,6 +434,11 @@ public:
|
|||
already_AddRefed<Layer>
|
||||
GetCanvasLayer(nsDisplayListBuilder* builder, Layer* oldLayer,
|
||||
LayerManager* manager) override;
|
||||
|
||||
bool
|
||||
UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
|
||||
bool
|
||||
InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) override;
|
||||
|
|
|
@ -29,6 +29,7 @@ class CanvasLayer;
|
|||
class CanvasRenderer;
|
||||
class Layer;
|
||||
class LayerManager;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
typedef mozilla::layers::CanvasRenderer CanvasRenderer;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
|
||||
|
||||
|
@ -140,6 +142,8 @@ public:
|
|||
virtual already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* builder,
|
||||
Layer *oldLayer,
|
||||
LayerManager *manager) = 0;
|
||||
virtual bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) { return false; }
|
||||
virtual bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) { return true; }
|
||||
|
||||
|
|
|
@ -1219,6 +1219,37 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
if (mCurrentContext) {
|
||||
return mCurrentContext->UpdateWebRenderCanvasData(aBuilder, aCanvasData);
|
||||
}
|
||||
if (mOffscreenCanvas) {
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
@ -1235,7 +1266,7 @@ HTMLCanvasElement::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
|||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -35,6 +35,7 @@ class Image;
|
|||
class Layer;
|
||||
class LayerManager;
|
||||
class SharedSurfaceTextureClient;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
|
@ -127,6 +128,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
|||
typedef layers::CanvasLayer CanvasLayer;
|
||||
typedef layers::Layer Layer;
|
||||
typedef layers::LayerManager LayerManager;
|
||||
typedef layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
|
||||
public:
|
||||
explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
|
||||
|
@ -306,6 +308,8 @@ public:
|
|||
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
Layer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData);
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer);
|
||||
// Should return true if the canvas layer should always be marked inactive.
|
||||
|
|
|
@ -40,9 +40,11 @@ WebRenderCommandBuilder::EmptyTransaction()
|
|||
for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) {
|
||||
RefPtr<WebRenderCanvasData> canvasData = iter.Get()->GetKey();
|
||||
WebRenderCanvasRendererAsync* canvas = canvasData->GetCanvasRenderer();
|
||||
if (canvas) {
|
||||
canvas->UpdateCompositableClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderCommandBuilder::NeedsEmptyTransaction()
|
||||
|
|
|
@ -255,13 +255,22 @@ WebRenderCanvasData::ClearCachedResources()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasData::ClearCanvasRenderer()
|
||||
{
|
||||
mCanvasRenderer = nullptr;
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererAsync*
|
||||
WebRenderCanvasData::GetCanvasRenderer()
|
||||
{
|
||||
if (!mCanvasRenderer) {
|
||||
mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
|
||||
return mCanvasRenderer.get();
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererAsync*
|
||||
WebRenderCanvasData::CreateCanvasRenderer()
|
||||
{
|
||||
mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
|
||||
return mCanvasRenderer.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,9 @@ public:
|
|||
virtual UserDataType GetType() override { return UserDataType::eCanvas; }
|
||||
static UserDataType Type() { return UserDataType::eCanvas; }
|
||||
|
||||
void ClearCanvasRenderer();
|
||||
WebRenderCanvasRendererAsync* GetCanvasRenderer();
|
||||
WebRenderCanvasRendererAsync* CreateCanvasRenderer();
|
||||
void ClearCachedResources() override;
|
||||
protected:
|
||||
UniquePtr<WebRenderCanvasRendererAsync> mCanvasRenderer;
|
||||
|
|
|
@ -994,9 +994,7 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
|||
new gfxFontconfigFontEntry(faceName, face, mContainsAppFonts);
|
||||
AddFontEntry(fontEntry);
|
||||
|
||||
if (fontEntry->IsUpright() &&
|
||||
fontEntry->Weight() == NS_FONT_WEIGHT_NORMAL &&
|
||||
fontEntry->Stretch() == NS_FONT_STRETCH_NORMAL) {
|
||||
if (fontEntry->IsNormalStyle()) {
|
||||
numRegularFaces++;
|
||||
}
|
||||
|
||||
|
|
|
@ -1485,16 +1485,27 @@ gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
|
|||
unicodeRange, int(script),
|
||||
NS_ConvertUTF16toUTF8(fe->Name()).get()));
|
||||
}
|
||||
}
|
||||
|
||||
aMatchData->mCmapsTested++;
|
||||
if (rank == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// omitting from original windows code -- family name, lang group, pitch
|
||||
// not available in current FontEntry implementation
|
||||
rank += CalcStyleMatch(fe, aMatchData->mStyle);
|
||||
} else if (!fe->IsNormalStyle()) {
|
||||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle);
|
||||
SearchAllFontsForChar(&data);
|
||||
if (data.mMatchRank >= RANK_MATCHED_CMAP) {
|
||||
fe = data.mBestMatch;
|
||||
rank = data.mMatchRank;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
aMatchData->mCmapsTested++;
|
||||
|
||||
// xxx - add whether AAT font with morphing info for specific lang groups
|
||||
|
||||
|
|
|
@ -143,6 +143,19 @@ public:
|
|||
bool IgnoreGDEF() const { return mIgnoreGDEF; }
|
||||
bool IgnoreGSUB() const { return mIgnoreGSUB; }
|
||||
|
||||
// Return whether the face corresponds to "normal" CSS style properties:
|
||||
// font-style: normal;
|
||||
// font-weight: normal;
|
||||
// font-stretch: normal;
|
||||
// If this is false, we might want to fall back to a different face and
|
||||
// possibly apply synthetic styling.
|
||||
bool IsNormalStyle() const
|
||||
{
|
||||
return IsUpright() &&
|
||||
Weight() == NS_FONT_WEIGHT_NORMAL &&
|
||||
Stretch() == NS_FONT_STRETCH_NORMAL;
|
||||
}
|
||||
|
||||
// whether a feature is supported by the font (limited to a small set
|
||||
// of features for which some form of fallback needs to be implemented)
|
||||
virtual bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag);
|
||||
|
@ -568,16 +581,14 @@ private:
|
|||
// used when iterating over all fonts looking for a match for a given character
|
||||
struct GlobalFontMatch {
|
||||
GlobalFontMatch(const uint32_t aCharacter,
|
||||
mozilla::unicode::Script aRunScript,
|
||||
const gfxFontStyle *aStyle) :
|
||||
mCh(aCharacter), mRunScript(aRunScript), mStyle(aStyle),
|
||||
mCh(aCharacter), mStyle(aStyle),
|
||||
mMatchRank(0), mCount(0), mCmapsTested(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const uint32_t mCh; // codepoint to be matched
|
||||
mozilla::unicode::Script mRunScript; // Unicode script for the codepoint
|
||||
const gfxFontStyle* mStyle; // style to match
|
||||
int32_t mMatchRank; // metric indicating closest match
|
||||
RefPtr<gfxFontEntry> mBestMatch; // current best match
|
||||
|
|
|
@ -615,18 +615,34 @@ gfxPlatformFontList::CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
|
|||
|
||||
familyName.AppendASCII(fallbackFamily);
|
||||
gfxFontFamily *fallback = FindFamilyByCanonicalName(familyName);
|
||||
if (!fallback)
|
||||
if (!fallback) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfxFontEntry *fontEntry;
|
||||
bool needsBold; // ignored in the system fallback case
|
||||
|
||||
// use first font in list that supports a given character
|
||||
fontEntry = fallback->FindFontForStyle(*aMatchStyle, needsBold);
|
||||
if (fontEntry && fontEntry->HasCharacter(aCh)) {
|
||||
if (fontEntry) {
|
||||
if (fontEntry->HasCharacter(aCh)) {
|
||||
*aMatchedFamily = fallback;
|
||||
return fontEntry;
|
||||
}
|
||||
// If we requested a styled font (bold and/or italic), and the char
|
||||
// was not available, check other faces of the family.
|
||||
if (!fontEntry->IsNormalStyle()) {
|
||||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
GlobalFontMatch data(aCh, aMatchStyle);
|
||||
fallback->SearchAllFontsForChar(&data);
|
||||
if (data.mBestMatch) {
|
||||
*aMatchedFamily = fallback;
|
||||
return data.mBestMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -652,7 +668,7 @@ gfxPlatformFontList::GlobalFontFallback(const uint32_t aCh,
|
|||
}
|
||||
|
||||
// otherwise, try to find it among local fonts
|
||||
GlobalFontMatch data(aCh, aRunScript, aMatchStyle);
|
||||
GlobalFontMatch data(aCh, aMatchStyle);
|
||||
|
||||
// iterate over all font families to find a font that support the character
|
||||
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
|
||||
|
|
|
@ -2828,10 +2828,9 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
|
|||
}
|
||||
|
||||
gfxFont*
|
||||
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh,
|
||||
Script aRunScript)
|
||||
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
|
||||
{
|
||||
GlobalFontMatch data(aCh, aRunScript, &mStyle);
|
||||
GlobalFontMatch data(aCh, &mStyle);
|
||||
aFamily->SearchAllFontsForChar(&data);
|
||||
gfxFontEntry* fe = data.mBestMatch;
|
||||
if (!fe) {
|
||||
|
@ -2930,22 +2929,18 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
|||
|
||||
gfxFont* font = nullptr;
|
||||
if (mFonts[0].CheckForFallbackFaces()) {
|
||||
font = FindFallbackFaceForChar(mFonts[0].Family(), aCh,
|
||||
aRunScript);
|
||||
font = FindFallbackFaceForChar(mFonts[0].Family(), aCh);
|
||||
} else if (!firstFont->GetFontEntry()->IsUserFont()) {
|
||||
// For platform fonts (but not userfonts), we may need to do
|
||||
// fallback within the family to handle cases where some faces
|
||||
// such as Italic or Black have reduced character sets compared
|
||||
// to the family's Regular face.
|
||||
gfxFontEntry* fe = firstFont->GetFontEntry();
|
||||
if (!fe->IsUpright() ||
|
||||
fe->Weight() != NS_FONT_WEIGHT_NORMAL ||
|
||||
fe->Stretch() != NS_FONT_STRETCH_NORMAL) {
|
||||
if (!fe->IsNormalStyle()) {
|
||||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
font = FindFallbackFaceForChar(mFonts[0].Family(), aCh,
|
||||
aRunScript);
|
||||
font = FindFallbackFaceForChar(mFonts[0].Family(), aCh);
|
||||
}
|
||||
}
|
||||
if (font) {
|
||||
|
@ -3047,7 +3042,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
|||
!mFonts[i-1].CheckForFallbackFaces() ||
|
||||
!mFonts[i-1].Family()->Name().Equals(ff.Family()->Name()),
|
||||
"should only do fallback once per font family");
|
||||
font = FindFallbackFaceForChar(ff.Family(), aCh, aRunScript);
|
||||
font = FindFallbackFaceForChar(ff.Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font;
|
||||
|
@ -3058,10 +3053,8 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
|||
// also above).
|
||||
fe = ff.FontEntry();
|
||||
if (!fe->mIsUserFontContainer && !fe->IsUserFont() &&
|
||||
(!fe->IsUpright() ||
|
||||
fe->Weight() != NS_FONT_WEIGHT_NORMAL ||
|
||||
fe->Stretch() != NS_FONT_STRETCH_NORMAL)) {
|
||||
font = FindFallbackFaceForChar(ff.Family(), aCh, aRunScript);
|
||||
!fe->IsNormalStyle()) {
|
||||
font = FindFallbackFaceForChar(ff.Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font;
|
||||
|
@ -3397,7 +3390,9 @@ gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh)
|
|||
for (j = 0; j < numPrefs; j++) {
|
||||
// look up the appropriate face
|
||||
gfxFontFamily *family = (*families)[j];
|
||||
if (!family) continue;
|
||||
if (!family) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if a pref font is used, it's likely to be used again in the same text run.
|
||||
// the style doesn't change so the face lookup can be cached rather than calling
|
||||
|
@ -3409,8 +3404,12 @@ gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh)
|
|||
|
||||
bool needsBold;
|
||||
gfxFontEntry *fe = family->FindFontForStyle(mStyle, needsBold);
|
||||
if (!fe) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if ch in cmap, create and return a gfxFont
|
||||
if (fe && fe->HasCharacter(aCh)) {
|
||||
if (fe->HasCharacter(aCh)) {
|
||||
gfxFont* prefFont = fe->FindOrMakeFont(&mStyle, needsBold);
|
||||
if (!prefFont) {
|
||||
continue;
|
||||
|
@ -3422,6 +3421,21 @@ gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh)
|
|||
return prefFont;
|
||||
}
|
||||
|
||||
// If we requested a styled font (bold and/or italic), and the char
|
||||
// was not available, check the regular face as well.
|
||||
if (!fe->IsNormalStyle()) {
|
||||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
gfxFont* prefFont = FindFallbackFaceForChar(family, aCh);
|
||||
if (prefFont) {
|
||||
mLastPrefFamily = family;
|
||||
mLastPrefFont = prefFont;
|
||||
mLastPrefLang = charLang;
|
||||
mLastPrefFirstFont = (i == 0 && j == 0);
|
||||
return prefFont;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1247,8 +1247,7 @@ protected:
|
|||
// search all faces in a family for a fallback in cases where it's unclear
|
||||
// whether the family might have a font for a given character
|
||||
gfxFont*
|
||||
FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh,
|
||||
Script aRunScript);
|
||||
FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh);
|
||||
|
||||
// helper methods for looking up fonts
|
||||
|
||||
|
|
|
@ -24,11 +24,10 @@ class MoveEmitterARM64
|
|||
// Original stack push value.
|
||||
uint32_t pushedAtStart_;
|
||||
|
||||
// These store stack offsets to spill locations, snapshotting
|
||||
// codegen->framePushed_ at the time they were allocated. They are -1 if no
|
||||
// This stores a stack offset to a spill location, snapshotting
|
||||
// codegen->framePushed_ at the time it was allocated. It is -1 if no
|
||||
// stack space has been allocated for that particular spill.
|
||||
int32_t pushedAtCycle_;
|
||||
int32_t pushedAtSpill_;
|
||||
|
||||
void assertDone() {
|
||||
MOZ_ASSERT(!inCycle_);
|
||||
|
@ -65,8 +64,7 @@ class MoveEmitterARM64
|
|||
: inCycle_(false),
|
||||
masm(masm),
|
||||
pushedAtStart_(masm.framePushed()),
|
||||
pushedAtCycle_(-1),
|
||||
pushedAtSpill_(-1)
|
||||
pushedAtCycle_(-1)
|
||||
{ }
|
||||
|
||||
~MoveEmitterARM64() {
|
||||
|
|
|
@ -141,16 +141,13 @@ public:
|
|||
bool isRecycled;
|
||||
RefPtr<WebRenderCanvasData> canvasData =
|
||||
aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderCanvasData>(this, &isRecycled);
|
||||
WebRenderCanvasRendererAsync* data =
|
||||
static_cast<WebRenderCanvasRendererAsync*>(canvasData->GetCanvasRenderer());
|
||||
|
||||
if (!isRecycled) {
|
||||
nsHTMLCanvasFrame* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
if (!canvasFrame->InitializeCanvasRenderer(aDisplayListBuilder, data)) {
|
||||
if (!canvasFrame->UpdateWebRenderCanvasData(aDisplayListBuilder, canvasData)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererAsync* data =
|
||||
static_cast<WebRenderCanvasRendererAsync*>(canvasData->GetCanvasRenderer());
|
||||
MOZ_ASSERT(data);
|
||||
data->UpdateCompositableClient();
|
||||
|
||||
// Push IFrame for async image pipeline.
|
||||
|
@ -461,11 +458,11 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
bool
|
||||
nsHTMLCanvasFrame::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
nsHTMLCanvasFrame::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(GetContent());
|
||||
return element->InitializeCanvasRenderer(aBuilder, aRenderer);
|
||||
return element->UpdateWebRenderCanvasData(aBuilder, aCanvasData);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace mozilla {
|
|||
namespace layers {
|
||||
class Layer;
|
||||
class LayerManager;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
typedef mozilla::layers::CanvasRenderer CanvasRenderer;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
|
||||
|
||||
NS_DECL_QUERYFRAME
|
||||
|
@ -53,8 +55,9 @@ public:
|
|||
LayerManager* aManager,
|
||||
nsDisplayItem* aItem,
|
||||
const ContainerLayerParameters& aContainerParameters);
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer);
|
||||
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData);
|
||||
|
||||
/* get the size of the canvas's image */
|
||||
nsIntSize GetCanvasSize();
|
||||
|
|
|
@ -6,7 +6,7 @@ fuzzy-if(Android,8,1000) == size-1.html size-1-ref.html
|
|||
== image-rendering-test.html image-rendering-ref.html
|
||||
== image-shadow.html image-shadow-ref.html
|
||||
|
||||
asserts-if(cocoaWidget,0-2) fails-if(webrender) == size-change-1.html size-change-1-ref.html
|
||||
asserts-if(cocoaWidget,0-2) == size-change-1.html size-change-1-ref.html
|
||||
|
||||
random-if(cocoaWidget) == subpixel-1.html about:blank # see bug 1192616, re-enable once we're off the pandaboards
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#if defined(ANDROID)
|
||||
#include <sys/syscall.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <android/api-level.h>
|
||||
#if __ANDROID_API__ < 8
|
||||
|
@ -331,25 +332,6 @@ void *
|
|||
SystemElf::GetSymbolPtr(const char *symbol) const
|
||||
{
|
||||
void *sym = dlsym(dlhandle, symbol);
|
||||
// Various bits of Gecko use isnanf, which gcc is happy to compile into
|
||||
// inlined code using floating-point comparisons. clang, on the other hand,
|
||||
// does not use inline code and generates full calls to isnanf.
|
||||
//
|
||||
// libm.so on Android defines isnanf as weak. dlsym always returns null for
|
||||
// weak symbols. Which means that we'll never be able to resolve the symbol
|
||||
// that clang generates here. However, said weak symbol for isnanf is just
|
||||
// an alias for __isnanf, which is the real definition. So if we're asked
|
||||
// for isnanf and we can't find it, try looking for __isnanf instead. The
|
||||
// actual system linker uses alternate resolution interfaces and therefore
|
||||
// does not encounter this issue.
|
||||
//
|
||||
// See also https://bugs.chromium.org/p/chromium/issues/detail?id=376828,
|
||||
// from which this comment and this fix are adapted.
|
||||
if (!sym &&
|
||||
!strcmp(symbol, "isnanf") &&
|
||||
!strcmp(GetName(), "libm.so")) {
|
||||
sym = dlsym(dlhandle, "__isnanf");
|
||||
}
|
||||
DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol, sym);
|
||||
ElfLoader::Singleton.lastError = dlerror();
|
||||
return sym;
|
||||
|
@ -576,6 +558,9 @@ ElfLoader::Init()
|
|||
if (dladdr(FunctionPtr(syscall), &info) != 0) {
|
||||
libc = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
||||
}
|
||||
if (dladdr(FunctionPtr<int (*)(double)>(isnan), &info) != 0) {
|
||||
libm = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -591,6 +576,7 @@ ElfLoader::~ElfLoader()
|
|||
self_elf = nullptr;
|
||||
#if defined(ANDROID)
|
||||
libc = nullptr;
|
||||
libm = nullptr;
|
||||
#endif
|
||||
|
||||
AutoLock lock(&handlesMutex);
|
||||
|
|
|
@ -473,6 +473,9 @@ private:
|
|||
* we wouldn't treat non-Android differently, but glibc uses versioned
|
||||
* symbols which this linker doesn't support. */
|
||||
RefPtr<LibHandle> libc;
|
||||
|
||||
/* And for libm. */
|
||||
RefPtr<LibHandle> libm;
|
||||
#endif
|
||||
|
||||
/* Bookkeeping */
|
||||
|
|
Загрузка…
Ссылка в новой задаче