mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
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:
@@ -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
@@ -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"),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,8 +18,8 @@ class nsCycleCollectionTraversalCallback;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Animation;
|
||||
}
|
||||
}
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
class nsNodeUtils
|
||||
{
|
||||
|
||||
+2
-3
@@ -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
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -76,6 +76,7 @@ enum class SharedSurfaceType : uint8_t {
|
||||
DXGLInterop2,
|
||||
Gralloc,
|
||||
IOSurface,
|
||||
GLXDrawable,
|
||||
|
||||
Max
|
||||
};
|
||||
|
||||
@@ -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 += [
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user