import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 967494 - "Preference Composition/Spelling/Language is ignored, and changing spellcheck language in one composition window affects all open and new compositions" [r=ehsan] Bug 1157421 - Fix typo "suggesteed". r=ehsan (d48b61df9)
- namespaces (c9e3edbf1)
- Bug 1167409 - 3/4 - Change ScriptLoadRequeest::mLoading to mProgress. r=jandem (34377ba15)
- Bug 1104732 - having deferred scripts shouldn't cause async scripts to delay domcontentloaded, r?smaug (f6b3a5ad9)
- Bug 1138395 - Optimize nsDocument::mExpandoAndGeneration.expando out from the cc graphs when possible, r=mccr8 (d944130ab)
- Bug 874838 - Make CreateElem return Element. r=khuey (ac65a35cf)
- Bug 1194619 - fix comment r=dholbert (017a488a2)
- Bug 1137494 - Change the type given to type validation check. r=jgilbert (05885cc7c)
- Bug 1106138 - Remove the early unpremultiply in WebGLContext::SurfaceFromElementResultToImageSurface, and let the texel conversion code handle it instead. r=jgilbert (b8010b16b)
- Bug 1185815 - Hoist generation increment. r=jgilbert (f6a276b5e)
- Bug 1175931 - TexImageFromVideoElement uses GL_HALF_FLOAT if it does not support GL_HALF_FLOAT_OES which would be the case on non-ANGLE systems. Using GL_HALF_FLOAT_OES on a non OES system would result in an error when using TexImage2D. r=jgilbert (d692281f1)
- Bug 1184534 - Add support for target size retrieval to GLX backend. r=jgilbert (0e5ba1f8e)
- bug 1174705 - add GLContext::GetDefaultFramebuffer. r=jgilbert (99c0e70aa)
- Bug 1179935, introduce complex viewport projections to Compositor, remove PrepareViewport; r=mstange (1753d65d3)
- Bug 1184534 - Fetch viewport size from context in CompositorOGL, discard if changed during composition. r=nical (4f57bc4ed)
- Bug 1187440 - Implement GLX shared surfaces on the OpenGL compositor. r=jgilbert,nical (4844e96ce)
- Bug 1033375 - Nudge simple linear gradients with hard stops to half-pixel gradient. r=nical (331ddd4fa)
- Bug 1185636 - Remove hard stop workaround for Cairo due to regressions. r=jrmuizel (ccefe7abc)
- Bug 1177807 - Mark cairo surface dirty in ReleaseBits. r=jrmuizel (ae9d508b9)
- Bug 1170390 - Detect 16bpp cairo xlib surface format. r=jrmuizel (25857ae30)
- Bug 1019063 - Check for ::CreateDCW failing when printing. r=dvander (7f54ba8d2)
- Bug 1170390 - Add gfxASurface::GetSurfaceFormat for retrieving precise surface format where necessary. r=jrmuizel (f70d11b29)
- Bug 1155626 - Don't assume that Factory::GetD2D1Device returns a non-null device and add some gfxCriticalLog. r=Bas (0c896a368)
- Bug 1182209 - Additional info with some critical errors. r=mchang CLOSED TREE (f4841baec)
This commit is contained in:
2021-12-28 09:45:42 +08:00
parent 23896f6de1
commit e8f234939e
67 changed files with 856 additions and 312 deletions
+8 -16
View File
@@ -210,25 +210,19 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
nsCOMPtr<nsIContent> root;
rv = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr, kNameSpaceID_XHTML,
getter_AddRefs(root));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> root = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr,
kNameSpaceID_XHTML);
rv = doc->AppendChildTo(root, false);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> head;
rv = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr, kNameSpaceID_XHTML,
getter_AddRefs(head));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> head = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr,
kNameSpaceID_XHTML);
rv = root->AppendChildTo(head, false);
NS_ENSURE_SUCCESS(rv, rv);
if (!DOMStringIsNull(aTitle)) {
nsCOMPtr<nsIContent> title;
rv = doc->CreateElem(NS_LITERAL_STRING("title"), nullptr,
kNameSpaceID_XHTML, getter_AddRefs(title));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> title = doc->CreateElem(NS_LITERAL_STRING("title"),
nullptr, kNameSpaceID_XHTML);
rv = head->AppendChildTo(title, false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -239,10 +233,8 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIContent> body;
rv = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr, kNameSpaceID_XHTML,
getter_AddRefs(body));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> body = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr,
kNameSpaceID_XHTML);
rv = root->AppendChildTo(body, false);
NS_ENSURE_SUCCESS(rv, rv);
+16 -23
View File
@@ -1781,6 +1781,10 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDocument)
if (elm) {
elm->MarkForCC();
}
if (tmp->mExpandoAndGeneration.expando.isObject()) {
JS::ExposeObjectToActiveJS(
&(tmp->mExpandoAndGeneration.expando.toObject()));
}
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
@@ -5476,13 +5480,8 @@ nsIDocument::CreateElement(const nsAString& aTagName, ErrorResult& rv)
nsContentUtils::ASCIIToLower(aTagName, lcTagName);
}
nsCOMPtr<nsIContent> content;
rv = CreateElem(needsLowercase ? lcTagName : aTagName,
nullptr, mDefaultElementType, getter_AddRefs(content));
if (rv.Failed()) {
return nullptr;
}
return dont_AddRef(content.forget().take()->AsElement());
return CreateElem(needsLowercase ? lcTagName : aTagName, nullptr,
mDefaultElementType);
}
void
@@ -5826,13 +5825,10 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
nsDependentAtomString localName(definition->mLocalName);
nsCOMPtr<nsIContent> newElement;
nsresult rv = document->CreateElem(localName, nullptr,
definition->mNamespaceID,
getter_AddRefs(newElement));
NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<Element> element =
document->CreateElem(localName, nullptr, definition->mNamespaceID);
NS_ENSURE_TRUE(element, true);
nsCOMPtr<Element> element = do_QueryInterface(newElement);
if (definition->mLocalName != typeAtom) {
// This element is a custom element by extension, thus we need to
// do some special setup. For non-extended custom elements, this happens
@@ -5840,7 +5836,7 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
document->SetupCustomElement(element, definition->mNamespaceID, &elemName);
}
rv = nsContentUtils::WrapNative(aCx, newElement, newElement, args.rval());
nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
NS_ENSURE_SUCCESS(rv, true);
return true;
@@ -8628,9 +8624,9 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
}
}
nsresult
nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix, int32_t aNamespaceID,
nsIContent **aResult)
already_AddRefed<Element>
nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix,
int32_t aNamespaceID)
{
#ifdef DEBUG
nsAutoString qName;
@@ -8649,19 +8645,16 @@ nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix, int32_t aNamesp
"check caller.");
#endif
*aResult = nullptr;
nsRefPtr<mozilla::dom::NodeInfo> nodeInfo;
mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
nsIDOMNode::ELEMENT_NODE,
getter_AddRefs(nodeInfo));
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(nodeInfo, nullptr);
nsCOMPtr<Element> element;
nsresult rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
NOT_FROM_PARSER);
element.forget(aResult);
return rv;
return NS_SUCCEEDED(rv) ? element.forget() : nullptr;
}
bool
@@ -9038,7 +9031,7 @@ nsDocument::UnblockOnload(bool aFireSync)
// done loading, in a way comparable to |window.onload|. We fire this
// event to indicate that the SVG should be considered fully loaded.
// Because scripting is disabled on SVG-as-image documents, this event
// is not accessible to content authors. (See bug 837135.)
// is not accessible to content authors. (See bug 837315.)
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this,
NS_LITERAL_STRING("MozSVGAsImageDocumentLoad"),
+3 -3
View File
@@ -986,9 +986,9 @@ public:
virtual nsresult Init();
virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
int32_t aNamespaceID,
nsIContent **aResult) override;
virtual already_AddRefed<Element> CreateElem(const nsAString& aName,
nsIAtom* aPrefix,
int32_t aNamespaceID) override;
virtual void Sanitize() override;
+2 -1
View File
@@ -929,7 +929,8 @@ public:
// XHTML1 section C.7).
bool hasAttr = content->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang,
aResult);
if (!hasAttr && (content->IsHTMLElement() || content->IsSVGElement())) {
if (!hasAttr && (content->IsHTMLElement() || content->IsSVGElement() ||
content->IsXULElement())) {
hasAttr = content->GetAttr(kNameSpaceID_None, nsGkAtoms::lang,
aResult);
}
+6 -5
View File
@@ -158,8 +158,8 @@ struct FullScreenOptions {
} // namespace mozilla
#define NS_IDOCUMENT_IID \
{ 0x6d18ec0b, 0x1f68, 0x4ae6, \
{ 0x8b, 0x3d, 0x8d, 0x7d, 0x8b, 0x8e, 0x28, 0xd4 } }
{ 0x292450a1, 0x285e, 0x4a09, \
{ 0x9a, 0xf9, 0x61, 0xf9, 0xb1, 0xbd, 0x27, 0xcc } }
// Enum for requesting a particular type of document when creating a doc
enum DocumentFlavor {
@@ -1375,10 +1375,11 @@ public:
/**
* Create an element with the specified name, prefix and namespace ID.
* Returns null if element name parsing failed.
*/
virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
int32_t aNamespaceID,
nsIContent** aResult) = 0;
virtual already_AddRefed<Element> CreateElem(const nsAString& aName,
nsIAtom* aPrefix,
int32_t aNamespaceID) = 0;
/**
* Get the security info (i.e. SSL state etc) that the document got
+2 -2
View File
@@ -18,8 +18,8 @@ class nsCycleCollectionTraversalCallback;
namespace mozilla {
namespace dom {
class Animation;
}
}
} // namespace dom
} // namespace mozilla
class nsNodeUtils
{
+2 -3
View File
@@ -28,9 +28,8 @@ namespace dom {
class DocumentFragment;
class DOMRect;
class DOMRectList;
class Selection;
}
}
} // namespace dom
} // namespace mozilla
class nsRange final : public nsIDOMRange,
public nsStubMutationObserver,
+37 -18
View File
@@ -666,7 +666,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
sriMetadata);
request->mURI = scriptURI;
request->mIsInline = false;
request->mLoading = true;
request->mProgress = nsScriptLoadRequest::Progress_Loading;
request->mReferrerPolicy = ourRefPolicy;
// set aScriptFromHead to false so we don't treat non preloaded scripts as
@@ -681,14 +681,21 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
}
// Should still be in loading stage of script.
NS_ASSERTION(!request->InCompilingStage(),
"Request should not yet be in compiling stage.");
request->mJSVersion = version;
if (aElement->GetScriptAsync()) {
request->mIsAsync = true;
if (!request->mLoading) {
if (request->IsDoneLoading()) {
mLoadedAsyncRequests.AppendElement(request);
// The script is available already. Run it ASAP when the event
// loop gets a chance to spin.
// KVKV TODO: Instead of processing immediately, try off-thread-parsing
// it and only schedule a ProcessRequest if that fails.
ProcessPendingRequestsAsync();
} else {
mLoadingAsyncRequests.AppendElement(request);
@@ -701,7 +708,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
request->mIsNonAsyncScriptInserted = true;
mNonAsyncExternalScriptInsertedRequests.AppendElement(request);
if (!request->mLoading) {
if (request->IsDoneLoading()) {
// The script is available already. Run it ASAP when the event
// loop gets a chance to spin.
ProcessPendingRequestsAsync();
@@ -730,14 +737,14 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
"Parser-blocking scripts and XSLT scripts in the same doc!");
request->mIsXSLT = true;
mXSLTRequests.AppendElement(request);
if (!request->mLoading) {
if (request->IsDoneLoading()) {
// The script is available already. Run it ASAP when the event
// loop gets a chance to spin.
ProcessPendingRequestsAsync();
}
return true;
}
if (!request->mLoading && ReadyToExecuteScripts()) {
if (request->IsDoneLoading() && ReadyToExecuteScripts()) {
// The request has already been loaded and there are no pending style
// sheets. If the script comes from the network stream, cheat for
// performance reasons and avoid a trip through the event loop.
@@ -780,7 +787,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
request = new nsScriptLoadRequest(aElement, version, CORS_NONE,
SRIMetadata()); // SRI doesn't apply
request->mJSVersion = version;
request->mLoading = false;
request->mProgress = nsScriptLoadRequest::Progress_DoneLoading;
request->mIsInline = true;
request->mURI = mDocument->GetDocumentURI();
request->mLineNo = aElement->GetScriptLineNumber();
@@ -851,6 +858,8 @@ public:
nsresult
nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
{
MOZ_ASSERT(aRequest->mProgress == nsScriptLoadRequest::Progress_Compiling);
aRequest->mProgress = nsScriptLoadRequest::Progress_DoneCompiling;
nsresult rv = ProcessRequest(aRequest);
mDocument->UnblockOnload(false);
return rv;
@@ -935,18 +944,21 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
}
mDocument->BlockOnload();
aRequest->mProgress = nsScriptLoadRequest::Progress_Compiling;
unused << runnable.forget();
return NS_OK;
}
nsresult
nsScriptLoader::ParseOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest)
nsScriptLoader::CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest)
{
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
"Processing requests when running scripts is unsafe.");
NS_ASSERTION(!aRequest->mOffThreadToken,
"Candidate for off-thread parsing is already parsed off-thread");
"Candidate for off-thread compile is already parsed off-thread");
NS_ASSERTION(!aRequest->InCompilingStage(),
"Candidate for off-thread compile is already in compiling stage.");
nsresult rv = AttemptAsyncScriptParse(aRequest);
if (rv != NS_ERROR_FAILURE) {
@@ -961,6 +973,8 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
{
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
"Processing requests when running scripts is unsafe.");
NS_ASSERTION(aRequest->IsReadyToRun(),
"Processing a request that is not ready to run.");
NS_ENSURE_ARG(aRequest);
nsAutoString textData;
@@ -1233,8 +1247,9 @@ void
nsScriptLoader::ProcessPendingRequests()
{
nsRefPtr<nsScriptLoadRequest> request;
if (mParserBlockingRequest &&
!mParserBlockingRequest->mLoading &&
mParserBlockingRequest->IsReadyToRun() &&
ReadyToExecuteScripts()) {
request.swap(mParserBlockingRequest);
UnblockParser(request);
@@ -1244,18 +1259,18 @@ nsScriptLoader::ProcessPendingRequests()
while (ReadyToExecuteScripts() &&
!mXSLTRequests.isEmpty() &&
!mXSLTRequests.getFirst()->mLoading) {
mXSLTRequests.getFirst()->IsReadyToRun()) {
request = mXSLTRequests.StealFirst();
ProcessRequest(request);
}
while (mEnabled && !mLoadedAsyncRequests.isEmpty()) {
request = mLoadedAsyncRequests.StealFirst();
ParseOffThreadOrProcessRequest(request);
CompileOffThreadOrProcessRequest(request);
}
while (mEnabled && !mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
!mNonAsyncExternalScriptInsertedRequests.getFirst()->mLoading) {
mNonAsyncExternalScriptInsertedRequests.getFirst()->IsReadyToRun()) {
// Violate the HTML5 spec and execute these in the insertion order in
// order to make LABjs and the "order" plug-in for RequireJS work with
// their Gecko-sniffed code path. See
@@ -1265,7 +1280,7 @@ nsScriptLoader::ProcessPendingRequests()
}
if (mDocumentParsingDone && mXSLTRequests.isEmpty()) {
while (!mDeferRequests.isEmpty() && !mDeferRequests.getFirst()->mLoading) {
while (!mDeferRequests.isEmpty() && mDeferRequests.getFirst()->IsReadyToRun()) {
request = mDeferRequests.StealFirst();
ProcessRequest(request);
}
@@ -1277,14 +1292,18 @@ nsScriptLoader::ProcessPendingRequests()
child->RemoveExecuteBlocker();
}
if (mDocumentParsingDone && mDocument && !mParserBlockingRequest &&
mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
mXSLTRequests.isEmpty() && mDeferRequests.isEmpty() &&
MaybeRemovedDeferRequests()) {
return ProcessPendingRequests();
}
if (mDocumentParsingDone && mDocument &&
!mParserBlockingRequest && mLoadingAsyncRequests.isEmpty() &&
mLoadedAsyncRequests.isEmpty() &&
mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
mXSLTRequests.isEmpty() && mDeferRequests.isEmpty()) {
if (MaybeRemovedDeferRequests()) {
return ProcessPendingRequests();
}
// No more pending scripts; time to unblock onload.
// OK to unblock onload synchronously here, since callers must be
// prepared for the world changing anyway.
@@ -1632,7 +1651,7 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
"aRequest should be pending!");
// Mark this as loaded
aRequest->mLoading = false;
aRequest->mProgress = nsScriptLoadRequest::Progress_DoneLoading;
// And if it's async, move it to the loaded list. aRequest->mIsAsync really
// _should_ be in a list, but the consequences if it's not are bad enough we
@@ -1701,7 +1720,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
sriMetadata);
request->mURI = aURI;
request->mIsInline = false;
request->mLoading = true;
request->mProgress = nsScriptLoadRequest::Progress_Loading;
request->mReferrerPolicy = aReferrerPolicy;
nsresult rv = StartLoad(request, aType, aScriptFromHead);
+20 -3
View File
@@ -60,7 +60,7 @@ public:
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity)
: mElement(aElement),
mLoading(true),
mProgress(Progress_Loading),
mIsInline(true),
mHasSourceMapURL(false),
mIsDefer(false),
@@ -110,11 +110,28 @@ public:
return mOffThreadToken ? &mOffThreadToken : nullptr;
}
enum Progress {
Progress_Loading,
Progress_DoneLoading,
Progress_Compiling,
Progress_DoneCompiling
};
bool IsReadyToRun() {
return mProgress == Progress_DoneLoading ||
mProgress == Progress_DoneCompiling;
}
bool IsDoneLoading() {
return mProgress == Progress_DoneLoading;
}
bool InCompilingStage() {
return (mProgress == Progress_Compiling) || (mProgress == Progress_DoneCompiling);
}
using super::getNext;
using super::isInList;
nsCOMPtr<nsIScriptElement> mElement;
bool mLoading; // Are we still waiting for a load to complete?
Progress mProgress; // Are we still waiting for a load to complete?
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mIsDefer; // True if we live in mDeferRequests.
@@ -455,7 +472,7 @@ private:
nsresult AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest);
nsresult ProcessRequest(nsScriptLoadRequest* aRequest);
nsresult ParseOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest);
nsresult CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest);
void FireScriptAvailable(nsresult aResult,
nsScriptLoadRequest* aRequest);
void FireScriptEvaluated(nsresult aResult,
+14 -8
View File
@@ -682,9 +682,10 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
if (!baseCaps.alpha)
baseCaps.premultAlpha = true;
if (gl->IsANGLE()) {
if (gl->IsANGLE() || gl->GetContextType() == GLContextType::GLX) {
// We can't use no-alpha formats on ANGLE yet because of:
// https://code.google.com/p/angleproject/issues/detail?id=764
// GLX only supports GL_RGBA pixmaps as well.
baseCaps.alpha = true;
}
@@ -887,6 +888,11 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
}
// increment the generation number - Do this early because later
// in CreateOffscreenGL(), "default" objects are created that will
// pick up the old generation.
++mGeneration;
// Get some prefs for some preferred/overriden things
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
@@ -930,16 +936,13 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
mResetLayer = true;
mOptionsFrozen = true;
// increment the generation number
++mGeneration;
// Update our internal stuff:
if (gl->WorkAroundDriverBugs() && gl->IsANGLE()) {
if (gl->WorkAroundDriverBugs()) {
if (!mOptions.alpha && gl->Caps().alpha)
mNeedsFakeNoAlpha = true;
// ANGLE doesn't quite handle this properly.
if (gl->Caps().depth && !gl->Caps().stencil)
if (gl->Caps().depth && !gl->Caps().stencil && gl->IsANGLE())
mNeedsFakeNoStencil = true;
}
@@ -1808,8 +1811,11 @@ WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
GLenum format, GLenum type,
mozilla::dom::Element& elt)
{
if (type == LOCAL_GL_HALF_FLOAT_OES)
if (type == LOCAL_GL_HALF_FLOAT_OES &&
!gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float))
{
type = LOCAL_GL_HALF_FLOAT;
}
if (!ValidateTexImageFormatAndType(format, type,
WebGLTexImageFunc::TexImage,
@@ -1948,7 +1954,7 @@ WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xoffset
TexSubImage2D_base(texImageTarget.get(), level, xoffset, yoffset, size.width,
size.height, data->Stride(), format, type, data->GetData(),
byteLength, js::Scalar::MaxTypedArrayViewType, srcFormat,
mPixelStorePremultiplyAlpha);
res.mIsPremultiplied);
}
size_t
+1 -1
View File
@@ -626,7 +626,7 @@ public:
size.width, size.height, data->Stride(), 0,
format, type, data->GetData(), byteLength,
js::Scalar::MaxTypedArrayViewType, srcFormat,
mPixelStorePremultiplyAlpha);
res.mIsPremultiplied);
}
void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
-14
View File
@@ -2479,20 +2479,6 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
return NS_OK;
}
if (!mPixelStorePremultiplyAlpha && res.mIsPremultiplied) {
switch (data->GetFormat()) {
case SurfaceFormat::B8G8R8X8:
// No alpha, so de-facto premult'd.
break;
case SurfaceFormat::B8G8R8A8:
data = gfxUtils::CreateUnpremultipliedDataSurface(data);
break;
default:
MOZ_ASSERT(false, "Format unsupported.");
break;
}
}
// We disallow loading cross-domain images and videos that have not been validated
// with CORS as WebGL textures. The reason for doing that is that timing
// attacks on WebGL shaders are able to retrieve approximations of the
+4
View File
@@ -1080,6 +1080,10 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type,
WebGLTexImageFunc func,
WebGLTexDimensions dims)
{
if (type == LOCAL_GL_HALF_FLOAT_OES) {
type = LOCAL_GL_HALF_FLOAT;
}
if (IsCompressedFunc(func) || IsCopyFunc(func)) {
MOZ_ASSERT(type == LOCAL_GL_NONE && format == LOCAL_GL_NONE);
return true;
+2 -2
View File
@@ -880,8 +880,8 @@ nsXBLPrototypeBinding::Read(nsIObjectInputStream* aStream,
mBaseTag = do_GetAtom(baseTag);
}
aDocument->CreateElem(NS_LITERAL_STRING("binding"), nullptr, kNameSpaceID_XBL,
getter_AddRefs(mBinding));
mBinding = aDocument->CreateElem(NS_LITERAL_STRING("binding"), nullptr,
kNameSpaceID_XBL);
nsCOMPtr<nsIContent> child;
rv = ReadContentNode(aStream, aDocument, aDocument->NodeInfoManager(), getter_AddRefs(child));
+4 -6
View File
@@ -125,15 +125,13 @@ createAndAddToResult(nsIAtom* aName, const nsSubstring& aValue,
"invalid result-holder");
nsIDocument* doc = aResultHolder->OwnerDoc();
nsCOMPtr<nsIContent> elem;
nsresult rv = doc->CreateElem(nsDependentAtomString(aName),
nullptr, kNameSpaceID_None,
getter_AddRefs(elem));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> elem = doc->CreateElem(nsDependentAtomString(aName),
nullptr, kNameSpaceID_None);
NS_ENSURE_TRUE(elem, NS_ERROR_NULL_POINTER);
nsRefPtr<nsTextNode> text = new nsTextNode(doc->NodeInfoManager());
rv = text->SetText(aValue, false);
nsresult rv = text->SetText(aValue, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = elem->AppendChildTo(text, false);
+3 -4
View File
@@ -175,10 +175,9 @@ txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument,
RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
nsGkAtoms::transformiix, namespaceID,
getter_AddRefs(mTextParent));
NS_ENSURE_SUCCESS(rv, rv);
mTextParent =
mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
nsGkAtoms::transformiix, namespaceID);
rv = mDocument->AppendChildTo(mTextParent, true);
+3 -5
View File
@@ -619,11 +619,9 @@ txMozillaXMLOutput::createTxWrapper()
RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> wrapper;
rv = mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
nsGkAtoms::transformiix, namespaceID,
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> wrapper =
mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
nsGkAtoms::transformiix, namespaceID);
uint32_t i, j, childCount = mDocument->GetChildCount();
#ifdef DEBUG
+2 -4
View File
@@ -3736,11 +3736,9 @@ XULDocument::CreateTemplateBuilder(nsIContent* aElement)
getter_AddRefs(bodyContent));
if (! bodyContent) {
nsresult rv =
bodyContent =
document->CreateElem(nsDependentAtomString(nsGkAtoms::treechildren),
nullptr, kNameSpaceID_XUL,
getter_AddRefs(bodyContent));
NS_ENSURE_SUCCESS(rv, rv);
nullptr, kNameSpaceID_XUL);
aElement->AppendChildTo(bodyContent, false);
}
+46 -21
View File
@@ -45,6 +45,7 @@
#include "nsStringFwd.h" // for nsAFlatString
#include "nsStyleUtil.h" // for nsStyleUtil
#include "nsXULAppAPI.h" // for XRE_GetProcessType
#include "nsIPlaintextEditor.h" // for editor flags
using namespace mozilla;
using namespace mozilla::dom;
@@ -596,18 +597,24 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
// Ignore pending dictionary fetchers by increasing this number.
mDictionaryFetcherGroup++;
if (mPreferredLang.IsEmpty() ||
!mPreferredLang.Equals(aDictionary, nsCaseInsensitiveStringComparator())) {
// When user sets dictionary manually, we store this value associated
// with editor url, if it doesn't match the document language exactly.
// For example on "en" sites, we need to store "en-GB", otherwise
// the language might jump back to en-US although the user explicitly
// chose otherwise.
StoreCurrentDictionary(mEditor, aDictionary);
} else {
// If user sets a dictionary matching the language defined by
// document, we consider content pref has been canceled, and we clear it.
ClearCurrentDictionary(mEditor);
uint32_t flags = 0;
mEditor->GetFlags(&flags);
if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
if (mPreferredLang.IsEmpty() ||
!mPreferredLang.Equals(aDictionary, nsCaseInsensitiveStringComparator())) {
// When user sets dictionary manually, we store this value associated
// with editor url.
StoreCurrentDictionary(mEditor, aDictionary);
} else {
// If user sets a dictionary matching (even partially), lang defined by
// document, we consider content pref has been canceled, and we clear it.
ClearCurrentDictionary(mEditor);
}
// Also store it in as a preference. It will be used as a default value
// when everything else fails but we don't want this for mail composer
// because it has spellchecked dictionary settings in Preferences.
Preferences::SetString("spellchecker.dictionary", aDictionary);
}
}
return mSpellChecker->SetCurrentDictionary(aDictionary);
@@ -685,6 +692,18 @@ nsEditorSpellCheck::UpdateCurrentDictionary(nsIEditorSpellCheckCallback* aCallba
NS_ENSURE_SUCCESS(rv, rv);
rootContent = do_QueryInterface(rootElement);
}
// Try to get topmost document's document element for embedded mail editor.
uint32_t flags = 0;
mEditor->GetFlags(&flags);
if (flags & nsIPlaintextEditor::eEditorMailMask) {
nsCOMPtr<nsIDocument> ownerDoc = rootContent->OwnerDoc();
NS_ENSURE_TRUE(ownerDoc, NS_ERROR_FAILURE);
nsIDocument* parentDoc = ownerDoc->GetParentDocument();
if (parentDoc) {
rootContent = do_QueryInterface(parentDoc->GetDocumentElement());
}
}
NS_ENSURE_TRUE(rootContent, NS_ERROR_FAILURE);
nsRefPtr<DictionaryFetcher> fetcher =
@@ -747,16 +766,22 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
// If we successfully fetched a dictionary from content prefs, do not go
// further. Use this exact dictionary.
nsAutoString dictName;
dictName.Assign(aFetcher->mDictionary);
if (!dictName.IsEmpty()) {
if (NS_SUCCEEDED(SetCurrentDictionary(dictName))) {
// We take an early exit here, so clear the suggested word list.
DeleteSuggestedWordList();
return NS_OK;
uint32_t flags;
mEditor->GetFlags(&flags);
if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
dictName.Assign(aFetcher->mDictionary);
if (!dictName.IsEmpty()) {
if (NS_SUCCEEDED(SetCurrentDictionary(dictName))) {
// We take an early exit here, so let's not forget to clear the word
// list.
DeleteSuggestedWordList();
return NS_OK;
}
// May be dictionary was uninstalled ?
// Clear the content preference and continue.
ClearCurrentDictionary(mEditor);
}
// Maybe the dictionary was uninstalled ?
// Clear the content preference and continue.
ClearCurrentDictionary(mEditor);
}
// Priority 2:
+2 -5
View File
@@ -4619,11 +4619,8 @@ nsEditor::CreateHTMLContent(nsIAtom* aTag)
return nullptr;
}
nsCOMPtr<nsIContent> ret;
nsresult res = doc->CreateElem(nsDependentAtomString(aTag), nullptr,
kNameSpaceID_XHTML, getter_AddRefs(ret));
NS_ENSURE_SUCCESS(res, nullptr);
return dont_AddRef(ret.forget().take()->AsElement());
return doc->CreateElem(nsDependentAtomString(aTag), nullptr,
kNameSpaceID_XHTML);
}
nsresult
+2 -2
View File
@@ -1766,7 +1766,7 @@ DrawTargetCG::Init(BackendType aType,
assert(mCg);
if (!mCg) {
gfxCriticalError() << "Failed to create CG context";
gfxCriticalError() << "Failed to create CG context" << mSize << ", " << aStride;
return false;
}
@@ -1868,7 +1868,7 @@ DrawTargetCG::Init(CGContextRef cgContext, const IntSize &aSize)
assert(mCg);
if (!mCg) {
gfxCriticalError() << "Invalid CG context at Init";
gfxCriticalError() << "Invalid CG context at Init " << aSize;
return false;
}
+41 -15
View File
@@ -455,6 +455,17 @@ private:
double mY;
};
static inline void
CairoPatternAddGradientStop(cairo_pattern_t* aPattern,
const GradientStop &aStop,
Float aNudge = 0)
{
cairo_pattern_add_color_stop_rgba(aPattern, aStop.offset + aNudge,
aStop.color.r, aStop.color.g, aStop.color.b,
aStop.color.a);
}
// Never returns nullptr. As such, you must always pass in Cairo-compatible
// patterns, most notably gradients with a GradientStopCairo.
// The pattern returned must have cairo_pattern_destroy() called on it by the
@@ -463,7 +474,9 @@ private:
// lifetime of the cairo_pattern_t returned must not exceed the lifetime of the
// Pattern passed in.
static cairo_pattern_t*
GfxPatternToCairoPattern(const Pattern& aPattern, Float aAlpha)
GfxPatternToCairoPattern(const Pattern& aPattern,
Float aAlpha,
const Matrix& aTransform)
{
cairo_pattern_t* pat;
const Matrix* matrix = nullptr;
@@ -511,10 +524,7 @@ GfxPatternToCairoPattern(const Pattern& aPattern, Float aAlpha)
const std::vector<GradientStop>& stops = cairoStops->GetStops();
for (size_t i = 0; i < stops.size(); ++i) {
const GradientStop& stop = stops[i];
cairo_pattern_add_color_stop_rgba(pat, stop.offset, stop.color.r,
stop.color.g, stop.color.b,
stop.color.a);
CairoPatternAddGradientStop(pat, stops[i]);
}
break;
@@ -534,10 +544,7 @@ GfxPatternToCairoPattern(const Pattern& aPattern, Float aAlpha)
const std::vector<GradientStop>& stops = cairoStops->GetStops();
for (size_t i = 0; i < stops.size(); ++i) {
const GradientStop& stop = stops[i];
cairo_pattern_add_color_stop_rgba(pat, stop.offset, stop.color.r,
stop.color.g, stop.color.b,
stop.color.a);
CairoPatternAddGradientStop(pat, stops[i]);
}
break;
@@ -649,6 +656,23 @@ DrawTargetCairo::GetSize()
return mSize;
}
SurfaceFormat
GfxFormatForCairoSurface(cairo_surface_t* surface)
{
cairo_surface_type_t type = cairo_surface_get_type(surface);
if (type == CAIRO_SURFACE_TYPE_IMAGE) {
return CairoFormatToGfxFormat(cairo_image_surface_get_format(surface));
}
#ifdef CAIRO_HAS_XLIB_SURFACE
// xlib is currently the only Cairo backend that creates 16bpp surfaces
if (type == CAIRO_SURFACE_TYPE_XLIB &&
cairo_xlib_surface_get_depth(surface) == 16) {
return SurfaceFormat::R5G6B5;
}
#endif
return CairoContentToGfxFormat(cairo_surface_get_content(surface));
}
already_AddRefed<SourceSurface>
DrawTargetCairo::Snapshot()
{
@@ -673,6 +697,7 @@ DrawTargetCairo::LockBits(uint8_t** aData, IntSize* aSize,
{
if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
WillChange();
Flush();
mLockedBits = cairo_image_surface_get_data(mSurface);
*aData = mLockedBits;
@@ -690,6 +715,7 @@ DrawTargetCairo::ReleaseBits(uint8_t* aData)
{
MOZ_ASSERT(mLockedBits == aData);
mLockedBits = nullptr;
cairo_surface_mark_dirty(mSurface);
}
void
@@ -868,7 +894,7 @@ DrawTargetCairo::DrawPattern(const Pattern& aPattern,
AutoClearDeviceOffset clear(aPattern);
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha, GetTransform());
if (!pat) {
return;
}
@@ -1151,7 +1177,7 @@ DrawTargetCairo::FillGlyphs(ScaledFont *aFont,
ScaledFontBase* scaledFont = static_cast<ScaledFontBase*>(aFont);
cairo_set_scaled_font(mContext, scaledFont->GetCairoScaledFont());
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha, GetTransform());
if (!pat)
return;
@@ -1190,12 +1216,12 @@ DrawTargetCairo::Mask(const Pattern &aSource,
cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
cairo_pattern_t* source = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
cairo_pattern_t* source = GfxPatternToCairoPattern(aSource, aOptions.mAlpha, GetTransform());
if (!source) {
return;
}
cairo_pattern_t* mask = GfxPatternToCairoPattern(aMask, aOptions.mAlpha);
cairo_pattern_t* mask = GfxPatternToCairoPattern(aMask, aOptions.mAlpha, GetTransform());
if (!mask) {
cairo_pattern_destroy(source);
return;
@@ -1231,7 +1257,7 @@ DrawTargetCairo::MaskSurface(const Pattern &aSource,
cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
cairo_pattern_t* pat = GfxPatternToCairoPattern(aSource, aOptions.mAlpha);
cairo_pattern_t* pat = GfxPatternToCairoPattern(aSource, aOptions.mAlpha, GetTransform());
if (!pat) {
return;
}
@@ -1513,7 +1539,7 @@ DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFo
}
}
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar) << " format " << (int)aFormat;
return nullptr;
}
+3 -3
View File
@@ -73,7 +73,7 @@ public:
HRESULT hr = mDT->mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpTexture));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1 CreateTexture2D failure " << size << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1 CreateTexture2D failure " << size << " Code: " << hexa(hr) << " format " << (int)format;
return;
}
mDT->mDevice->CopyResource(tmpTexture, mDT->mTexture);
@@ -323,7 +323,7 @@ DrawTargetD2D::GetBitmapForSurface(SourceSurface *aSurface,
}
if (FAILED(hr)) {
IntSize size(sourceRect.width, sourceRect.height);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1CreateBitmap failure " << size << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(size))) << "[D2D] 1CreateBitmap failure " << size << " Code: " << hexa(hr) << " format " << (int)srcSurf->GetFormat();
return nullptr;
}
@@ -1401,7 +1401,7 @@ DrawTargetD2D::Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
hr = device->QueryInterface((ID3D10Device1**)byRef(mDevice));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to get D3D10 device from texture.";
gfxCriticalError() << "Failed to get D3D10 device from texture." << " format " << (int)aFormat;
return false;
}
+20 -10
View File
@@ -655,7 +655,7 @@ DrawTargetD2D1::CreateSourceSurfaceFromData(unsigned char *aData,
byRef(bitmap));
if (FAILED(hr) || !bitmap) {
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D2D1.1] 1CreateBitmap failure " << aSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D2D1.1] 1CreateBitmap failure " << aSize << " Code: " << hexa(hr) << " format " << (int)aFormat;
return nullptr;
}
@@ -741,10 +741,15 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
{
HRESULT hr;
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
ID2D1Device* device = Factory::GetD2D1Device();
if (!device) {
return false;
}
hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxCriticalError() <<"[D2D1.1] 1Failed to create a DeviceContext, code: " << hexa(hr);
gfxCriticalError() <<"[D2D1.1] 1Failed to create a DeviceContext, code: " << hexa(hr) << " format " << (int)aFormat;
return false;
}
@@ -765,7 +770,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = mDC->CreateBitmapFromDxgiSurface(dxgiSurface, props, (ID2D1Bitmap1**)byRef(mBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hexa(hr);
gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hexa(hr) << " format " << (int)aFormat;
return false;
}
@@ -808,10 +813,15 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
{
HRESULT hr;
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
ID2D1Device* device = Factory::GetD2D1Device();
if (!device) {
return false;
}
hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxCriticalError() <<"[D2D1.1] 2Failed to create a DeviceContext, code: " << hexa(hr);
gfxCriticalError() <<"[D2D1.1] 2Failed to create a DeviceContext, code: " << hexa(hr) << " format " << (int)aFormat;
return false;
}
@@ -831,7 +841,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << aSize << " Code: " << hexa(hr);
gfxCriticalError() << "[D2D1.1] 3CreateBitmap failure " << aSize << " Code: " << hexa(hr) << " format " << (int)aFormat;
return false;
}
@@ -984,7 +994,7 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
if (!IsOperatorBoundByMask(aOp)) {
HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 6CreateBitmap failure " << mSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 6CreateBitmap failure " << mSize << " Code: " << hexa(hr) << " format " << (int)mFormat;
// For now, crash in this scenario; this should happen because tmpBitmap is
// null and CopyFromBitmap call below dereferences it.
// return;
@@ -1022,7 +1032,7 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
RefPtr<ID2D1Bitmap> tmpBitmap;
HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 5CreateBitmap failure " << mSize << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D2D1.1] 5CreateBitmap failure " << mSize << " Code: " << hexa(hr) << " format " << (int)mFormat;
// For now, crash in this scenario; this should happen because tmpBitmap is
// null and CopyFromBitmap call below dereferences it.
// return;
@@ -1465,7 +1475,7 @@ DrawTargetD2D1::OptimizeSourceSurface(SourceSurface* aSurface) const
byRef(bitmap));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(data->GetSize()))) << "[D2D1.1] 4CreateBitmap failure " << data->GetSize() << " Code: " << hexa(hr);
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(data->GetSize()))) << "[D2D1.1] 4CreateBitmap failure " << data->GetSize() << " Code: " << hexa(hr) << " format " << (int)data->GetFormat();
}
}
+4 -1
View File
@@ -729,7 +729,10 @@ Factory::SetDirect3D11Device(ID3D11Device *aDevice)
RefPtr<IDXGIDevice> device;
aDevice->QueryInterface((IDXGIDevice**)byRef(device));
factory->CreateDevice(device, &mD2D1Device);
HRESULT hr = factory->CreateDevice(device, &mD2D1Device);
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1] Failed to create gfx factory's D2D1 device, code: " << hexa(hr);
}
}
ID3D11Device*
+3 -13
View File
@@ -140,8 +140,7 @@ GfxFormatToCairoFormat(SurfaceFormat format)
case SurfaceFormat::R5G6B5:
return CAIRO_FORMAT_RGB16_565;
default:
gfxWarning() << "Unknown image format";
MOZ_ASSERT(false, "Unknown image format");
gfxCriticalError() << "Unknown image format " << (int)format;
return CAIRO_FORMAT_ARGB32;
}
}
@@ -159,8 +158,7 @@ GfxFormatToCairoContent(SurfaceFormat format)
case SurfaceFormat::A8:
return CAIRO_CONTENT_ALPHA;
default:
gfxWarning() << "Unknown image format";
MOZ_ASSERT(false, "Unknown image format");
gfxCriticalError() << "Unknown image content format " << (int)format;
return CAIRO_CONTENT_COLOR_ALPHA;
}
}
@@ -235,15 +233,7 @@ CairoFormatToGfxFormat(cairo_format_t format)
}
}
static inline SurfaceFormat
GfxFormatForCairoSurface(cairo_surface_t* surface)
{
if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE) {
return CairoFormatToGfxFormat(cairo_image_surface_get_format(surface));
}
return CairoContentToGfxFormat(cairo_surface_get_content(surface));
}
SurfaceFormat GfxFormatForCairoSurface(cairo_surface_t* surface);
static inline void
GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
+15
View File
@@ -32,6 +32,7 @@
#define MOZ_GL_DEBUG 1
#endif
#include "../../mfbt/Maybe.h"
#include "../../mfbt/RefPtr.h"
#include "../../mfbt/UniquePtr.h"
@@ -321,6 +322,13 @@ public:
virtual bool IsCurrent() = 0;
/**
* Get the default framebuffer for this context.
*/
virtual GLuint GetDefaultFramebuffer() {
return 0;
}
protected:
bool mInitialized;
bool mIsOffscreen;
@@ -3270,6 +3278,13 @@ public:
GLuint GetFB();
/*
* Retrieves the size of the native windowing system drawable.
*/
virtual Maybe<gfx::IntSize> GetTargetSize() {
return Maybe<gfx::IntSize>();
};
private:
void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
switch (precisiontype) {
+9
View File
@@ -50,6 +50,15 @@ public:
virtual bool SwapBuffers() override;
// Overrides the current GLXDrawable backing the context and makes the
// context current.
bool OverrideDrawable(GLXDrawable drawable);
// Undoes the effect of a drawable override.
bool RestoreDrawable();
virtual Maybe<gfx::IntSize> GetTargetSize() override;
private:
friend class GLContextProviderGLX;
+30
View File
@@ -30,6 +30,7 @@
#include "GLContextGLX.h"
#include "gfxUtils.h"
#include "gfx2DGlue.h"
#include "GLScreenBuffer.h"
#ifdef MOZ_WIDGET_GTK
#include "gfxPlatformGtk.h"
@@ -907,6 +908,35 @@ GLContextGLX::SwapBuffers()
return true;
}
Maybe<gfx::IntSize>
GLContextGLX::GetTargetSize()
{
unsigned int width = 0, height = 0;
Window root;
int x, y;
unsigned int border, depth;
XGetGeometry(mDisplay, mDrawable, &root, &x, &y, &width, &height,
&border, &depth);
Maybe<gfx::IntSize> size;
size.emplace(width, height);
return size;
}
bool
GLContextGLX::OverrideDrawable(GLXDrawable drawable)
{
if (Screen())
Screen()->AssureBlitted();
Bool result = mGLX->xMakeCurrent(mDisplay, drawable, mContext);
return result;
}
bool
GLContextGLX::RestoreDrawable()
{
return mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
}
GLContextGLX::GLContextGLX(
const SurfaceCaps& caps,
GLContext* shareContext,
+2 -1
View File
@@ -792,7 +792,8 @@ ReadBuffer::SetReadBuffer(GLenum userMode) const
switch (userMode) {
case LOCAL_GL_BACK:
internalMode = (mFB == 0) ? LOCAL_GL_BACK
case LOCAL_GL_FRONT:
internalMode = (mFB == 0) ? userMode
: LOCAL_GL_COLOR_ATTACHMENT0;
break;
+110
View File
@@ -0,0 +1,110 @@
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
/* 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/. */
#include "SharedSurfaceGLX.h"
#include "gfxXlibSurface.h"
#include "GLXLibrary.h"
#include "GLContextProvider.h"
#include "GLContextGLX.h"
#include "GLScreenBuffer.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/ShadowLayerUtilsX11.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/X11Util.h"
namespace mozilla {
namespace gl {
/* static */
UniquePtr<SharedSurface_GLXDrawable>
SharedSurface_GLXDrawable::Create(GLContext* prodGL,
const SurfaceCaps& caps,
const gfx::IntSize& size,
bool deallocateClient,
bool inSameProcess)
{
UniquePtr<SharedSurface_GLXDrawable> ret;
Display* display = DefaultXDisplay();
Screen* screen = XDefaultScreenOfDisplay(display);
Visual* visual = gfxXlibSurface::FindVisual(screen, gfxImageFormat::ARGB32);
RefPtr<gfxXlibSurface> surf = gfxXlibSurface::Create(screen, visual, size);
if (!deallocateClient)
surf->ReleasePixmap();
ret.reset(new SharedSurface_GLXDrawable(prodGL, size, inSameProcess, surf));
return Move(ret);
}
SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
const gfx::IntSize& size,
bool inSameProcess,
const RefPtr<gfxXlibSurface>& xlibSurface)
: SharedSurface(SharedSurfaceType::GLXDrawable,
AttachmentType::Screen,
gl,
size,
true,
true)
, mXlibSurface(xlibSurface)
, mInSameProcess(inSameProcess)
{}
void
SharedSurface_GLXDrawable::Fence()
{
mGL->MakeCurrent();
mGL->fFlush();
}
void
SharedSurface_GLXDrawable::LockProdImpl()
{
mGL->Screen()->SetReadBuffer(LOCAL_GL_FRONT);
GLContextGLX::Cast(mGL)->OverrideDrawable(mXlibSurface->GetGLXPixmap());
}
void
SharedSurface_GLXDrawable::UnlockProdImpl()
{
GLContextGLX::Cast(mGL)->RestoreDrawable();
}
bool
SharedSurface_GLXDrawable::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{
if (!mXlibSurface)
return false;
*out_descriptor = layers::SurfaceDescriptorX11(mXlibSurface, mInSameProcess);
return true;
}
/* static */
UniquePtr<SurfaceFactory_GLXDrawable>
SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
{
MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
typedef SurfaceFactory_GLXDrawable ptrT;
UniquePtr<ptrT> ret(new ptrT(prodGL, caps, allocator,
flags & ~layers::TextureFlags::ORIGIN_BOTTOM_LEFT));
return Move(ret);
}
UniquePtr<SharedSurface>
SurfaceFactory_GLXDrawable::CreateShared(const gfx::IntSize& size)
{
bool deallocateClient = !!(mFlags & layers::TextureFlags::DEALLOCATE_CLIENT);
return SharedSurface_GLXDrawable::Create(mGL, mCaps, size, deallocateClient,
mAllocator->IsSameProcess());
}
} // namespace gl
} // namespace mozilla
+67
View File
@@ -0,0 +1,67 @@
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
/* 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 SHARED_SURFACE_GLX_H_
#define SHARED_SURFACE_GLX_H_
#include "SharedSurface.h"
#include "mozilla/RefPtr.h"
class gfxXlibSurface;
namespace mozilla {
namespace gl {
class SharedSurface_GLXDrawable
: public SharedSurface
{
public:
static UniquePtr<SharedSurface_GLXDrawable> Create(GLContext* prodGL,
const SurfaceCaps& caps,
const gfx::IntSize& size,
bool deallocateClient,
bool inSameProcess);
virtual void Fence() override;
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
private:
SharedSurface_GLXDrawable(GLContext* gl,
const gfx::IntSize& size,
bool inSameProcess,
const RefPtr<gfxXlibSurface>& xlibSurface);
RefPtr<gfxXlibSurface> mXlibSurface;
bool mInSameProcess;
};
class SurfaceFactory_GLXDrawable
: public SurfaceFactory
{
public:
static UniquePtr<SurfaceFactory_GLXDrawable> Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
private:
SurfaceFactory_GLXDrawable(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::GLXDrawable, prodGL, caps, allocator, flags)
{ }
};
} // namespace gl
} // namespace mozilla
#endif // SHARED_SURFACE_GLX_H_
+1
View File
@@ -76,6 +76,7 @@ enum class SharedSurfaceType : uint8_t {
DXGLInterop2,
Gralloc,
IOSurface,
GLXDrawable,
Max
};
+4
View File
@@ -108,6 +108,10 @@ elif gl_provider == 'GLX':
# as it includes X11 headers which cause conflicts.
SOURCES += [
'GLContextProviderGLX.cpp',
'SharedSurfaceGLX.cpp'
]
EXPORTS += [
'SharedSurfaceGLX.h'
]
else:
UNIFIED_SOURCES += [
-10
View File
@@ -365,16 +365,6 @@ public:
*/
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
/**
* Setup the viewport and projection matrix for rendering to a target of the
* given dimensions. The size and transform here will override those set in
* BeginFrame. BeginFrame sets a size and transform for the default render
* target, usually the screen. Calling this method prepares the compositor to
* render using a different viewport (that is, size and transform), usually
* associated with a new render target.
*/
virtual void PrepareViewport(const gfx::IntSize& aSize) = 0;
/**
* Whether textures created by this compositor can receive partial updates.
*/
+1 -2
View File
@@ -318,8 +318,7 @@ DIBTextureHost::DIBTextureHost(TextureFlags aFlags,
MOZ_ASSERT(mSurface);
mSize = mSurface->GetSize();
mFormat = ImageFormatToSurfaceFormat(
gfxPlatform::GetPlatform()->OptimalFormatForContent(mSurface->GetContentType()));
mFormat = mSurface->GetSurfaceFormat();
}
void
-2
View File
@@ -110,8 +110,6 @@ public:
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) override { }
virtual void PrepareViewport(const gfx::IntSize& aSize) override { }
#ifdef MOZ_DUMP_PAINTING
virtual const char* Name() const override { return "Basic"; }
#endif // MOZ_DUMP_PAINTING
+8
View File
@@ -32,6 +32,11 @@
#include "SharedSurfaceIO.h"
#endif
#ifdef GL_PROVIDER_GLX
#include "GLXLibrary.h"
#include "SharedSurfaceGLX.h"
#endif
using namespace mozilla::gfx;
using namespace mozilla::gl;
@@ -86,6 +91,9 @@ ClientCanvasLayer::Initialize(const Data& aData)
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags);
#elif defined(MOZ_WIDGET_GONK)
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
#elif defined(GL_PROVIDER_GLX)
if (sGLXLibrary.UseTextureFromPixmap())
factory = SurfaceFactory_GLXDrawable::Create(mGLContext, caps, forwarder, mFlags);
#else
if (mGLContext->GetContextType() == GLContextType::EGL) {
if (XRE_IsParentProcess()) {
+33 -1
View File
@@ -716,6 +716,7 @@ public:
explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin)
: mClearOnBind(false)
, mOrigin(aOrigin)
, mHasComplexProjection(false)
{}
virtual ~CompositingRenderTarget() {}
@@ -731,14 +732,45 @@ public:
mClearOnBind = true;
}
const gfx::IntPoint& GetOrigin() { return mOrigin; }
const gfx::IntPoint& GetOrigin() const { return mOrigin; }
gfx::IntRect GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
/**
* If a Projection matrix is set, then it is used for rendering to
* this render target instead of generating one. If no explicit
* projection is set, Compositors are expected to generate an
* orthogonal maaping that maps 0..1 to the full size of the render
* target.
*/
bool HasComplexProjection() const { return mHasComplexProjection; }
void ClearProjection() { mHasComplexProjection = false; }
void SetProjection(const gfx::Matrix4x4& aNewMatrix, bool aEnableDepthBuffer,
float aZNear, float aZFar)
{
mProjectionMatrix = aNewMatrix;
mEnableDepthBuffer = aEnableDepthBuffer;
mZNear = aZNear;
mZFar = aZFar;
mHasComplexProjection = true;
}
void GetProjection(gfx::Matrix4x4& aMatrix, bool& aEnableDepth, float& aZNear, float& aZFar)
{
MOZ_ASSERT(mHasComplexProjection);
aMatrix = mProjectionMatrix;
aEnableDepth = mEnableDepthBuffer;
aZNear = mZNear;
aZFar = mZFar;
}
protected:
bool mClearOnBind;
private:
gfx::IntPoint mOrigin;
gfx::Matrix4x4 mProjectionMatrix;
float mZNear, mZFar;
bool mHasComplexProjection;
bool mEnableDepthBuffer;
};
/**
+33 -14
View File
@@ -534,9 +534,20 @@ CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget)
MOZ_ASSERT(aRenderTarget);
CompositingRenderTargetD3D11* newRT =
static_cast<CompositingRenderTargetD3D11*>(aRenderTarget);
mCurrentRT = newRT;
mCurrentRT->BindRenderTarget(mContext);
PrepareViewport(newRT->GetSize());
if (mCurrentRT != newRT) {
mCurrentRT = newRT;
mCurrentRT->BindRenderTarget(mContext);
}
if (newRT->HasComplexProjection()) {
gfx::Matrix4x4 projection;
bool depthEnable;
float zNear, zFar;
newRT->GetProjection(projection, depthEnable, zNear, zFar);
PrepareViewport(newRT->GetSize(), projection, zNear, zFar);
} else {
PrepareViewport(newRT->GetSize());
}
}
void
@@ -1145,16 +1156,6 @@ CompositorD3D11::EndFrame()
void
CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
{
D3D11_VIEWPORT viewport;
viewport.MaxDepth = 1.0f;
viewport.MinDepth = 0.0f;
viewport.Width = aSize.width;
viewport.Height = aSize.height;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
mContext->RSSetViewports(1, &viewport);
// This view matrix translates coordinates from 0..width and 0..height to
// -1..1 on the X axis, and -1..1 on the Y axis (flips the Y coordinate)
Matrix viewMatrix = Matrix::Translation(-1.0, 1.0);
@@ -1164,7 +1165,25 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
Matrix4x4 projection = Matrix4x4::From2D(viewMatrix);
projection._33 = 0.0f;
memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection));
PrepareViewport(aSize, projection, 0.0f, 1.0f);
}
void
CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix4x4& aProjection,
float aZNear, float aZFar)
{
D3D11_VIEWPORT viewport;
viewport.MaxDepth = aZFar;
viewport.MinDepth = aZNear;
viewport.Width = aSize.width;
viewport.Height = aSize.height;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
mContext->RSSetViewports(1, &viewport);
memcpy(&mVSConstants.projection, &aProjection._11, sizeof(mVSConstants.projection));
}
void
+3 -1
View File
@@ -129,7 +129,9 @@ public:
* Setup the viewport and projection matrix for rendering
* to a window of the given dimensions.
*/
virtual void PrepareViewport(const gfx::IntSize& aSize) override;
virtual void PrepareViewport(const gfx::IntSize& aSize);
virtual void PrepareViewport(const gfx::IntSize& aSize, const gfx::Matrix4x4& aProjection,
float aZNear, float aZFar);
virtual bool SupportsPartialTextureUpdate() override { return true; }
+1 -1
View File
@@ -71,7 +71,7 @@ public:
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override {}
virtual void PrepareViewport(const gfx::IntSize& aSize) override;
virtual void PrepareViewport(const gfx::IntSize& aSize);
virtual bool SupportsPartialTextureUpdate() override{ return true; }
+14 -1
View File
@@ -62,9 +62,11 @@ GetXRenderPictFormatFromId(Display* aDisplay, PictFormat aFormatId)
return XRenderFindFormat(aDisplay, PictFormatID, &tmplate, 0);
}
SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf)
SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf,
bool aForwardGLX)
: mId(aSurf->XDrawable())
, mSize(aSurf->GetSize())
, mGLXPixmap(None)
{
const XRenderPictFormat *pictFormat = aSurf->XRenderFormat();
if (pictFormat) {
@@ -72,6 +74,10 @@ SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf)
} else {
mFormat = cairo_xlib_surface_get_visual(aSurf->CairoSurface())->visualid;
}
if (aForwardGLX) {
mGLXPixmap = aSurf->GetGLXPixmap();
}
}
SurfaceDescriptorX11::SurfaceDescriptorX11(Drawable aDrawable, XID aFormatID,
@@ -79,6 +85,7 @@ SurfaceDescriptorX11::SurfaceDescriptorX11(Drawable aDrawable, XID aFormatID,
: mId(aDrawable)
, mFormat(aFormatID)
, mSize(aSize)
, mGLXPixmap(None)
{ }
already_AddRefed<gfxXlibSurface>
@@ -100,6 +107,12 @@ SurfaceDescriptorX11::OpenForeign() const
surf = new gfxXlibSurface(display, mId, visual, mSize);
}
#ifdef GL_PROVIDER_GLX
if (mGLXPixmap)
surf->BindGLXPixmap(mGLXPixmap);
#endif
return surf->CairoStatus() ? nullptr : surf.forget();
}
+6 -2
View File
@@ -31,7 +31,7 @@ struct SurfaceDescriptorX11 {
SurfaceDescriptorX11()
{ }
explicit SurfaceDescriptorX11(gfxXlibSurface* aSurf);
explicit SurfaceDescriptorX11(gfxXlibSurface* aSurf, bool aForwardGLX = false);
SurfaceDescriptorX11(Drawable aDrawable, XID aFormatID,
const gfx::IntSize& aSize);
@@ -52,6 +52,7 @@ struct SurfaceDescriptorX11 {
Drawable mId;
XID mFormat; // either a PictFormat or VisualID
gfx::IntSize mSize;
Drawable mGLXPixmap; // used to prevent multiple bindings to the same GLXPixmap in-process
};
} // namespace layers
@@ -67,12 +68,15 @@ struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
WriteParam(aMsg, aParam.mId);
WriteParam(aMsg, aParam.mSize);
WriteParam(aMsg, aParam.mFormat);
WriteParam(aMsg, aParam.mGLXPixmap);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
return (ReadParam(aMsg, aIter, &aResult->mId) &&
ReadParam(aMsg, aIter, &aResult->mSize) &&
ReadParam(aMsg, aIter, &aResult->mFormat));
ReadParam(aMsg, aIter, &aResult->mFormat) &&
ReadParam(aMsg, aIter, &aResult->mGLXPixmap)
);
}
};
@@ -33,11 +33,18 @@ CompositingRenderTargetOGL::BindTexture(GLenum aTextureUnit, GLenum aTextureTarg
void
CompositingRenderTargetOGL::BindRenderTarget()
{
bool needsClear = false;
if (mInitParams.mStatus != InitParams::INITIALIZED) {
InitializeImpl();
if (mInitParams.mInit == INIT_MODE_CLEAR) {
needsClear = true;
mClearOnBind = false;
}
} else {
MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED);
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO);
GLuint fbo = mFBO == 0 ? mGL->GetDefaultFramebuffer() : mFBO;
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fbo);
GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
// The main framebuffer (0) of non-offscreen contexts
@@ -57,14 +64,14 @@ CompositingRenderTargetOGL::BindRenderTarget()
}
}
mCompositor->PrepareViewport(mInitParams.mSize);
needsClear = mClearOnBind;
}
if (mClearOnBind) {
if (needsClear) {
mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height);
mGL->fClearColor(0.0, 0.0, 0.0, 0.0);
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
mClearOnBind = false;
mGL->fClearDepth(0.0);
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
}
}
@@ -83,7 +90,9 @@ CompositingRenderTargetOGL::InitializeImpl()
{
MOZ_ASSERT(mInitParams.mStatus == InitParams::READY);
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO);
//TODO: call mGL->GetBackbufferFB(), use that
GLuint fbo = mFBO == 0 ? mGL->GetDefaultFramebuffer() : mFBO;
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fbo);
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
mInitParams.mFBOTextureTarget,
@@ -101,15 +110,6 @@ CompositingRenderTargetOGL::InitializeImpl()
}
mInitParams.mStatus = InitParams::INITIALIZED;
mCompositor->PrepareViewport(mInitParams.mSize);
mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height);
if (mInitParams.mInit == INIT_MODE_CLEAR) {
mGL->fClearColor(0.0, 0.0, 0.0, 0.0);
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
mClearOnBind = false;
}
}
} // namespace layers
@@ -39,6 +39,8 @@ class CompositingRenderTargetOGL : public CompositingRenderTarget
{
typedef mozilla::gl::GLContext GLContext;
friend class CompositorOGL;
// For lazy initialisation of the GL stuff
struct InitParams
{
+73 -44
View File
@@ -435,43 +435,54 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
}
void
CompositorOGL::PrepareViewport(const gfx::IntSize& aSize)
CompositorOGL::PrepareViewport(CompositingRenderTargetOGL* aRenderTarget)
{
MOZ_ASSERT(aRenderTarget);
const gfx::IntSize& size = aRenderTarget->mInitParams.mSize;
// Set the viewport correctly.
mGLContext->fViewport(0, 0, aSize.width, aSize.height);
mGLContext->fViewport(0, 0, size.width, size.height);
mViewportSize = aSize;
mViewportSize = size;
// We flip the view matrix around so that everything is right-side up; we're
// drawing directly into the window's back buffer, so this keeps things
// looking correct.
// XXX: We keep track of whether the window size changed, so we could skip
// this update if it hadn't changed since the last call.
if (!aRenderTarget->HasComplexProjection()) {
// We flip the view matrix around so that everything is right-side up; we're
// drawing directly into the window's back buffer, so this keeps things
// looking correct.
// XXX: We keep track of whether the window size changed, so we could skip
// this update if it hadn't changed since the last call.
// Matrix to transform (0, 0, aWidth, aHeight) to viewport space (-1.0, 1.0,
// 2, 2) and flip the contents.
Matrix viewMatrix;
if (mGLContext->IsOffscreen() && !gIsGtest) {
// In case of rendering via GL Offscreen context, disable Y-Flipping
viewMatrix.PreTranslate(-1.0, -1.0);
viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
// Matrix to transform (0, 0, aWidth, aHeight) to viewport space (-1.0, 1.0,
// 2, 2) and flip the contents.
Matrix viewMatrix;
if (mGLContext->IsOffscreen() && !gIsGtest) {
// In case of rendering via GL Offscreen context, disable Y-Flipping
viewMatrix.PreTranslate(-1.0, -1.0);
viewMatrix.PreScale(2.0f / float(size.width), 2.0f / float(size.height));
} else {
viewMatrix.PreTranslate(-1.0, 1.0);
viewMatrix.PreScale(2.0f / float(size.width), 2.0f / float(size.height));
viewMatrix.PreScale(1.0f, -1.0f);
}
MOZ_ASSERT(mCurrentRenderTarget, "No destination");
// If we're drawing directly to the window then we want to offset
// drawing by the render offset.
if (!mTarget && mCurrentRenderTarget->IsWindow()) {
viewMatrix.PreTranslate(mRenderOffset.x, mRenderOffset.y);
}
Matrix4x4 matrix3d = Matrix4x4::From2D(viewMatrix);
matrix3d._33 = 0.0f;
mProjMatrix = matrix3d;
mGLContext->fDepthRange(0.0f, 1.0f);
} else {
viewMatrix.PreTranslate(-1.0, 1.0);
viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
viewMatrix.PreScale(1.0f, -1.0f);
// XXX take into account mRenderOffset
bool depthEnable;
float zNear, zFar;
aRenderTarget->GetProjection(mProjMatrix, depthEnable, zNear, zFar);
mGLContext->fDepthRange(zNear, zFar);
}
MOZ_ASSERT(mCurrentRenderTarget, "No destination");
// If we're drawing directly to the window then we want to offset
// drawing by the render offset.
if (!mTarget && mCurrentRenderTarget->IsWindow()) {
viewMatrix.PreTranslate(mRenderOffset.x, mRenderOffset.y);
}
Matrix4x4 matrix3d = Matrix4x4::From2D(viewMatrix);
matrix3d._33 = 0.0f;
mProjMatrix = matrix3d;
}
already_AddRefed<CompositingRenderTarget>
@@ -532,10 +543,14 @@ CompositorOGL::SetRenderTarget(CompositingRenderTarget *aSurface)
= static_cast<CompositingRenderTargetOGL*>(aSurface);
if (mCurrentRenderTarget != surface) {
mCurrentRenderTarget = surface;
mContextStateTracker.PopOGLSection(gl(), "Frame");
if (mCurrentRenderTarget) {
mContextStateTracker.PopOGLSection(gl(), "Frame");
}
mContextStateTracker.PushOGLSection(gl(), "Frame");
surface->BindRenderTarget();
}
PrepareViewport(mCurrentRenderTarget);
}
CompositingRenderTarget*
@@ -634,23 +649,29 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
TexturePoolOGL::Fill(gl());
#endif
mCurrentRenderTarget =
CompositingRenderTargetOGL::RenderTargetForWindow(this,
IntSize(width, height));
mCurrentRenderTarget->BindRenderTarget();
mContextStateTracker.PushOGLSection(gl(), "Frame");
#ifdef DEBUG
mWindowRenderTarget = mCurrentRenderTarget;
#endif
// Default blend function implements "OVER"
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
LOCAL_GL_ONE, LOCAL_GL_ONE);
mGLContext->fEnable(LOCAL_GL_BLEND);
// Make sure SCISSOR is enabled before setting the render target, since the RT
// assumes scissor is enabled while it does clears.
mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
// Prefer the native windowing system's provided window size for the viewport.
IntSize viewportSize = mGLContext->GetTargetSize().valueOr(mWidgetSize);
if (viewportSize != mWidgetSize) {
mGLContext->fScissor(0, 0, viewportSize.width, viewportSize.height);
}
RefPtr<CompositingRenderTargetOGL> rt =
CompositingRenderTargetOGL::RenderTargetForWindow(this, viewportSize);
SetRenderTarget(rt);
#ifdef DEBUG
mWindowRenderTarget = mCurrentRenderTarget;
#endif
if (aClipRectOut && !aClipRectIn) {
aClipRectOut->SetRect(0, 0, width, height);
}
@@ -1395,13 +1416,21 @@ CompositorOGL::EndFrame()
return;
}
mCurrentRenderTarget = nullptr;
if (mTexturePool) {
mTexturePool->EndFrame();
}
mGLContext->SwapBuffers();
// If our window size changed during composition, we should discard the frame.
// We don't need to worry about rescheduling a composite, as widget
// implementations handle this in their expose event listeners.
// See bug 1184534. TODO: implement this for single-buffered targets?
IntSize targetSize = mGLContext->GetTargetSize().valueOr(mViewportSize);
if (!(mCurrentRenderTarget->IsWindow() && targetSize != mViewportSize)) {
mGLContext->SwapBuffers();
}
mCurrentRenderTarget = nullptr;
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
// Unbind all textures
+3 -3
View File
@@ -182,6 +182,7 @@ class CompositorOGL final : public Compositor
typedef mozilla::gl::GLContext GLContext;
friend class GLManagerCompositor;
friend class CompositingRenderTargetOGL;
std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms;
public:
@@ -260,9 +261,6 @@ public:
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) override;
virtual void PrepareViewport(const gfx::IntSize& aSize) override;
#ifdef MOZ_DUMP_PAINTING
virtual const char* Name() const override { return "OGL"; }
#endif // MOZ_DUMP_PAINTING
@@ -327,6 +325,8 @@ private:
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform);
void PrepareViewport(CompositingRenderTargetOGL *aRenderTarget);
/** Widget associated with this compositor */
nsIWidget *mWidget;
gfx::IntSize mWidgetSize;
+11
View File
@@ -33,6 +33,9 @@
#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
#endif
#ifdef GL_PROVIDER_GLX
#include "mozilla/layers/X11TextureHost.h"
#endif
using namespace mozilla::gl;
using namespace mozilla::gfx;
@@ -93,6 +96,14 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
break;
}
#endif
#ifdef GL_PROVIDER_GLX
case SurfaceDescriptor::TSurfaceDescriptorX11: {
const auto& desc = aDesc.get_SurfaceDescriptorX11();
result = new X11TextureHost(aFlags, desc);
break;
}
#endif
default: return nullptr;
}
return result.forget();
+18 -4
View File
@@ -35,6 +35,7 @@
#include "nsString.h" // for nsDependentString
#include "nsTArray.h" // for nsTArray, nsTArray_Impl
#include "nsThreadUtils.h" // for NS_IsMainThread
#include "mozilla/gfx/Logging.h"
#if !XP_MACOSX
#include "gfxPDFSurface.h"
@@ -393,6 +394,8 @@ nsDeviceContext::Init(nsIWidget *aWidget)
already_AddRefed<gfxContext>
nsDeviceContext::CreateRenderingContext()
{
MOZ_ASSERT(mWidth > 0 && mHeight > 0);
nsRefPtr<gfxASurface> printingSurface = mPrintingSurface;
#ifdef XP_MACOSX
// CreateRenderingContext() can be called (on reflow) after EndPage()
@@ -410,6 +413,11 @@ nsDeviceContext::CreateRenderingContext()
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(printingSurface,
gfx::IntSize(mWidth, mHeight));
if (!dt) {
gfxCriticalError() << "Failed to create draw target in device context sized " << mWidth << "x" << mHeight << " and pointers " << hexa(mPrintingSurface) << " and " << hexa(printingSurface);
MOZ_CRASH("Cannot CreateDrawTargetForSurface");
}
#ifdef XP_MACOSX
dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
#endif
@@ -494,7 +502,9 @@ nsDeviceContext::InitForPrinting(nsIDeviceContextSpec *aDevice)
Init(nullptr);
CalcPrintingSize();
if (!CalcPrintingSize()) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@@ -662,11 +672,12 @@ nsDeviceContext::FindScreen(nsIScreen** outScreen)
}
}
void
bool
nsDeviceContext::CalcPrintingSize()
{
if (!mPrintingSurface)
return;
if (!mPrintingSurface) {
return (mWidth > 0 && mHeight > 0);
}
bool inPoints = true;
@@ -716,6 +727,7 @@ nsDeviceContext::CalcPrintingSize()
#endif
default:
gfxCriticalError() << "Printing to unknown surface type " << (int)mPrintingSurface->GetType();
NS_ERROR("trying to print to unknown surface type");
}
@@ -728,6 +740,8 @@ nsDeviceContext::CalcPrintingSize()
mWidth = NSToIntRound(size.width);
mHeight = NSToIntRound(size.height);
}
return (mWidth > 0 && mHeight > 0);
}
bool nsDeviceContext::CheckDPIChange() {
+3 -1
View File
@@ -259,7 +259,9 @@ private:
void ComputeClientRectUsingScreen(nsRect *outRect);
void ComputeFullAreaUsingScreen(nsRect *outRect);
void FindScreen(nsIScreen **outScreen);
void CalcPrintingSize();
// Return false if the surface is not right
bool CalcPrintingSize();
void UpdateAppUnitsForFullZoom();
nscoord mWidth;
+14
View File
@@ -12,6 +12,8 @@
#include "mozilla/MemoryReporting.h"
#include "nsISupportsImpl.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/HelpersCairo.h"
#include "gfx2DGlue.h"
#include "gfxASurface.h"
@@ -209,6 +211,9 @@ gfxASurface::Init(cairo_surface_t* surface, bool existingSurface)
mSurface = surface;
mSurfaceValid = surface && !cairo_surface_status(surface);
if (!mSurfaceValid) {
gfxWarning() << "ASurface Init failed with Cairo status " << cairo_surface_status(surface) << " on " << hexa(surface);
}
if (existingSurface || !mSurfaceValid) {
mFloatingRefs = 0;
@@ -695,6 +700,15 @@ gfxASurface::GetSize() const
return IntSize(-1, -1);
}
SurfaceFormat
gfxASurface::GetSurfaceFormat() const
{
if (!mSurfaceValid) {
return SurfaceFormat::UNKNOWN;
}
return GfxFormatForCairoSurface(mSurface);
}
already_AddRefed<gfxImageSurface>
gfxASurface::GetAsImageSurface()
{
+2
View File
@@ -169,6 +169,8 @@ public:
virtual const mozilla::gfx::IntSize GetSize() const;
virtual mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
void SetOpaqueRect(const gfxRect& aRect);
const gfxRect& GetOpaqueRect() {
+2 -9
View File
@@ -781,7 +781,7 @@ cairo_user_data_key_t kDrawTarget;
already_AddRefed<DrawTarget>
gfxPlatform::CreateDrawTargetForSurface(gfxASurface *aSurface, const IntSize& aSize)
{
SurfaceFormat format = Optimal2DFormatForContent(aSurface->GetContentType());
SurfaceFormat format = aSurface->GetSurfaceFormat();
RefPtr<DrawTarget> drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize, &format);
if (!drawTarget) {
gfxWarning() << "gfxPlatform::CreateDrawTargetForSurface failed in CreateDrawTargetForCairoSurface";
@@ -874,14 +874,7 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
// function will be called for the old user data.
}
SurfaceFormat format;
if (aSurface->GetContentType() == gfxContentType::ALPHA) {
format = SurfaceFormat::A8;
} else if (aSurface->GetContentType() == gfxContentType::COLOR) {
format = SurfaceFormat::B8G8R8X8;
} else {
format = SurfaceFormat::B8G8R8A8;
}
SurfaceFormat format = aSurface->GetSurfaceFormat();
if (aTarget->GetBackendType() == BackendType::CAIRO) {
// If we're going to be used with a CAIRO DrawTarget, then just create a
+4
View File
@@ -6,6 +6,7 @@
#include "gfxWindowsSurface.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/Logging.h"
#include "cairo.h"
#include "cairo-win32.h"
@@ -29,6 +30,9 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, uint32_t flags) :
if (flags & FLAG_FOR_PRINTING) {
Init(cairo_win32_printing_surface_create(mDC));
mForPrinting = true;
if (!mSurfaceValid) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Invalid printing surface";
}
} else
#endif
InitWithDC(flags);
+14 -6
View File
@@ -85,13 +85,13 @@ gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
gfxXlibSurface::~gfxXlibSurface()
{
#if defined(GL_PROVIDER_GLX)
if (mGLXPixmap) {
gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
}
#endif
// gfxASurface's destructor calls RecordMemoryFreed().
if (mPixmapTaken) {
#if defined(GL_PROVIDER_GLX)
if (mGLXPixmap) {
gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
}
#endif
XFreePixmap (mDisplay, mDrawable);
}
}
@@ -276,7 +276,7 @@ void
gfxXlibSurface::Finish()
{
#if defined(GL_PROVIDER_GLX)
if (mGLXPixmap) {
if (mPixmapTaken && mGLXPixmap) {
gl::sGLXLibrary.DestroyPixmap(mDisplay, mGLXPixmap);
mGLXPixmap = None;
}
@@ -610,6 +610,14 @@ gfxXlibSurface::GetGLXPixmap()
}
return mGLXPixmap;
}
void
gfxXlibSurface::BindGLXPixmap(GLXPixmap aPixmap)
{
MOZ_ASSERT(!mGLXPixmap, "A GLXPixmap is already bound!");
mGLXPixmap = aPixmap;
}
#endif
gfxMemoryLocation
+3
View File
@@ -85,6 +85,9 @@ public:
#if defined(GL_PROVIDER_GLX)
GLXPixmap GetGLXPixmap();
// Binds a GLXPixmap backed by this context's surface.
// Primarily for use in sharing surfaces.
void BindGLXPixmap(GLXPixmap aPixmap);
#endif
// Return true if cairo will take its slow path when this surface is used
-4
View File
@@ -1072,10 +1072,6 @@ nsCSSBorderRenderer::CreateCornerGradient(mozilla::css::Corner aCorner,
nsTArray<gfx::GradientStop> rawStops(2);
rawStops.SetLength(2);
// This is only guaranteed to give correct (and in some cases more correct)
// rendering with the Direct2D Azure and Quartz Cairo backends. For other
// cairo backends it could create un-antialiased border corner transitions
// since that at least used to be pixman's behaviour for hard stops.
rawStops[0].color = firstColor;
rawStops[0].offset = 0.5;
rawStops[1].color = secondColor;
+1
View File
@@ -2893,6 +2893,7 @@ PresShell::CreateReferenceRenderingContext()
if (mPresContext->IsScreen()) {
rc = new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget());
} else {
// We assume the devCtx has positive width and height for this call
rc = devCtx->CreateRenderingContext();
}
+1
View File
@@ -2489,6 +2489,7 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO)
poPresContext->SetIsRenderingOnlySelection(true);
// temporarily creating rendering context
// which is needed to find the selection frames
// mPrintDC must have positive width and height for this call
nsRenderingContext rc(mPrt->mPrintDC->CreateRenderingContext());
// find the starting and ending page numbers
@@ -0,0 +1,14 @@
var timer = null;
function handleRequest(request, response)
{
response.processAsync();
response.setHeader("Content-Type", "application/javascript", false);
response.write("state = 'mid-async';\n");
timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(function() {
response.write("state = 'async loaded';\n");
response.finish();
}, 5 * 1000 /* milliseconds */, timer.TYPE_ONE_SHOT);
}
@@ -0,0 +1,3 @@
is(document.readyState, "interactive", "readyState should be interactive during defer.");
state = "defer";
@@ -128,6 +128,11 @@ support-files =
[test_bug715739.html]
[test_bug716579.html]
[test_bug717180.html]
[test_bug1104732.html]
support-files =
file_defer_bug1104732.js
file_async_bug1104732.sjs
[test_compatmode.html]
[test_html5_tree_construction.html]
skip-if = toolkit == 'android' #TIMED_OUT
@@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1104732
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1104732</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1104732 **/
// Expected order of the values of the "state" variable:
// Test starting
// defer
// DOMContentLoaded
// async loaded
// load
var state = "Test starting";
SimpleTest.waitForExplicitFinish();
is(document.readyState, "loading", "Document should have been loading.");
document.addEventListener("DOMContentLoaded", function () {
is(document.readyState, "interactive", "readyState should be interactive during DOMContentLoaded.");
is(state, "defer", "Bad state upon DOMContentLoaded");
state = "DOMContentLoaded";
});
window.addEventListener("load", function () {
is(document.readyState, "complete", "readyState should be complete during load.");
is(state, "async loaded", "Bad state upon load")
state = "load";
SimpleTest.finish();
});
</script>
<script defer src="file_defer_bug1104732.js"></script>
<script async src="file_async_bug1104732.sjs"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1104732">Mozilla Bug 1104732</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>
+10 -3
View File
@@ -237,12 +237,19 @@ InlineSpellChecker.prototype = {
if (curlang == sortedList[i].id) {
item.setAttribute("checked", "true");
} else {
var callback = function(me, val) {
var callback = function(me, val, dictName) {
return function(evt) {
me.selectDictionary(val);
// Notify change of dictionary, especially for Thunderbird,
// which is otherwise not notified any more.
var view = menu.ownerDocument.defaultView;
var spellcheckChangeEvent = new view.CustomEvent(
"spellcheck-changed", {detail: { dictionary: dictName}});
menu.ownerDocument.dispatchEvent(spellcheckChangeEvent);
}
};
item.addEventListener("command", callback(this, i), true);
item.addEventListener
("command", callback(this, i, sortedList[i].id), true);
}
if (insertBefore)
menu.insertBefore(item, insertBefore);
@@ -335,7 +342,7 @@ InlineSpellChecker.prototype = {
this.mInlineSpellChecker.spellCheckRange(null); // causes recheck
},
// callback for selecting a suggesteed replacement
// callback for selecting a suggested replacement
replaceMisspelling: function(index)
{
if (this.mRemote) {
+7
View File
@@ -7,6 +7,7 @@
#include "nsReadableUtils.h"
#include "nsIPrintSession.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/Logging.h"
#define DEFAULT_MARGIN_WIDTH 0.5
@@ -906,6 +907,9 @@ NS_IMETHODIMP nsPrintSettings::GetPaperWidth(double *aPaperWidth)
NS_IMETHODIMP nsPrintSettings::SetPaperWidth(double aPaperWidth)
{
mPaperWidth = aPaperWidth;
if (mPaperWidth <= 0) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Setting paper width to bad value " << mPaperWidth;
}
return NS_OK;
}
@@ -918,6 +922,9 @@ NS_IMETHODIMP nsPrintSettings::GetPaperHeight(double *aPaperHeight)
NS_IMETHODIMP nsPrintSettings::SetPaperHeight(double aPaperHeight)
{
mPaperHeight = aPaperHeight;
if (mPaperHeight <= 0) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Setting paper height to bad value " << mPaperHeight;
}
return NS_OK;
}
+14
View File
@@ -41,6 +41,8 @@
#include "nsIStringBundle.h"
#define NS_ERROR_GFX_PRINTER_BUNDLE_URL "chrome://global/locale/printing.properties"
#include "mozilla/gfx/Logging.h"
#include "mozilla/Logging.h"
PRLogModuleInfo * kWidgetPrintingLogMod = PR_NewLogModule("printing-widget");
#define PR_PL(_p1) MOZ_LOG(kWidgetPrintingLogMod, mozilla::LogLevel::Debug, _p1)
@@ -281,6 +283,10 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface
double width, height;
mPrintSettings->GetEffectivePageSize(&width, &height);
if (width <= 0 || height <= 0) {
return NS_ERROR_FAILURE;
}
// convert twips to points
width /= TWIPS_PER_POINT_FLOAT;
height /= TWIPS_PER_POINT_FLOAT;
@@ -300,9 +306,17 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface
if (mDevMode) {
NS_WARN_IF_FALSE(mDriverName, "No driver!");
HDC dc = ::CreateDCW(mDriverName, mDeviceName, nullptr, mDevMode);
if (!dc) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed to create device context in GetSurfaceForPrinter";
return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
}
// have this surface take over ownership of this DC
newSurface = new gfxWindowsSurface(dc, gfxWindowsSurface::FLAG_TAKE_DC | gfxWindowsSurface::FLAG_FOR_PRINTING);
if (newSurface->GetType() == (gfxSurfaceType)-1) {
gfxCriticalError() << "Invalid windows surface from " << gfx::hexa(dc);
newSurface = nullptr;
}
}
}