зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound a=merge
--HG-- extra : amend_source : 97412f1e791df737909df250fa3cf08eb9763504
This commit is contained in:
Коммит
f50a9f937d
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 1069071: IPDL changes require CLOBBER
|
Bug 1069071: IPDL changes require CLOBBER (second time around)
|
||||||
|
|
|
@ -739,7 +739,7 @@ namespace {
|
||||||
struct RoleComparator
|
struct RoleComparator
|
||||||
{
|
{
|
||||||
const nsDependentSubstring& mRole;
|
const nsDependentSubstring& mRole;
|
||||||
RoleComparator(const nsDependentSubstring& aRole) : mRole(aRole) {}
|
explicit RoleComparator(const nsDependentSubstring& aRole) : mRole(aRole) {}
|
||||||
int operator()(const nsRoleMapEntry& aEntry) const {
|
int operator()(const nsRoleMapEntry& aEntry) const {
|
||||||
return Compare(mRole, aEntry.ARIARoleString());
|
return Compare(mRole, aEntry.ARIARoleString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,14 @@ Accessible::ScrollTo(uint32_t aHow) const
|
||||||
nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aHow);
|
nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aHow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Accessible::UpdateChildren()
|
||||||
|
{
|
||||||
|
AutoTreeMutation mut(this);
|
||||||
|
InvalidateChildren();
|
||||||
|
return EnsureChildren();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -1936,7 +1936,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
|
||||||
mParent = aParent;
|
mParent = aParent;
|
||||||
mIndexInParent = aIndexInParent;
|
mIndexInParent = aIndexInParent;
|
||||||
|
|
||||||
mParent->InvalidateChildrenGroupInfo();
|
#ifdef DEBUG
|
||||||
|
AssertInMutatingSubtree();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Note: this is currently only used for richlistitems and their children.
|
// Note: this is currently only used for richlistitems and their children.
|
||||||
if (mParent->HasNameDependentParent() || mParent->IsXULListItem())
|
if (mParent->HasNameDependentParent() || mParent->IsXULListItem())
|
||||||
|
@ -1949,7 +1951,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
|
||||||
void
|
void
|
||||||
Accessible::UnbindFromParent()
|
Accessible::UnbindFromParent()
|
||||||
{
|
{
|
||||||
mParent->InvalidateChildrenGroupInfo();
|
#ifdef DEBUG
|
||||||
|
AssertInMutatingSubtree();
|
||||||
|
#endif
|
||||||
mParent = nullptr;
|
mParent = nullptr;
|
||||||
mIndexInParent = -1;
|
mIndexInParent = -1;
|
||||||
mIndexOfEmbeddedChild = -1;
|
mIndexOfEmbeddedChild = -1;
|
||||||
|
@ -2658,6 +2662,21 @@ Accessible::StaticAsserts() const
|
||||||
"Accessible::mGenericType was oversized by eLastAccGenericType!");
|
"Accessible::mGenericType was oversized by eLastAccGenericType!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Accessible::AssertInMutatingSubtree() const
|
||||||
|
{
|
||||||
|
if (IsDoc() || IsApplication())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Accessible *acc = this;
|
||||||
|
while (!acc->IsDoc() && !(acc->mStateFlags & eSubtreeMutating)) {
|
||||||
|
acc = acc->Parent();
|
||||||
|
if (!acc)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(acc->mStateFlags & eSubtreeMutating);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// KeyBinding class
|
// KeyBinding class
|
||||||
|
|
|
@ -373,11 +373,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Update the children cache.
|
* Update the children cache.
|
||||||
*/
|
*/
|
||||||
inline bool UpdateChildren()
|
bool UpdateChildren();
|
||||||
{
|
|
||||||
InvalidateChildren();
|
|
||||||
return EnsureChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache children if necessary. Return true if the accessible is defunct.
|
* Cache children if necessary. Return true if the accessible is defunct.
|
||||||
|
@ -948,7 +944,8 @@ protected:
|
||||||
eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map
|
eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map
|
||||||
eHasNumericValue = 1 << 4, // accessible has a numeric value
|
eHasNumericValue = 1 << 4, // accessible has a numeric value
|
||||||
eGroupInfoDirty = 1 << 5, // accessible needs to update group info
|
eGroupInfoDirty = 1 << 5, // accessible needs to update group info
|
||||||
eIgnoreDOMUIEvent = 1 << 6, // don't process DOM UI events for a11y events
|
eSubtreeMutating = 1 << 6, // subtree is being mutated
|
||||||
|
eIgnoreDOMUIEvent = 1 << 7, // don't process DOM UI events for a11y events
|
||||||
|
|
||||||
eLastStateFlag = eIgnoreDOMUIEvent
|
eLastStateFlag = eIgnoreDOMUIEvent
|
||||||
};
|
};
|
||||||
|
@ -1064,7 +1061,7 @@ protected:
|
||||||
int32_t mIndexInParent;
|
int32_t mIndexInParent;
|
||||||
|
|
||||||
static const uint8_t kChildrenFlagsBits = 2;
|
static const uint8_t kChildrenFlagsBits = 2;
|
||||||
static const uint8_t kStateFlagsBits = 7;
|
static const uint8_t kStateFlagsBits = 8;
|
||||||
static const uint8_t kContextFlagsBits = 1;
|
static const uint8_t kContextFlagsBits = 1;
|
||||||
static const uint8_t kTypeBits = 6;
|
static const uint8_t kTypeBits = 6;
|
||||||
static const uint8_t kGenericTypesBits = 13;
|
static const uint8_t kGenericTypesBits = 13;
|
||||||
|
@ -1079,9 +1076,11 @@ protected:
|
||||||
uint32_t mGenericTypes : kGenericTypesBits;
|
uint32_t mGenericTypes : kGenericTypesBits;
|
||||||
|
|
||||||
void StaticAsserts() const;
|
void StaticAsserts() const;
|
||||||
|
void AssertInMutatingSubtree() const;
|
||||||
|
|
||||||
friend class DocAccessible;
|
friend class DocAccessible;
|
||||||
friend class xpcAccessible;
|
friend class xpcAccessible;
|
||||||
|
friend class AutoTreeMutation;
|
||||||
|
|
||||||
nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
|
nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
|
||||||
int32_t mIndexOfEmbeddedChild;
|
int32_t mIndexOfEmbeddedChild;
|
||||||
|
@ -1165,6 +1164,35 @@ private:
|
||||||
uint32_t mModifierMask;
|
uint32_t mModifierMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class makes sure required tasks are done before and after tree
|
||||||
|
* mutations. Currently this only includes group info invalidation. You must
|
||||||
|
* have an object of this class on the stack when calling methods that mutate
|
||||||
|
* the accessible tree.
|
||||||
|
*/
|
||||||
|
class AutoTreeMutation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoTreeMutation(Accessible* aRoot, bool aInvalidationRequired = true) :
|
||||||
|
mInvalidationRequired(aInvalidationRequired), mRoot(aRoot)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!(mRoot->mStateFlags & Accessible::eSubtreeMutating));
|
||||||
|
mRoot->mStateFlags |= Accessible::eSubtreeMutating;
|
||||||
|
}
|
||||||
|
~AutoTreeMutation()
|
||||||
|
{
|
||||||
|
if (mInvalidationRequired)
|
||||||
|
mRoot->InvalidateChildrenGroupInfo();
|
||||||
|
|
||||||
|
MOZ_ASSERT(mRoot->mStateFlags & Accessible::eSubtreeMutating);
|
||||||
|
mRoot->mStateFlags &= ~Accessible::eSubtreeMutating;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mInvalidationRequired;
|
||||||
|
private:
|
||||||
|
Accessible* mRoot;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -483,7 +483,13 @@ DocAccessible::Shutdown()
|
||||||
|
|
||||||
mDependentIDsHash.Clear();
|
mDependentIDsHash.Clear();
|
||||||
mNodeToAccessibleMap.Clear();
|
mNodeToAccessibleMap.Clear();
|
||||||
ClearCache(mAccessibleCache);
|
|
||||||
|
{
|
||||||
|
// We're about to get rid of all of our children so there won't be anything
|
||||||
|
// to invalidate.
|
||||||
|
AutoTreeMutation mut(this, false);
|
||||||
|
ClearCache(mAccessibleCache);
|
||||||
|
}
|
||||||
|
|
||||||
HyperTextAccessibleWrap::Shutdown();
|
HyperTextAccessibleWrap::Shutdown();
|
||||||
|
|
||||||
|
@ -1318,8 +1324,10 @@ DocAccessible::ProcessInvalidationList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the subtree is created.
|
// Make sure the subtree is created.
|
||||||
if (accessible)
|
if (accessible) {
|
||||||
|
AutoTreeMutation mut(accessible);
|
||||||
CacheChildrenInSubtree(accessible);
|
CacheChildrenInSubtree(accessible);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mInvalidationList.Clear();
|
mInvalidationList.Clear();
|
||||||
|
@ -1425,7 +1433,9 @@ DocAccessible::DoInitialUpdate()
|
||||||
SetRoleMapEntry(aria::GetRoleMap(mContent));
|
SetRoleMapEntry(aria::GetRoleMap(mContent));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build initial tree.
|
// Build initial tree. Since its the initial tree there's no group info to
|
||||||
|
// invalidate.
|
||||||
|
AutoTreeMutation mut(this, false);
|
||||||
CacheChildrenInSubtree(this);
|
CacheChildrenInSubtree(this);
|
||||||
|
|
||||||
// Fire reorder event after the document tree is constructed. Note, since
|
// Fire reorder event after the document tree is constructed. Note, since
|
||||||
|
@ -1659,6 +1669,9 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer,
|
||||||
// accessibles into accessible tree. We need to invalidate children even
|
// accessibles into accessible tree. We need to invalidate children even
|
||||||
// there's no inserted accessibles in the end because accessible children
|
// there's no inserted accessibles in the end because accessible children
|
||||||
// are created while parent recaches child accessibles.
|
// are created while parent recaches child accessibles.
|
||||||
|
// XXX Group invalidation here may be redundant with invalidation in
|
||||||
|
// UpdateTree.
|
||||||
|
AutoTreeMutation mut(aContainer);
|
||||||
aContainer->InvalidateChildren();
|
aContainer->InvalidateChildren();
|
||||||
CacheChildrenInSubtree(aContainer);
|
CacheChildrenInSubtree(aContainer);
|
||||||
}
|
}
|
||||||
|
@ -1691,6 +1704,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
|
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
|
||||||
|
AutoTreeMutation mut(aContainer);
|
||||||
|
|
||||||
if (child) {
|
if (child) {
|
||||||
updateFlags |= UpdateTreeInternal(child, aIsInsert, reorderEvent);
|
updateFlags |= UpdateTreeInternal(child, aIsInsert, reorderEvent);
|
||||||
|
|
|
@ -85,7 +85,8 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||||
if (!imageMapObj)
|
if (!imageMapObj)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool doReorderEvent = false;
|
bool treeChanged = false;
|
||||||
|
AutoTreeMutation mut(this);
|
||||||
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
|
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
|
||||||
|
|
||||||
// Remove areas that are not a valid part of the image map anymore.
|
// Remove areas that are not a valid part of the image map anymore.
|
||||||
|
@ -98,10 +99,10 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||||
nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
|
nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
|
||||||
mDoc->FireDelayedEvent(event);
|
mDoc->FireDelayedEvent(event);
|
||||||
reorderEvent->AddSubMutationEvent(event);
|
reorderEvent->AddSubMutationEvent(event);
|
||||||
doReorderEvent = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveChild(area);
|
RemoveChild(area);
|
||||||
|
treeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert new areas into the tree.
|
// Insert new areas into the tree.
|
||||||
|
@ -123,14 +124,18 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||||
nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
|
nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
|
||||||
mDoc->FireDelayedEvent(event);
|
mDoc->FireDelayedEvent(event);
|
||||||
reorderEvent->AddSubMutationEvent(event);
|
reorderEvent->AddSubMutationEvent(event);
|
||||||
doReorderEvent = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
treeChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire reorder event if needed.
|
// Fire reorder event if needed.
|
||||||
if (doReorderEvent)
|
if (treeChanged && aDoFireEvents)
|
||||||
mDoc->FireDelayedEvent(reorderEvent);
|
mDoc->FireDelayedEvent(reorderEvent);
|
||||||
|
|
||||||
|
if (!treeChanged)
|
||||||
|
mut.mInvalidationRequired = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessible*
|
Accessible*
|
||||||
|
|
|
@ -385,6 +385,14 @@ let OutputGenerator = {
|
||||||
this._addLandmark(output, aAccessible);
|
this._addLandmark(output, aAccessible);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gridcell: function gridcell(aAccessible, aRoleStr, aState, aFlags) {
|
||||||
|
let output = [];
|
||||||
|
this._addState(output, aState);
|
||||||
|
this._addName(output, aAccessible, aFlags);
|
||||||
|
this._addLandmark(output, aAccessible);
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -440,6 +440,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||||
oldAccOrElmOrID: "grid",
|
oldAccOrElmOrID: "grid",
|
||||||
expectedUtterance: [["4", "7"], ["4", "7"]],
|
expectedUtterance: [["4", "7"], ["4", "7"]],
|
||||||
expectedBraille: [["4", "7"], ["4", "7"]]
|
expectedBraille: [["4", "7"], ["4", "7"]]
|
||||||
|
}, {
|
||||||
|
accOrElmOrID: "gridcell3",
|
||||||
|
oldAccOrElmOrID: "grid",
|
||||||
|
expectedUtterance: [[{"string": "stateSelected"}, "5"],
|
||||||
|
["5", {"string": "stateSelected"}]],
|
||||||
|
expectedBraille: [["5"], ["5"]],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Test all possible utterance order preference values.
|
// Test all possible utterance order preference values.
|
||||||
|
@ -581,7 +587,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||||
</ol>
|
</ol>
|
||||||
<ol role="row">
|
<ol role="row">
|
||||||
<li role="rowheader">2</li>
|
<li role="rowheader">2</li>
|
||||||
<li role="gridcell">5</li>
|
<li id="gridcell3" aria-selected="true" role="gridcell">5</li>
|
||||||
<li role="gridcell">6</li>
|
<li role="gridcell">6</li>
|
||||||
</ol>
|
</ol>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -57,8 +57,10 @@ include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
|
||||||
# including that file. MOZ_PACKAGER_MINIFY_JS is used in packager.mk, but since
|
# including that file. MOZ_PACKAGER_MINIFY_JS is used in packager.mk, but since
|
||||||
# recipe evaluation is deferred, we can set it here after the inclusion.
|
# recipe evaluation is deferred, we can set it here after the inclusion.
|
||||||
ifneq (,$(JS_BINARY))
|
ifneq (,$(JS_BINARY))
|
||||||
|
ifndef MOZ_DEBUG
|
||||||
MOZ_PACKAGER_MINIFY_JS=1
|
MOZ_PACKAGER_MINIFY_JS=1
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (bundle, $(MOZ_FS_LAYOUT))
|
ifeq (bundle, $(MOZ_FS_LAYOUT))
|
||||||
BINPATH = $(_BINPATH)
|
BINPATH = $(_BINPATH)
|
||||||
|
|
|
@ -1616,6 +1616,11 @@ pref("loop.debug.loglevel", "Error");
|
||||||
pref("loop.debug.dispatcher", false);
|
pref("loop.debug.dispatcher", false);
|
||||||
pref("loop.debug.websocket", false);
|
pref("loop.debug.websocket", false);
|
||||||
pref("loop.debug.sdk", false);
|
pref("loop.debug.sdk", false);
|
||||||
|
#ifdef DEBUG
|
||||||
|
pref("loop.CSP", "default-src 'self' about: file: chrome: http://localhost:*; img-src 'self' data: http://www.gravatar.com/ about: file: chrome:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net http://localhost:* ws://localhost:*");
|
||||||
|
#else
|
||||||
|
pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src 'self' data: http://www.gravatar.com/ about: file: chrome:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net");
|
||||||
|
#endif
|
||||||
pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
|
pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
|
||||||
pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");
|
pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
const PREF_INTRO_SHOWN = "browser.newtabpage.introShown";
|
const PREF_INTRO_SHOWN = "browser.newtabpage.introShown";
|
||||||
|
|
||||||
let gIntro = {
|
let gIntro = {
|
||||||
_introShown: Services.prefs.getBoolPref(PREF_INTRO_SHOWN),
|
|
||||||
|
|
||||||
_nodeIDSuffixes: [
|
_nodeIDSuffixes: [
|
||||||
"panel",
|
"panel",
|
||||||
"what",
|
"what",
|
||||||
|
@ -26,7 +24,7 @@ let gIntro = {
|
||||||
},
|
},
|
||||||
|
|
||||||
showIfNecessary: function() {
|
showIfNecessary: function() {
|
||||||
if (!this._introShown) {
|
if (!Services.prefs.getBoolPref(PREF_INTRO_SHOWN)) {
|
||||||
Services.prefs.setBoolPref(PREF_INTRO_SHOWN, true);
|
Services.prefs.setBoolPref(PREF_INTRO_SHOWN, true);
|
||||||
this.showPanel();
|
this.showPanel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ const kObservedTopics = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const PREF_PERMISSION_FAKE = "media.navigator.permission.fake";
|
const PREF_PERMISSION_FAKE = "media.navigator.permission.fake";
|
||||||
|
const PREF_LOOP_CSP = "loop.CSP";
|
||||||
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
@ -162,12 +163,14 @@ fakeLoopAboutModule.prototype = {
|
||||||
let factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
|
let factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
|
||||||
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
|
||||||
|
let originalLoopCsp = Services.prefs.getCharPref(PREF_LOOP_CSP);
|
||||||
registerCleanupFunction(function() {
|
registerCleanupFunction(function() {
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
kObservedTopics.forEach(topic => {
|
kObservedTopics.forEach(topic => {
|
||||||
Services.obs.removeObserver(observer, topic);
|
Services.obs.removeObserver(observer, topic);
|
||||||
});
|
});
|
||||||
Services.prefs.clearUserPref(PREF_PERMISSION_FAKE);
|
Services.prefs.clearUserPref(PREF_PERMISSION_FAKE);
|
||||||
|
Services.prefs.setCharPref(PREF_LOOP_CSP, originalLoopCsp);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,6 +179,8 @@ let gTests = [
|
||||||
{
|
{
|
||||||
desc: "getUserMedia about:loopconversation shouldn't prompt",
|
desc: "getUserMedia about:loopconversation shouldn't prompt",
|
||||||
run: function checkAudioVideoLoop() {
|
run: function checkAudioVideoLoop() {
|
||||||
|
Services.prefs.setCharPref(PREF_LOOP_CSP, "default-src 'unsafe-inline'");
|
||||||
|
|
||||||
let classID = Cc["@mozilla.org/uuid-generator;1"]
|
let classID = Cc["@mozilla.org/uuid-generator;1"]
|
||||||
.getService(Ci.nsIUUIDGenerator).generateUUID();
|
.getService(Ci.nsIUUIDGenerator).generateUUID();
|
||||||
registrar.registerFactory(classID, "",
|
registrar.registerFactory(classID, "",
|
||||||
|
@ -198,6 +203,7 @@ let gTests = [
|
||||||
yield closeStream();
|
yield closeStream();
|
||||||
|
|
||||||
registrar.unregisterFactory(classID, factory);
|
registrar.unregisterFactory(classID, factory);
|
||||||
|
Services.prefs.setCharPref(PREF_LOOP_CSP, originalLoopCsp);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ support-files =
|
||||||
offlineEvent.cacheManifest
|
offlineEvent.cacheManifest
|
||||||
offlineEvent.cacheManifest^headers^
|
offlineEvent.cacheManifest^headers^
|
||||||
offlineEvent.html
|
offlineEvent.html
|
||||||
privateBrowsingMode.js
|
|
||||||
subtst_contextmenu.html
|
subtst_contextmenu.html
|
||||||
video.ogg
|
video.ogg
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
// This file is only present in per-window private browsing buikds.
|
|
||||||
var perWindowPrivateBrowsing = true;
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ Browser context menu tests.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script> var perWindowPrivateBrowsing = false; </script>
|
|
||||||
<script type="text/javascript" src="privateBrowsingMode.js"></script>
|
|
||||||
<script type="text/javascript" src="contextmenu_common.js"></script>
|
<script type="text/javascript" src="contextmenu_common.js"></script>
|
||||||
<script class="testbody" type="text/javascript">
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
@ -111,26 +109,15 @@ function runTest(testNum) {
|
||||||
|
|
||||||
function () {
|
function () {
|
||||||
// Context menu for text link
|
// Context menu for text link
|
||||||
if (perWindowPrivateBrowsing) {
|
checkContextMenu(["context-openlinkintab", true,
|
||||||
checkContextMenu(["context-openlinkintab", true,
|
"context-openlink", true,
|
||||||
"context-openlink", true,
|
"context-openlinkprivate", true,
|
||||||
"context-openlinkprivate", true,
|
"---", null,
|
||||||
"---", null,
|
"context-bookmarklink", true,
|
||||||
"context-bookmarklink", true,
|
"context-savelink", true,
|
||||||
"context-savelink", true,
|
"context-copylink", true,
|
||||||
"context-copylink", true,
|
"context-searchselect", true
|
||||||
"context-searchselect", true
|
].concat(inspectItems));
|
||||||
].concat(inspectItems));
|
|
||||||
} else {
|
|
||||||
checkContextMenu(["context-openlinkintab", true,
|
|
||||||
"context-openlink", true,
|
|
||||||
"---", null,
|
|
||||||
"context-bookmarklink", true,
|
|
||||||
"context-savelink", true,
|
|
||||||
"context-copylink", true,
|
|
||||||
"context-searchselect", true
|
|
||||||
].concat(inspectItems));
|
|
||||||
}
|
|
||||||
closeContextMenu();
|
closeContextMenu();
|
||||||
openContextMenuFor(mailto); // Invoke context menu for next test.
|
openContextMenuFor(mailto); // Invoke context menu for next test.
|
||||||
},
|
},
|
||||||
|
@ -587,34 +574,19 @@ function runTest(testNum) {
|
||||||
// Context menu for selected text which matches valid URL pattern
|
// Context menu for selected text which matches valid URL pattern
|
||||||
if (SpecialPowers.Services.appinfo.OS == "Darwin") {
|
if (SpecialPowers.Services.appinfo.OS == "Darwin") {
|
||||||
// This test is only enabled on Mac due to bug 736399.
|
// This test is only enabled on Mac due to bug 736399.
|
||||||
if (perWindowPrivateBrowsing) {
|
checkContextMenu(["context-openlinkincurrent", true,
|
||||||
checkContextMenu(["context-openlinkincurrent", true,
|
"context-openlinkintab", true,
|
||||||
"context-openlinkintab", true,
|
"context-openlink", true,
|
||||||
"context-openlink", true,
|
"context-openlinkprivate", true,
|
||||||
"context-openlinkprivate", true,
|
"---", null,
|
||||||
"---", null,
|
"context-bookmarklink", true,
|
||||||
"context-bookmarklink", true,
|
"context-savelink", true,
|
||||||
"context-savelink", true,
|
"context-copy", true,
|
||||||
"context-copy", true,
|
"context-selectall", true,
|
||||||
"context-selectall", true,
|
"---", null,
|
||||||
"---", null,
|
"context-searchselect", true,
|
||||||
"context-searchselect", true,
|
"context-viewpartialsource-selection", true
|
||||||
"context-viewpartialsource-selection", true
|
].concat(inspectItems));
|
||||||
].concat(inspectItems));
|
|
||||||
} else {
|
|
||||||
checkContextMenu(["context-openlinkincurrent", true,
|
|
||||||
"context-openlinkintab", true,
|
|
||||||
"context-openlink", true,
|
|
||||||
"---", null,
|
|
||||||
"context-bookmarklink", true,
|
|
||||||
"context-savelink", true,
|
|
||||||
"context-copy", true,
|
|
||||||
"context-selectall", true,
|
|
||||||
"---", null,
|
|
||||||
"context-searchselect", true,
|
|
||||||
"context-viewpartialsource-selection", true
|
|
||||||
].concat(inspectItems));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
closeContextMenu();
|
closeContextMenu();
|
||||||
// clear the selection because following tests don't expect any selection
|
// clear the selection because following tests don't expect any selection
|
||||||
|
@ -625,42 +597,23 @@ function runTest(testNum) {
|
||||||
|
|
||||||
function () {
|
function () {
|
||||||
// Context menu for image link
|
// Context menu for image link
|
||||||
if (perWindowPrivateBrowsing) {
|
checkContextMenu(["context-openlinkintab", true,
|
||||||
checkContextMenu(["context-openlinkintab", true,
|
"context-openlink", true,
|
||||||
"context-openlink", true,
|
"context-openlinkprivate", true,
|
||||||
"context-openlinkprivate", true,
|
"---", null,
|
||||||
"---", null,
|
"context-bookmarklink", true,
|
||||||
"context-bookmarklink", true,
|
"context-savelink", true,
|
||||||
"context-savelink", true,
|
"context-copylink", true,
|
||||||
"context-copylink", true,
|
"---", null,
|
||||||
"---", null,
|
"context-viewimage", true,
|
||||||
"context-viewimage", true,
|
"context-copyimage-contents", true,
|
||||||
"context-copyimage-contents", true,
|
"context-copyimage", true,
|
||||||
"context-copyimage", true,
|
"---", null,
|
||||||
"---", null,
|
"context-saveimage", true,
|
||||||
"context-saveimage", true,
|
"context-sendimage", true,
|
||||||
"context-sendimage", true,
|
"context-setDesktopBackground", true,
|
||||||
"context-setDesktopBackground", true,
|
"context-viewimageinfo", true
|
||||||
"context-viewimageinfo", true
|
].concat(inspectItems));
|
||||||
].concat(inspectItems));
|
|
||||||
} else {
|
|
||||||
checkContextMenu(["context-openlinkintab", true,
|
|
||||||
"context-openlink", true,
|
|
||||||
"---", null,
|
|
||||||
"context-bookmarklink", true,
|
|
||||||
"context-savelink", true,
|
|
||||||
"context-copylink", true,
|
|
||||||
"---", null,
|
|
||||||
"context-viewimage", true,
|
|
||||||
"context-copyimage-contents", true,
|
|
||||||
"context-copyimage", true,
|
|
||||||
"---", null,
|
|
||||||
"context-saveimage", true,
|
|
||||||
"context-sendimage", true,
|
|
||||||
"context-setDesktopBackground", true,
|
|
||||||
"context-viewimageinfo", true
|
|
||||||
].concat(inspectItems));
|
|
||||||
}
|
|
||||||
closeContextMenu();
|
closeContextMenu();
|
||||||
selectInputText(select_inputtext); // Select text prior to opening context menu.
|
selectInputText(select_inputtext); // Select text prior to opening context menu.
|
||||||
openContextMenuFor(select_inputtext); // Invoke context menu for next test.
|
openContextMenuFor(select_inputtext); // Invoke context menu for next test.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head_dirprovider.js
|
head = head_dirprovider.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_bookmark_pref.js]
|
[test_bookmark_pref.js]
|
||||||
[test_keys.js]
|
[test_keys.js]
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_DownloadsCommon.js]
|
[test_DownloadsCommon.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head_feeds.js
|
head = head_feeds.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_355473.js]
|
[test_355473.js]
|
||||||
[test_758990.js]
|
[test_758990.js]
|
||||||
|
|
|
@ -9,3 +9,8 @@ set -e
|
||||||
|
|
||||||
# The browser_parsable_css.js can fail if we add some css that isn't parsable.
|
# The browser_parsable_css.js can fail if we add some css that isn't parsable.
|
||||||
./mach mochitest browser/components/loop/test/mochitest browser/base/content/test/general/browser_parsable_css.js
|
./mach mochitest browser/components/loop/test/mochitest browser/base/content/test/general/browser_parsable_css.js
|
||||||
|
|
||||||
|
# The check to make sure that the media devices can be used in Loop without
|
||||||
|
# prompting is in browser_devices_get_user_media_about_urls.js. It's possible
|
||||||
|
# to mess this up with CSP handling, and probably other changes, too.
|
||||||
|
./mach mochitest browser/base/content/test/general/browser_devices_get_user_media_about_urls.js
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
|
|
||||||
[test_loopapi_hawk_request.js]
|
[test_loopapi_hawk_request.js]
|
||||||
[test_looppush_initialize.js]
|
[test_looppush_initialize.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head_migration.js
|
head = head_migration.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_IE_bookmarks.js]
|
[test_IE_bookmarks.js]
|
||||||
skip-if = os != "win"
|
skip-if = os != "win"
|
||||||
|
|
|
@ -507,7 +507,6 @@ BrowserGlue.prototype = {
|
||||||
NewTabUtils.init();
|
NewTabUtils.init();
|
||||||
DirectoryLinksProvider.init();
|
DirectoryLinksProvider.init();
|
||||||
NewTabUtils.links.addProvider(DirectoryLinksProvider);
|
NewTabUtils.links.addProvider(DirectoryLinksProvider);
|
||||||
BrowserNewTabPreloader.init();
|
|
||||||
#ifdef NIGHTLY_BUILD
|
#ifdef NIGHTLY_BUILD
|
||||||
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
|
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
|
||||||
SignInToWebsiteUX.init();
|
SignInToWebsiteUX.init();
|
||||||
|
@ -2243,7 +2242,7 @@ let DefaultBrowserCheck = {
|
||||||
|
|
||||||
let iconPixels = win.devicePixelRatio > 1 ? "32" : "16";
|
let iconPixels = win.devicePixelRatio > 1 ? "32" : "16";
|
||||||
let iconURL = "chrome://branding/content/icon" + iconPixels + ".png";
|
let iconURL = "chrome://branding/content/icon" + iconPixels + ".png";
|
||||||
const priority = notificationBox.PRIORITY_INFO_HIGH;
|
const priority = notificationBox.PRIORITY_WARNING_HIGH;
|
||||||
let callback = this._onNotificationEvent.bind(this);
|
let callback = this._onNotificationEvent.bind(this);
|
||||||
this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
|
this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
|
||||||
iconURL, priority, buttons,
|
iconURL, priority, buttons,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head_bookmarks.js
|
head = head_bookmarks.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
bookmarks.glue.html
|
bookmarks.glue.html
|
||||||
bookmarks.glue.json
|
bookmarks.glue.json
|
||||||
|
|
|
@ -397,7 +397,6 @@
|
||||||
var menuitem = document.createElementNS(kXULNS, "menuitem");
|
var menuitem = document.createElementNS(kXULNS, "menuitem");
|
||||||
var name = engines[i].name;
|
var name = engines[i].name;
|
||||||
menuitem.setAttribute("label", name);
|
menuitem.setAttribute("label", name);
|
||||||
menuitem.setAttribute("id", name);
|
|
||||||
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon");
|
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon");
|
||||||
// Since this menu is rebuilt by the observer method whenever a new
|
// Since this menu is rebuilt by the observer method whenever a new
|
||||||
// engine is selected, the "selected" attribute does not need to be
|
// engine is selected, the "selected" attribute does not need to be
|
||||||
|
|
|
@ -187,7 +187,7 @@ skip-if = true # Needs to be rewritten as Marionette test, bug 995916
|
||||||
[browser_739531.js]
|
[browser_739531.js]
|
||||||
[browser_739805.js]
|
[browser_739805.js]
|
||||||
[browser_819510_perwindowpb.js]
|
[browser_819510_perwindowpb.js]
|
||||||
skip-if = os == "linux" # Intermittent failures, bug 894063
|
skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 894063; e10s: Bug 1079073
|
||||||
|
|
||||||
# Disabled for frequent intermittent failures
|
# Disabled for frequent intermittent failures
|
||||||
[browser_464620_a.js]
|
[browser_464620_a.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
data/sessionCheckpoints_all.json
|
data/sessionCheckpoints_all.json
|
||||||
data/sessionstore_invalid.js
|
data/sessionstore_invalid.js
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_421977.js]
|
[test_421977.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_cld2.js]
|
[test_cld2.js]
|
||||||
[test_healthreport.js]
|
[test_healthreport.js]
|
||||||
|
|
|
@ -49,6 +49,8 @@ function ToolSidebar(tabbox, panel, uid, showTabstripe=true)
|
||||||
if (!showTabstripe) {
|
if (!showTabstripe) {
|
||||||
this._tabbox.setAttribute("hidetabs", "true");
|
this._tabbox.setAttribute("hidetabs", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._toolPanel.emit("sidebar-created", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ToolSidebar = ToolSidebar;
|
exports.ToolSidebar = ToolSidebar;
|
||||||
|
@ -210,6 +212,8 @@ ToolSidebar.prototype = {
|
||||||
this._tabbox.width = this._width;
|
this._tabbox.width = this._width;
|
||||||
}
|
}
|
||||||
this._tabbox.removeAttribute("hidden");
|
this._tabbox.removeAttribute("hidden");
|
||||||
|
|
||||||
|
this.emit("show");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -218,6 +222,8 @@ ToolSidebar.prototype = {
|
||||||
hide: function ToolSidebar_hide() {
|
hide: function ToolSidebar_hide() {
|
||||||
Services.prefs.setIntPref("devtools.toolsidebar-width." + this._uid, this._tabbox.width);
|
Services.prefs.setIntPref("devtools.toolsidebar-width." + this._uid, this._tabbox.width);
|
||||||
this._tabbox.setAttribute("hidden", "true");
|
this._tabbox.setAttribute("hidden", "true");
|
||||||
|
|
||||||
|
this.emit("hide");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,6 +263,8 @@ ToolSidebar.prototype = {
|
||||||
this._telemetry.toolClosed(this._currentTool);
|
this._telemetry.toolClosed(this._currentTool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._toolPanel.emit("sidebar-destroyed", this);
|
||||||
|
|
||||||
this._tabs = null;
|
this._tabs = null;
|
||||||
this._tabbox = null;
|
this._tabbox = null;
|
||||||
this._panelDoc = null;
|
this._panelDoc = null;
|
||||||
|
|
|
@ -30,6 +30,7 @@ skip-if = e10s # Bug 1070837 - devtools/framework/toolbox.js |doc| getter not e1
|
||||||
[browser_toolbox_select_event.js]
|
[browser_toolbox_select_event.js]
|
||||||
skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown
|
skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown
|
||||||
[browser_toolbox_sidebar.js]
|
[browser_toolbox_sidebar.js]
|
||||||
|
[browser_toolbox_sidebar_events.js]
|
||||||
[browser_toolbox_tabsswitch_shortcuts.js]
|
[browser_toolbox_tabsswitch_shortcuts.js]
|
||||||
[browser_toolbox_tool_ready.js]
|
[browser_toolbox_tool_ready.js]
|
||||||
[browser_toolbox_tool_remote_reopen.js]
|
[browser_toolbox_tool_remote_reopen.js]
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
const Cu = Components.utils;
|
||||||
|
const { ToolSidebar } = devtools.require("devtools/framework/sidebar");
|
||||||
|
|
||||||
|
const toolURL = "data:text/xml;charset=utf8,<?xml version='1.0'?>" +
|
||||||
|
"<?xml-stylesheet href='chrome://browser/skin/devtools/common.css' type='text/css'?>" +
|
||||||
|
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'>" +
|
||||||
|
"<hbox flex='1'><description flex='1'>foo</description><splitter class='devtools-side-splitter'/>" +
|
||||||
|
"<tabbox flex='1' id='sidebar' class='devtools-sidebar-tabs'><tabs/><tabpanels flex='1'/></tabbox>" +
|
||||||
|
"</hbox>" +
|
||||||
|
"</window>";
|
||||||
|
|
||||||
|
const tab1URL = "data:text/html;charset=utf8,<title>1</title><p>1</p>";
|
||||||
|
|
||||||
|
let collectedEvents = [];
|
||||||
|
|
||||||
|
let toolDefinition = {
|
||||||
|
id: "testTool1072208",
|
||||||
|
visibilityswitch: "devtools.testTool1072208.enabled",
|
||||||
|
url: toolURL,
|
||||||
|
label: "Test tool",
|
||||||
|
isTargetSupported: function() true,
|
||||||
|
build: function(iframeWindow, toolbox) {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
executeSoon(() => {
|
||||||
|
deferred.resolve({
|
||||||
|
target: toolbox.target,
|
||||||
|
toolbox: toolbox,
|
||||||
|
isReady: true,
|
||||||
|
destroy: function(){},
|
||||||
|
panelDoc: iframeWindow.document,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return deferred.promise;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
gDevTools.registerTool(toolDefinition);
|
||||||
|
|
||||||
|
addTab("about:blank").then(function(aTab) {
|
||||||
|
let target = TargetFactory.forTab(aTab);
|
||||||
|
gDevTools.showToolbox(target, toolDefinition.id).then(function(toolbox) {
|
||||||
|
let panel = toolbox.getPanel(toolDefinition.id);
|
||||||
|
ok(true, "Tool open");
|
||||||
|
|
||||||
|
panel.once("sidebar-created", function(event, id) {
|
||||||
|
collectedEvents.push(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.once("sidebar-destroyed", function(event, id) {
|
||||||
|
collectedEvents.push(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
let tabbox = panel.panelDoc.getElementById("sidebar");
|
||||||
|
panel.sidebar = new ToolSidebar(tabbox, panel, "testbug1072208", true);
|
||||||
|
|
||||||
|
panel.sidebar.once("show", function(event, id) {
|
||||||
|
collectedEvents.push(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.sidebar.once("hide", function(event, id) {
|
||||||
|
collectedEvents.push(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.sidebar.once("tab1-selected", () => finishUp(panel));
|
||||||
|
panel.sidebar.addTab("tab1", tab1URL, true);
|
||||||
|
panel.sidebar.show();
|
||||||
|
}).then(null, console.error);
|
||||||
|
});
|
||||||
|
|
||||||
|
function finishUp(panel) {
|
||||||
|
panel.sidebar.hide();
|
||||||
|
panel.sidebar.destroy();
|
||||||
|
|
||||||
|
let events = collectedEvents.join(":");
|
||||||
|
is(events, "sidebar-created:show:hide:sidebar-destroyed",
|
||||||
|
"Found the right amount of collected events.");
|
||||||
|
|
||||||
|
gDevTools.unregisterTool(toolDefinition.id);
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -897,6 +897,15 @@ Toolbox.prototype = {
|
||||||
let panel = built;
|
let panel = built;
|
||||||
iframe.panel = panel;
|
iframe.panel = panel;
|
||||||
|
|
||||||
|
// The panel instance is expected to fire (and listen to) various
|
||||||
|
// framework events, so make sure it's properly decorated with
|
||||||
|
// appropriate API (on, off, once, emit).
|
||||||
|
// In this case we decorate panel instances directly returned by
|
||||||
|
// the tool definition 'build' method.
|
||||||
|
if (typeof panel.emit == "undefined") {
|
||||||
|
EventEmitter.decorate(panel);
|
||||||
|
}
|
||||||
|
|
||||||
gDevTools.emit(id + "-build", this, panel);
|
gDevTools.emit(id + "-build", this, panel);
|
||||||
this.emit(id + "-build", panel);
|
this.emit(id + "-build", panel);
|
||||||
|
|
||||||
|
@ -915,6 +924,14 @@ Toolbox.prototype = {
|
||||||
promise.resolve(built).then((panel) => {
|
promise.resolve(built).then((panel) => {
|
||||||
this._toolPanels.set(id, panel);
|
this._toolPanels.set(id, panel);
|
||||||
|
|
||||||
|
// Make sure to decorate panel object with event API also in case
|
||||||
|
// where the tool definition 'build' method returns only a promise
|
||||||
|
// and the actual panel instance is available as soon as the
|
||||||
|
// promise is resolved.
|
||||||
|
if (typeof panel.emit == "undefined") {
|
||||||
|
EventEmitter.decorate(panel);
|
||||||
|
}
|
||||||
|
|
||||||
gDevTools.emit(id + "-ready", this, panel);
|
gDevTools.emit(id + "-ready", this, panel);
|
||||||
this.emit(id + "-ready", panel);
|
this.emit(id + "-ready", panel);
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,6 @@ var ResourceContainer = Class({
|
||||||
this.expander.setAttribute("open", "");
|
this.expander.setAttribute("open", "");
|
||||||
this.line.appendChild(this.expander);
|
this.line.appendChild(this.expander);
|
||||||
|
|
||||||
this.icon = doc.createElementNS(HTML_NS, "span");
|
|
||||||
this.line.appendChild(this.icon);
|
|
||||||
|
|
||||||
this.label = doc.createElementNS(HTML_NS, "span");
|
this.label = doc.createElementNS(HTML_NS, "span");
|
||||||
this.label.className = "file-label";
|
this.label.className = "file-label";
|
||||||
this.line.appendChild(this.label);
|
this.line.appendChild(this.label);
|
||||||
|
@ -93,11 +90,10 @@ var ResourceContainer = Class({
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this.elt.remove();
|
this.elt.remove();
|
||||||
this.expander.remove();
|
this.expander.remove();
|
||||||
this.icon.remove();
|
|
||||||
this.highlighter.remove();
|
this.highlighter.remove();
|
||||||
this.children.remove();
|
this.children.remove();
|
||||||
this.label.remove();
|
this.label.remove();
|
||||||
this.elt = this.expander = this.icon = this.highlighter = this.children = this.label = null;
|
this.elt = this.expander = this.highlighter = this.children = this.label = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,29 +121,6 @@ var ResourceContainer = Class({
|
||||||
|
|
||||||
this.tree.options.resourceFormatter(this.resource, this.label);
|
this.tree.options.resourceFormatter(this.resource, this.label);
|
||||||
|
|
||||||
this.icon.className = "file-icon";
|
|
||||||
|
|
||||||
let contentCategory = this.resource.contentCategory;
|
|
||||||
let baseName = this.resource.basename || "";
|
|
||||||
|
|
||||||
if (!this.resource.parent) {
|
|
||||||
this.icon.classList.add("icon-none");
|
|
||||||
} else if (this.resource.isDir) {
|
|
||||||
this.icon.classList.add("icon-folder");
|
|
||||||
} else if (baseName.endsWith(".manifest") || baseName.endsWith(".webapp")) {
|
|
||||||
this.icon.classList.add("icon-manifest");
|
|
||||||
} else if (contentCategory === "js") {
|
|
||||||
this.icon.classList.add("icon-js");
|
|
||||||
} else if (contentCategory === "css") {
|
|
||||||
this.icon.classList.add("icon-css");
|
|
||||||
} else if (contentCategory === "html") {
|
|
||||||
this.icon.classList.add("icon-html");
|
|
||||||
} else if (contentCategory === "image") {
|
|
||||||
this.icon.classList.add("icon-img");
|
|
||||||
} else {
|
|
||||||
this.icon.classList.add("icon-file");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.expander.style.visibility = this.resource.hasChildren ? "visible" : "hidden";
|
this.expander.style.visibility = this.resource.hasChildren ? "visible" : "hidden";
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,6 +45,7 @@ const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).de
|
||||||
const Telemetry = require("devtools/shared/telemetry");
|
const Telemetry = require("devtools/shared/telemetry");
|
||||||
const Editor = require("devtools/sourceeditor/editor");
|
const Editor = require("devtools/sourceeditor/editor");
|
||||||
const TargetFactory = require("devtools/framework/target").TargetFactory;
|
const TargetFactory = require("devtools/framework/target").TargetFactory;
|
||||||
|
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||||
|
|
||||||
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
@ -2169,6 +2170,10 @@ ScratchpadTarget.prototype = Heritage.extend(ScratchpadTab.prototype, {
|
||||||
*/
|
*/
|
||||||
function ScratchpadSidebar(aScratchpad)
|
function ScratchpadSidebar(aScratchpad)
|
||||||
{
|
{
|
||||||
|
// Make sure to decorate this object. ToolSidebar requires the parent
|
||||||
|
// panel to support event (emit) API.
|
||||||
|
EventEmitter.decorate(this);
|
||||||
|
|
||||||
let ToolSidebar = require("devtools/framework/sidebar").ToolSidebar;
|
let ToolSidebar = require("devtools/framework/sidebar").ToolSidebar;
|
||||||
let tabbox = document.querySelector("#scratchpad-sidebar");
|
let tabbox = document.querySelector("#scratchpad-sidebar");
|
||||||
this._sidebar = new ToolSidebar(tabbox, this, "scratchpad");
|
this._sidebar = new ToolSidebar(tabbox, this, "scratchpad");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_bezierCanvas.js]
|
[test_bezierCanvas.js]
|
||||||
[test_cubicBezier.js]
|
[test_cubicBezier.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_parseDeclarations.js]
|
[test_parseDeclarations.js]
|
||||||
[test_parseSingleValue.js]
|
[test_parseSingleValue.js]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
experiments_1.manifest
|
experiments_1.manifest
|
||||||
experiment-1.xpi
|
experiment-1.xpi
|
||||||
|
|
|
@ -444,6 +444,9 @@
|
||||||
@BINPATH@/components/addoncompat.manifest
|
@BINPATH@/components/addoncompat.manifest
|
||||||
@BINPATH@/components/multiprocessShims.js
|
@BINPATH@/components/multiprocessShims.js
|
||||||
@BINPATH@/components/pluginGlue.manifest
|
@BINPATH@/components/pluginGlue.manifest
|
||||||
|
@BINPATH@/components/ProcessSingleton.manifest
|
||||||
|
@BINPATH@/components/MainProcessSingleton.js
|
||||||
|
@BINPATH@/components/ContentProcessSingleton.js
|
||||||
@BINPATH@/browser/components/nsSessionStore.manifest
|
@BINPATH@/browser/components/nsSessionStore.manifest
|
||||||
@BINPATH@/browser/components/nsSessionStartup.js
|
@BINPATH@/browser/components/nsSessionStartup.js
|
||||||
@BINPATH@/browser/components/nsSessionStore.js
|
@BINPATH@/browser/components/nsSessionStore.js
|
||||||
|
|
|
@ -74,7 +74,10 @@ else
|
||||||
SEARCHPLUGINS_NAMES = $(shell cat $(call MERGE_FILE,/searchplugins/list.txt))
|
SEARCHPLUGINS_NAMES = $(shell cat $(call MERGE_FILE,/searchplugins/list.txt))
|
||||||
endif
|
endif
|
||||||
SEARCHPLUGINS_PATH := $(FINAL_TARGET)/searchplugins
|
SEARCHPLUGINS_PATH := $(FINAL_TARGET)/searchplugins
|
||||||
SEARCHPLUGINS := $(addsuffix .xml,$(SEARCHPLUGINS_NAMES))
|
# metro build call a searchplugins target for search engine plugins
|
||||||
|
.PHONY: searchplugins
|
||||||
|
SEARCHPLUGINS_TARGET := libs searchplugins
|
||||||
|
SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_NAMES)),$(or $(wildcard $(call MERGE_FILE,searchplugins/$(plugin))),$(info Missing searchplugin: $(plugin))))
|
||||||
PP_TARGETS += SEARCHPLUGINS
|
PP_TARGETS += SEARCHPLUGINS
|
||||||
|
|
||||||
# Required for l10n.mk - defines a list of app sub dirs that should
|
# Required for l10n.mk - defines a list of app sub dirs that should
|
||||||
|
@ -119,10 +122,6 @@ libs:: $(addprefix generic/profile/,$(PROFILE_FILES))
|
||||||
libs:: $(call MERGE_FILES,$(addprefix profile/chrome/,$(PROFILE_CHROME)))
|
libs:: $(call MERGE_FILES,$(addprefix profile/chrome/,$(PROFILE_CHROME)))
|
||||||
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile/chrome
|
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile/chrome
|
||||||
|
|
||||||
# metro build calls back here for search engine plugins
|
|
||||||
searchplugins: $(addprefix $(FINAL_TARGET)/searchplugins/,$(SEARCHPLUGINS))
|
|
||||||
.PHONY: searchplugins
|
|
||||||
|
|
||||||
libs-%:
|
libs-%:
|
||||||
$(NSINSTALL) -D $(DIST)/install
|
$(NSINSTALL) -D $(DIST)/install
|
||||||
@$(MAKE) -C ../../toolkit/locales libs-$*
|
@$(MAKE) -C ../../toolkit/locales libs-$*
|
||||||
|
|
|
@ -18,7 +18,9 @@ const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||||
const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='win'/>";
|
const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='win'/>";
|
||||||
const NEWTAB_URL = "about:newtab";
|
const NEWTAB_URL = "about:newtab";
|
||||||
const PREF_BRANCH = "browser.newtab.";
|
|
||||||
|
const PREF_NEWTAB_URL = "browser.newtab.url";
|
||||||
|
const PREF_NEWTAB_PRELOAD = "browser.newtab.preload";
|
||||||
|
|
||||||
// The interval between swapping in a preload docShell and kicking off the
|
// The interval between swapping in a preload docShell and kicking off the
|
||||||
// next preload in the background.
|
// next preload in the background.
|
||||||
|
@ -34,6 +36,11 @@ const TOPIC_XUL_WINDOW_CLOSED = "xul-window-destroyed";
|
||||||
|
|
||||||
const BROWSER_CONTENT_SCRIPT = "chrome://browser/content/content.js";
|
const BROWSER_CONTENT_SCRIPT = "chrome://browser/content/content.js";
|
||||||
|
|
||||||
|
function isPreloadingEnabled() {
|
||||||
|
return Services.prefs.getBoolPref(PREF_NEWTAB_PRELOAD) &&
|
||||||
|
!Services.prefs.prefHasUserValue(PREF_NEWTAB_URL);
|
||||||
|
}
|
||||||
|
|
||||||
function createTimer(obj, delay) {
|
function createTimer(obj, delay) {
|
||||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
timer.init(obj, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
timer.init(obj, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||||
|
@ -48,18 +55,13 @@ function clearTimer(timer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.BrowserNewTabPreloader = {
|
this.BrowserNewTabPreloader = {
|
||||||
init: function Preloader_init() {
|
|
||||||
Preferences.init();
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit: function Preloader_uninit() {
|
uninit: function Preloader_uninit() {
|
||||||
HostFrame.destroy();
|
HostFrame.destroy();
|
||||||
Preferences.uninit();
|
|
||||||
HiddenBrowsers.uninit();
|
HiddenBrowsers.uninit();
|
||||||
},
|
},
|
||||||
|
|
||||||
newTab: function Preloader_newTab(aTab) {
|
newTab: function Preloader_newTab(aTab) {
|
||||||
if (!Preferences.enabled) {
|
if (!isPreloadingEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,41 +83,6 @@ this.BrowserNewTabPreloader = {
|
||||||
|
|
||||||
Object.freeze(BrowserNewTabPreloader);
|
Object.freeze(BrowserNewTabPreloader);
|
||||||
|
|
||||||
let Preferences = {
|
|
||||||
_enabled: null,
|
|
||||||
_branch: null,
|
|
||||||
|
|
||||||
get enabled() {
|
|
||||||
if (this._enabled === null) {
|
|
||||||
this._enabled = this._branch.getBoolPref("preload") &&
|
|
||||||
!this._branch.prefHasUserValue("url");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._enabled;
|
|
||||||
},
|
|
||||||
|
|
||||||
init: function Preferences_init() {
|
|
||||||
this._branch = Services.prefs.getBranch(PREF_BRANCH);
|
|
||||||
this._branch.addObserver("", this, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit: function Preferences_uninit() {
|
|
||||||
if (this._branch) {
|
|
||||||
this._branch.removeObserver("", this);
|
|
||||||
this._branch = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
observe: function Preferences_observe() {
|
|
||||||
let prevEnabled = this._enabled;
|
|
||||||
this._enabled = null;
|
|
||||||
|
|
||||||
if (prevEnabled && !this.enabled) {
|
|
||||||
HiddenBrowsers.uninit();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let HiddenBrowsers = {
|
let HiddenBrowsers = {
|
||||||
_browsers: null,
|
_browsers: null,
|
||||||
_updateTimer: null,
|
_updateTimer: null,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files = blocklist.xml
|
support-files = blocklist.xml
|
||||||
|
|
||||||
[test_social.js]
|
[test_social.js]
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_DirectoryLinksProvider.js]
|
[test_DirectoryLinksProvider.js]
|
||||||
|
|
|
@ -342,7 +342,6 @@ browser.jar:
|
||||||
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
||||||
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
||||||
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
||||||
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
|
|
||||||
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
||||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||||
|
|
|
@ -472,7 +472,6 @@ browser.jar:
|
||||||
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
||||||
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
||||||
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
||||||
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
|
|
||||||
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
||||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||||
|
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 4.0 KiB |
|
@ -78,49 +78,6 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry .file-icon {
|
|
||||||
display: inline-block;
|
|
||||||
background: url(file-icons-sheet@2x.png);
|
|
||||||
background-size: 140px 15px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: 20px;
|
|
||||||
height: 15px;
|
|
||||||
background-position: -40px 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .file-icon.icon-none {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-css {
|
|
||||||
background-position: 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-js {
|
|
||||||
background-position: -20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-html {
|
|
||||||
background-position: -40px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-file {
|
|
||||||
background-position: -60px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-folder {
|
|
||||||
background-position: -80px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-img {
|
|
||||||
background-position: -100px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry .icon-manifest {
|
|
||||||
background-position: -120px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
|
@ -378,7 +378,6 @@ browser.jar:
|
||||||
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
skin/classic/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
||||||
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
||||||
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
||||||
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
|
|
||||||
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
||||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||||
|
@ -806,7 +805,6 @@ browser.jar:
|
||||||
skin/classic/aero/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
skin/classic/aero/browser/devtools/arrow-e@2x.png (../shared/devtools/images/arrow-e@2x.png)
|
||||||
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
skin/classic/browser/devtools/responsiveui-home.png (../shared/devtools/responsiveui-home.png)
|
||||||
skin/classic/aero/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
skin/classic/aero/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
|
||||||
skin/classic/aero/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
|
|
||||||
skin/classic/aero/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
skin/classic/aero/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
|
||||||
skin/classic/aero/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
skin/classic/aero/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||||
skin/classic/aero/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
skin/classic/aero/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||||
|
|
|
@ -326,6 +326,34 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then
|
||||||
DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
|
DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# bionic in Android < 4.1 doesn't support PIE
|
||||||
|
# On OSX, the linker defaults to building PIE programs when targetting OSX 10.7+,
|
||||||
|
# but not when targetting OSX < 10.7. OSX < 10.7 doesn't support running PIE
|
||||||
|
# programs, so as long as support for OSX 10.6 is kept, we can't build PIE.
|
||||||
|
# Even after dropping 10.6 support, MOZ_PIE would not be useful since it's the
|
||||||
|
# default (and clang says the -pie option is not used).
|
||||||
|
# On other Unix systems, some file managers (Nautilus) can't start PIE programs
|
||||||
|
MOZ_PIE=
|
||||||
|
|
||||||
|
MOZ_ARG_ENABLE_BOOL(pie,
|
||||||
|
[ --enable-pie Enable Position Independent Executables],
|
||||||
|
MOZ_PIE=1,
|
||||||
|
MOZ_PIE= )
|
||||||
|
|
||||||
|
if test "$GNU_CC" -a -n "$MOZ_PIE"; then
|
||||||
|
AC_MSG_CHECKING([for PIE support])
|
||||||
|
_SAVE_LDFLAGS=$LDFLAGS
|
||||||
|
LDFLAGS="$LDFLAGS -pie"
|
||||||
|
AC_TRY_LINK(,,AC_MSG_RESULT([yes])
|
||||||
|
[MOZ_PROGRAM_LDFLAGS="$MOZ_PROGRAM_LDFLAGS -pie"],
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR([--enable-pie requires PIE support from the linker.]))
|
||||||
|
LDFLAGS=$_SAVE_LDFLAGS
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(MOZ_PROGRAM_LDFLAGS)
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl GCC and clang will fail if given an unknown warning option like -Wfoobar.
|
dnl GCC and clang will fail if given an unknown warning option like -Wfoobar.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head_crtestutils.js
|
head = head_crtestutils.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
support-files = data/**
|
support-files = data/**
|
||||||
|
|
||||||
[test_abi.js]
|
[test_abi.js]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_resolve_uris_ipc.js]
|
[test_resolve_uris_ipc.js]
|
||||||
|
|
|
@ -641,6 +641,8 @@ endif
|
||||||
|
|
||||||
endif # NO_PROFILE_GUIDED_OPTIMIZE
|
endif # NO_PROFILE_GUIDED_OPTIMIZE
|
||||||
|
|
||||||
|
MOZ_PROGRAM_LDFLAGS += $(MOZ_GLUE_PROGRAM_LDFLAGS)
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
checkout:
|
checkout:
|
||||||
|
@ -673,7 +675,7 @@ $(PROGRAM): $(PROGOBJS) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESF
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(RM) $@.manifest
|
@$(RM) $@.manifest
|
||||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||||
$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(PROGOBJS) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS)
|
$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $(PROGOBJS) $(RESFILE) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS)
|
||||||
ifdef MSMANIFEST_TOOL
|
ifdef MSMANIFEST_TOOL
|
||||||
@if test -f $@.manifest; then \
|
@if test -f $@.manifest; then \
|
||||||
if test -f '$(srcdir)/$@.manifest'; then \
|
if test -f '$(srcdir)/$@.manifest'; then \
|
||||||
|
@ -694,7 +696,7 @@ ifdef MOZ_PROFILE_GENERATE
|
||||||
touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink
|
touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink
|
||||||
endif
|
endif
|
||||||
else # !WINNT || GNU_CC
|
else # !WINNT || GNU_CC
|
||||||
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
|
$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
|
||||||
$(call CHECK_BINARY,$@)
|
$(call CHECK_BINARY,$@)
|
||||||
endif # WINNT && !GNU_CC
|
endif # WINNT && !GNU_CC
|
||||||
|
|
||||||
|
@ -742,7 +744,7 @@ endif
|
||||||
$(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
|
$(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||||
$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS)
|
$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_PROGRAM_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS)
|
||||||
ifdef MSMANIFEST_TOOL
|
ifdef MSMANIFEST_TOOL
|
||||||
@if test -f $@.manifest; then \
|
@if test -f $@.manifest; then \
|
||||||
mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
||||||
|
@ -750,7 +752,7 @@ ifdef MSMANIFEST_TOOL
|
||||||
fi
|
fi
|
||||||
endif # MSVC with manifest tool
|
endif # MSVC with manifest tool
|
||||||
else
|
else
|
||||||
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
|
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(EXTRA_LIBS) $(OS_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
|
||||||
$(call CHECK_BINARY,$@)
|
$(call CHECK_BINARY,$@)
|
||||||
endif # WINNT && !GNU_CC
|
endif # WINNT && !GNU_CC
|
||||||
|
|
||||||
|
|
115
configure.in
115
configure.in
|
@ -1412,22 +1412,54 @@ if test "$GNU_CC"; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Turn on GNU-specific warnings:
|
# Turn on gcc/clang warnings:
|
||||||
# -Wall - turn on a lot of warnings
|
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
|
||||||
# -Wpointer-arith - good to have
|
|
||||||
# -Wdeclaration-after-statement - MSVC doesn't like these
|
|
||||||
# -Werror=return-type - catches missing returns, zero false positives
|
|
||||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
|
||||||
# -Wtype-limits - catches overflow bugs, few false positives
|
|
||||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
|
||||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
|
||||||
#
|
#
|
||||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement"
|
# -Wall - turn on a lot of warnings
|
||||||
MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
|
# -Wchar-subscripts - catches array index using signed char
|
||||||
MOZ_C_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_c_has_werror_int_to_pointer_cast)
|
# -Wcomment - catches nested comments
|
||||||
MOZ_C_SUPPORTS_WARNING(-W, type-limits, ac_c_has_wtype_limits)
|
# -Wdeclaration-after-statement - MSVC doesn't like these
|
||||||
MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
|
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||||
MOZ_C_SUPPORTS_WARNING(-W, sign-compare, ac_c_has_sign_compare)
|
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
|
||||||
|
# -Wenum-compare - catches comparison of different enum types
|
||||||
|
# -Wignored-qualifiers - catches returns types with qualifiers like const
|
||||||
|
# -Wimplicit-int - catches C variable declaration without a type
|
||||||
|
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
|
||||||
|
# -Wmultichar - catches multicharacter integer constants like 'THIS'
|
||||||
|
# -Wnonnull - catches NULL used with functions arguments marked as non-null
|
||||||
|
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||||
|
# -Wpointer-sign - catches mixing pointers to signed and unsigned types
|
||||||
|
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
|
||||||
|
# -Wreturn-type - catches missing returns, zero false positives
|
||||||
|
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||||
|
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||||
|
# -Wtrigraphs - catches unlikely use of trigraphs
|
||||||
|
# -Wtype-limits - catches overflow bugs, few false positives
|
||||||
|
# -Wunknown-pragmas - catches unexpected #pragma directives
|
||||||
|
#
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wdeclaration-after-statement"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wempty-body"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-to-int-cast"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wsign-compare"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
|
||||||
|
|
||||||
|
# Treat some warnings as errors:
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=char-subscripts"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=comment"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=endif-labels"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=enum-compare"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=ignored-qualifiers"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=implicit-int"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=int-to-pointer-cast"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=multichar"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=nonnull"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-arith"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-sign"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
|
||||||
|
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
|
||||||
|
|
||||||
# Turn off the following warnings that -Wall turns on:
|
# Turn off the following warnings that -Wall turns on:
|
||||||
# -Wno-unused - lots of violations in third-party code
|
# -Wno-unused - lots of violations in third-party code
|
||||||
|
@ -1478,22 +1510,42 @@ if test "$GNU_CXX"; then
|
||||||
# FIXME: Let us build with strict aliasing. bug 414641.
|
# FIXME: Let us build with strict aliasing. bug 414641.
|
||||||
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
|
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
|
||||||
|
|
||||||
# Turn on GNU-specific warnings:
|
# Turn on gcc/clang warnings:
|
||||||
# -Wall - turn on a lot of warnings
|
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
|
||||||
# -Wpointer-arith - good to have
|
|
||||||
# -Woverloaded-virtual - ???
|
|
||||||
# -Werror=return-type - catches missing returns, zero false positives
|
|
||||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
|
||||||
# -Werror=type-limits - catches overflow bugs, few false positives
|
|
||||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
|
||||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
|
||||||
#
|
#
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
|
# -Wall - turn on a lot of warnings
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
|
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_cxx_has_werror_int_to_pointer_cast)
|
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=type-limits, ac_cxx_has_werror_type_limits)
|
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
|
# -Wmissing-braces - catches aggregate initializers missing nested braces
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-W, sign-compare, ac_cxx_has_sign_compare)
|
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||||
|
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||||
|
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||||
|
# -Wreturn-type - catches missing returns, zero false positives
|
||||||
|
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||||
|
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||||
|
# -Wtrigraphs - catches unlikely use of trigraphs
|
||||||
|
# -Wtype-limits - catches overflow bugs, few false positives
|
||||||
|
# -Wunused-label - catches unused goto labels
|
||||||
|
# -Wwrite-strings - catches non-const char* pointers to string literals
|
||||||
|
#
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wwrite-strings"
|
||||||
|
|
||||||
|
# Treat some warnings as errors:
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=parentheses"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
|
||||||
|
|
||||||
# Turn off the following warnings that -Wall turns on:
|
# Turn off the following warnings that -Wall turns on:
|
||||||
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
|
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
|
||||||
|
@ -1501,7 +1553,8 @@ if test "$GNU_CXX"; then
|
||||||
# for performance reasons, and because GCC and clang accept it (though
|
# for performance reasons, and because GCC and clang accept it (though
|
||||||
# clang warns about it).
|
# clang warns about it).
|
||||||
#
|
#
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-Wno-, invalid-offsetof, ac_cxx_has_wno_invalid_offsetof)
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
|
||||||
|
|
||||||
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
|
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
|
||||||
|
|
||||||
if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
|
if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ImportLoader MOZ_FINAL : public nsIStreamListener
|
||||||
class Updater {
|
class Updater {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Updater(ImportLoader* aLoader) : mLoader(aLoader)
|
explicit Updater(ImportLoader* aLoader) : mLoader(aLoader)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// After a new link is added that refers to this import, we
|
// After a new link is added that refers to this import, we
|
||||||
|
|
|
@ -555,7 +555,7 @@ namespace {
|
||||||
struct PositionComparator
|
struct PositionComparator
|
||||||
{
|
{
|
||||||
Element* const mElement;
|
Element* const mElement;
|
||||||
PositionComparator(Element* const aElement) : mElement(aElement) {}
|
explicit PositionComparator(Element* const aElement) : mElement(aElement) {}
|
||||||
|
|
||||||
int operator()(void* aElement) const {
|
int operator()(void* aElement) const {
|
||||||
Element* curElement = static_cast<Element*>(aElement);
|
Element* curElement = static_cast<Element*>(aElement);
|
||||||
|
@ -2752,6 +2752,33 @@ AppendCSPFromHeader(nsIContentSecurityPolicy* csp,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDocument::IsLoopDocument(nsIChannel *aChannel)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIURI> chanURI;
|
||||||
|
nsresult rv = aChannel->GetOriginalURI(getter_AddRefs(chanURI));
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
|
bool isAbout = false;
|
||||||
|
bool isLoop = false;
|
||||||
|
rv = chanURI->SchemeIs("about", &isAbout);
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
if (isAbout) {
|
||||||
|
nsCOMPtr<nsIURI> loopURI;
|
||||||
|
rv = NS_NewURI(getter_AddRefs(loopURI), "about:loopconversation");
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
rv = chanURI->EqualsExceptRef(loopURI, &isLoop);
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
if (!isLoop) {
|
||||||
|
rv = NS_NewURI(getter_AddRefs(loopURI), "about:looppanel");
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
rv = chanURI->EqualsExceptRef(loopURI, &isLoop);
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isLoop;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsDocument::InitCSP(nsIChannel* aChannel)
|
nsDocument::InitCSP(nsIChannel* aChannel)
|
||||||
{
|
{
|
||||||
|
@ -2805,9 +2832,13 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this is part of the Loop/Hello service
|
||||||
|
bool applyLoopCSP = IsLoopDocument(aChannel);
|
||||||
|
|
||||||
// If there's no CSP to apply, go ahead and return early
|
// If there's no CSP to apply, go ahead and return early
|
||||||
if (!applyAppDefaultCSP &&
|
if (!applyAppDefaultCSP &&
|
||||||
!applyAppManifestCSP &&
|
!applyAppManifestCSP &&
|
||||||
|
!applyLoopCSP &&
|
||||||
cspHeaderValue.IsEmpty() &&
|
cspHeaderValue.IsEmpty() &&
|
||||||
cspROHeaderValue.IsEmpty()) {
|
cspROHeaderValue.IsEmpty()) {
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
|
@ -2880,6 +2911,17 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||||
csp->AppendPolicy(appManifestCSP, false);
|
csp->AppendPolicy(appManifestCSP, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----- if the doc is part of Loop, apply the loop CSP
|
||||||
|
if (applyLoopCSP) {
|
||||||
|
nsAdoptingString loopCSP;
|
||||||
|
loopCSP = Preferences::GetString("loop.CSP");
|
||||||
|
NS_ASSERTION(loopCSP, "Missing loop.CSP preference");
|
||||||
|
// If the pref has been removed, we continue without setting a CSP
|
||||||
|
if (loopCSP) {
|
||||||
|
csp->AppendPolicy(loopCSP, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----- if there's a full-strength CSP header, apply it.
|
// ----- if there's a full-strength CSP header, apply it.
|
||||||
if (!cspHeaderValue.IsEmpty()) {
|
if (!cspHeaderValue.IsEmpty()) {
|
||||||
rv = AppendCSPFromHeader(csp, cspHeaderValue, false);
|
rv = AppendCSPFromHeader(csp, cspHeaderValue, false);
|
||||||
|
|
|
@ -1662,6 +1662,7 @@ private:
|
||||||
void DoUnblockOnload();
|
void DoUnblockOnload();
|
||||||
|
|
||||||
nsresult CheckFrameOptions();
|
nsresult CheckFrameOptions();
|
||||||
|
bool IsLoopDocument(nsIChannel* aChannel);
|
||||||
nsresult InitCSP(nsIChannel* aChannel);
|
nsresult InitCSP(nsIChannel* aChannel);
|
||||||
|
|
||||||
void FlushCSPWebConsoleErrorQueue()
|
void FlushCSPWebConsoleErrorQueue()
|
||||||
|
|
|
@ -1735,7 +1735,7 @@ public:
|
||||||
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
|
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||||
IPC::Principal(aPrincipal), aJSONRetVal);
|
IPC::Principal(aPrincipal), aJSONRetVal);
|
||||||
}
|
}
|
||||||
return cc->CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
return cc->SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
|
||||||
IPC::Principal(aPrincipal), aJSONRetVal);
|
IPC::Principal(aPrincipal), aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1873,7 +1873,7 @@ struct interval
|
||||||
struct CombiningComparator
|
struct CombiningComparator
|
||||||
{
|
{
|
||||||
const char16_t mUcs;
|
const char16_t mUcs;
|
||||||
CombiningComparator(char16_t ucs) : mUcs(ucs) {}
|
explicit CombiningComparator(char16_t aUcs) : mUcs(aUcs) {}
|
||||||
int operator()(const interval& combining) const {
|
int operator()(const interval& combining) const {
|
||||||
if (mUcs > combining.last)
|
if (mUcs > combining.last)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head_utilities.js
|
head = head_utilities.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
1_original.xml
|
1_original.xml
|
||||||
1_result.xml
|
1_result.xml
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_bug553888_wrap.js]
|
[test_bug553888_wrap.js]
|
||||||
[test_xhr_document_ipc.js]
|
[test_xhr_document_ipc.js]
|
||||||
|
|
|
@ -2244,7 +2244,7 @@ namespace {
|
||||||
struct PositionComparator
|
struct PositionComparator
|
||||||
{
|
{
|
||||||
nsIContent* const mElement;
|
nsIContent* const mElement;
|
||||||
PositionComparator(nsIContent* const element) : mElement(element) {}
|
explicit PositionComparator(nsIContent* const aElement) : mElement(aElement) {}
|
||||||
|
|
||||||
int operator()(nsIContent* aElement) const {
|
int operator()(nsIContent* aElement) const {
|
||||||
if (mElement == aElement) {
|
if (mElement == aElement) {
|
||||||
|
@ -2260,7 +2260,7 @@ struct PositionComparator
|
||||||
struct NodeListAdaptor
|
struct NodeListAdaptor
|
||||||
{
|
{
|
||||||
nsINodeList* const mList;
|
nsINodeList* const mList;
|
||||||
NodeListAdaptor(nsINodeList* aList) : mList(aList) {}
|
explicit NodeListAdaptor(nsINodeList* aList) : mList(aList) {}
|
||||||
nsIContent* operator[](size_t aIdx) const {
|
nsIContent* operator[](size_t aIdx) const {
|
||||||
return mList->Item(aIdx);
|
return mList->Item(aIdx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2478,8 +2478,8 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||||
// will take care of calling MediaDecoder::PlaybackEnded.
|
// will take care of calling MediaDecoder::PlaybackEnded.
|
||||||
if (mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING &&
|
if (mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING &&
|
||||||
!mDecoder->GetDecodedStream()) {
|
!mDecoder->GetDecodedStream()) {
|
||||||
int64_t videoTime = HasVideo() ? mVideoFrameEndTime : 0;
|
int64_t clockTime = std::max(mAudioEndTime, mVideoFrameEndTime);
|
||||||
int64_t clockTime = std::max(mEndTime, videoTime);
|
clockTime = std::max(int64_t(0), std::max(clockTime, mEndTime));
|
||||||
UpdatePlaybackPosition(clockTime);
|
UpdatePlaybackPosition(clockTime);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -3143,7 +3143,13 @@ void MediaDecoderStateMachine::OnAudioSinkError()
|
||||||
|
|
||||||
mAudioCompleted = true;
|
mAudioCompleted = true;
|
||||||
|
|
||||||
// Notify media decoder/element about this error.
|
// Make the best effort to continue playback when there is video.
|
||||||
|
if (HasVideo()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise notify media decoder/element about this error for it makes
|
||||||
|
// no sense to play an audio-only file without sound output.
|
||||||
RefPtr<nsIRunnable> task(
|
RefPtr<nsIRunnable> task(
|
||||||
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnDecodeError));
|
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnDecodeError));
|
||||||
nsresult rv = mDecodeTaskQueue->Dispatch(task);
|
nsresult rv = mDecodeTaskQueue->Dispatch(task);
|
||||||
|
|
|
@ -226,7 +226,7 @@ StealJSArrayDataIntoThreadSharedFloatArrayBufferList(JSContext* aJSContext,
|
||||||
? (uint8_t*) JS_StealArrayBufferContents(aJSContext, arrayBuffer)
|
? (uint8_t*) JS_StealArrayBufferContents(aJSContext, arrayBuffer)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (stolenData) {
|
if (stolenData) {
|
||||||
result->SetData(i, stolenData, reinterpret_cast<float*>(stolenData));
|
result->SetData(i, stolenData, js_free, reinterpret_cast<float*>(stolenData));
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Storage {
|
struct Storage {
|
||||||
Storage()
|
Storage() :
|
||||||
{
|
mDataToFree(nullptr),
|
||||||
mDataToFree = nullptr;
|
mFree(nullptr),
|
||||||
mSampleData = nullptr;
|
mSampleData(nullptr)
|
||||||
|
{}
|
||||||
|
~Storage() {
|
||||||
|
if (mFree) {
|
||||||
|
mFree(mDataToFree);
|
||||||
|
} else { MOZ_ASSERT(!mDataToFree); }
|
||||||
}
|
}
|
||||||
~Storage() { free(mDataToFree); }
|
|
||||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
// NB: mSampleData might not be owned, if it is it just points to
|
// NB: mSampleData might not be owned, if it is it just points to
|
||||||
|
@ -51,6 +55,7 @@ public:
|
||||||
return aMallocSizeOf(mDataToFree);
|
return aMallocSizeOf(mDataToFree);
|
||||||
}
|
}
|
||||||
void* mDataToFree;
|
void* mDataToFree;
|
||||||
|
void (*mFree)(void*);
|
||||||
const float* mSampleData;
|
const float* mSampleData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,11 +72,17 @@ public:
|
||||||
* Call this only during initialization, before the object is handed to
|
* Call this only during initialization, before the object is handed to
|
||||||
* any other thread.
|
* any other thread.
|
||||||
*/
|
*/
|
||||||
void SetData(uint32_t aIndex, void* aDataToFree, const float* aData)
|
void SetData(uint32_t aIndex, void* aDataToFree, void (*aFreeFunc)(void*), const float* aData)
|
||||||
{
|
{
|
||||||
Storage* s = &mContents[aIndex];
|
Storage* s = &mContents[aIndex];
|
||||||
free(s->mDataToFree);
|
if (s->mFree) {
|
||||||
|
s->mFree(s->mDataToFree);
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(!s->mDataToFree);
|
||||||
|
}
|
||||||
|
|
||||||
s->mDataToFree = aDataToFree;
|
s->mDataToFree = aDataToFree;
|
||||||
|
s->mFree = aFreeFunc;
|
||||||
s->mSampleData = aData;
|
s->mSampleData = aData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv)
|
||||||
for (uint32_t i = 0; i < data->GetChannels(); ++i) {
|
for (uint32_t i = 0; i < data->GetChannels(); ++i) {
|
||||||
PodCopy(channelData + length * i, data->GetData(i), mBuffer->Length());
|
PodCopy(channelData + length * i, data->GetData(i), mBuffer->Length());
|
||||||
PodZero(channelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length());
|
PodZero(channelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length());
|
||||||
paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, channelData);
|
paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, channelData);
|
||||||
}
|
}
|
||||||
data = paddedBuffer;
|
data = paddedBuffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,9 @@ PeriodicWave::PeriodicWave(AudioContext* aContext,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PodCopy(buffer, aRealData, aLength);
|
PodCopy(buffer, aRealData, aLength);
|
||||||
mCoefficients->SetData(0, buffer, buffer);
|
mCoefficients->SetData(0, buffer, free, buffer);
|
||||||
PodCopy(buffer+aLength, aImagData, aLength);
|
PodCopy(buffer+aLength, aImagData, aLength);
|
||||||
mCoefficients->SetData(1, nullptr, buffer+aLength);
|
mCoefficients->SetData(1, nullptr, free, buffer+aLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct RemoteVoice {
|
||||||
bool localService;
|
bool localService;
|
||||||
};
|
};
|
||||||
|
|
||||||
intr protocol PSpeechSynthesis
|
sync protocol PSpeechSynthesis
|
||||||
{
|
{
|
||||||
manager PContent;
|
manager PContent;
|
||||||
manages PSpeechSynthesisRequest;
|
manages PSpeechSynthesisRequest;
|
||||||
|
|
|
@ -9,7 +9,7 @@ include protocol PSpeechSynthesis;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
intr protocol PSpeechSynthesisRequest
|
async protocol PSpeechSynthesisRequest
|
||||||
{
|
{
|
||||||
manager PSpeechSynthesis;
|
manager PSpeechSynthesis;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head_content.js
|
head = head_content.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
empty_document.xml
|
empty_document.xml
|
||||||
isequalnode_data.xml
|
isequalnode_data.xml
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head_docshell.js
|
head = head_docshell.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
|
|
||||||
[test_bug414201_jfif.js]
|
[test_bug414201_jfif.js]
|
||||||
[test_bug442584.js]
|
[test_bug442584.js]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_pb_notification_ipc.js]
|
[test_pb_notification_ipc.js]
|
||||||
# Bug 751575: Perma-fails with: command timed out: 1200 seconds without output
|
# Bug 751575: Perma-fails with: command timed out: 1200 seconds without output
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head =
|
head =
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
|
|
||||||
[test_activityFilters.js]
|
[test_activityFilters.js]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "URLSearchParams.h"
|
#include "URLSearchParams.h"
|
||||||
#include "mozilla/dom/URLSearchParamsBinding.h"
|
#include "mozilla/dom/URLSearchParamsBinding.h"
|
||||||
#include "mozilla/dom/EncodingUtils.h"
|
#include "mozilla/dom/EncodingUtils.h"
|
||||||
|
#include "nsDOMString.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -230,7 +231,7 @@ URLSearchParams::RemoveObservers()
|
||||||
void
|
void
|
||||||
URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
|
URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
|
||||||
{
|
{
|
||||||
aRetval.Truncate();
|
SetDOMStringToNull(aRetval);
|
||||||
|
|
||||||
for (uint32_t i = 0, len = mSearchParams.Length(); i < len; ++i) {
|
for (uint32_t i = 0, len = mSearchParams.Length(); i < len; ++i) {
|
||||||
if (mSearchParams[i].mKey.Equals(aName)) {
|
if (mSearchParams[i].mKey.Equals(aName)) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
|
||||||
-->
|
-->
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Test for Bug 887836</title>
|
<title>Test for URLSearchParams</title>
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
</head>
|
</head>
|
||||||
|
@ -30,7 +30,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
|
||||||
var u = new URLSearchParams();
|
var u = new URLSearchParams();
|
||||||
ok(u, "URLSearchParams created");
|
ok(u, "URLSearchParams created");
|
||||||
is(u.has('foo'), false, 'URLSearchParams.has(foo)');
|
is(u.has('foo'), false, 'URLSearchParams.has(foo)');
|
||||||
is(u.get('foo'), '', 'URLSearchParams.get(foo)');
|
is(u.get('foo'), null, 'URLSearchParams.get(foo)');
|
||||||
is(u.getAll('foo').length, 0, 'URLSearchParams.getAll(foo)');
|
is(u.getAll('foo').length, 0, 'URLSearchParams.getAll(foo)');
|
||||||
|
|
||||||
u.append('foo', 'bar');
|
u.append('foo', 'bar');
|
||||||
|
@ -275,6 +275,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
|
||||||
runTest();
|
runTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testGetNULL() {
|
||||||
|
|
||||||
|
var u = new URLSearchParams();
|
||||||
|
is(typeof u.get(''), "object", "typeof URL.searchParams.get('')");
|
||||||
|
is(u.get(''), null, "URL.searchParams.get('') should be null");
|
||||||
|
|
||||||
|
var url = new URL('http://www.example.net?a=b');
|
||||||
|
is(url.searchParams.get('b'), null, "URL.searchParams.get('b') should be null");
|
||||||
|
is(url.searchParams.get('a'), 'b', "URL.searchParams.get('a')");
|
||||||
|
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
|
||||||
var tests = [
|
var tests = [
|
||||||
testSimpleURLSearchParams,
|
testSimpleURLSearchParams,
|
||||||
testCopyURLSearchParams,
|
testCopyURLSearchParams,
|
||||||
|
@ -285,7 +298,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
|
||||||
testEncoding,
|
testEncoding,
|
||||||
testMultiURL,
|
testMultiURL,
|
||||||
testOrdering,
|
testOrdering,
|
||||||
testDelete
|
testDelete,
|
||||||
|
testGetNULL
|
||||||
];
|
];
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
|
|
|
@ -3091,18 +3091,11 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
|
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
|
||||||
{
|
{
|
||||||
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
||||||
// adjust flags for current direction run
|
|
||||||
uint32_t flags = mTextRunFlags;
|
|
||||||
if (direction & 1) {
|
|
||||||
flags |= gfxTextRunFactory::TEXT_IS_RTL;
|
|
||||||
} else {
|
|
||||||
flags &= ~gfxTextRunFactory::TEXT_IS_RTL;
|
|
||||||
}
|
|
||||||
mTextRun = mFontgrp->MakeTextRun(text,
|
mTextRun = mFontgrp->MakeTextRun(text,
|
||||||
length,
|
length,
|
||||||
mThebes,
|
mThebes,
|
||||||
mAppUnitsPerDevPixel,
|
mAppUnitsPerDevPixel,
|
||||||
flags);
|
direction==NSBIDI_RTL ? gfxTextRunFactory::TEXT_IS_RTL : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual nscoord GetWidth()
|
virtual nscoord GetWidth()
|
||||||
|
@ -3128,14 +3121,10 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
virtual void DrawText(nscoord xOffset, nscoord width)
|
virtual void DrawText(nscoord xOffset, nscoord width)
|
||||||
{
|
{
|
||||||
gfxPoint point = mPt;
|
gfxPoint point = mPt;
|
||||||
bool rtl = mTextRun->IsRightToLeft();
|
point.x += xOffset;
|
||||||
bool verticalRun = mTextRun->IsVertical();
|
|
||||||
|
|
||||||
gfxFloat& inlineCoord = verticalRun ? point.y : point.x;
|
|
||||||
inlineCoord += xOffset;
|
|
||||||
|
|
||||||
// offset is given in terms of left side of string
|
// offset is given in terms of left side of string
|
||||||
if (rtl) {
|
if (mTextRun->IsRightToLeft()) {
|
||||||
// Bug 581092 - don't use rounded pixel width to advance to
|
// Bug 581092 - don't use rounded pixel width to advance to
|
||||||
// right-hand end of run, because this will cause different
|
// right-hand end of run, because this will cause different
|
||||||
// glyph positioning for LTR vs RTL drawing of the same
|
// glyph positioning for LTR vs RTL drawing of the same
|
||||||
|
@ -3149,7 +3138,7 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
gfxFont::LOOSE_INK_EXTENTS,
|
gfxFont::LOOSE_INK_EXTENTS,
|
||||||
mThebes,
|
mThebes,
|
||||||
nullptr);
|
nullptr);
|
||||||
inlineCoord += textRunMetrics.mAdvanceWidth;
|
point.x += textRunMetrics.mAdvanceWidth;
|
||||||
// old code was:
|
// old code was:
|
||||||
// point.x += width * mAppUnitsPerDevPixel;
|
// point.x += width * mAppUnitsPerDevPixel;
|
||||||
// TODO: restore this if/when we move to fractional coords
|
// TODO: restore this if/when we move to fractional coords
|
||||||
|
@ -3168,15 +3157,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
mCtx->EnsureTarget();
|
mCtx->EnsureTarget();
|
||||||
for (uint32_t c = 0; c < numRuns; c++) {
|
for (uint32_t c = 0; c < numRuns; c++) {
|
||||||
gfxFont *font = runs[c].mFont;
|
gfxFont *font = runs[c].mFont;
|
||||||
|
|
||||||
bool verticalFont =
|
|
||||||
runs[c].mOrientation == gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT;
|
|
||||||
|
|
||||||
const float& baselineOriginInline =
|
|
||||||
verticalFont ? baselineOrigin.y : baselineOrigin.x;
|
|
||||||
const float& baselineOriginBlock =
|
|
||||||
verticalFont ? baselineOrigin.x : baselineOrigin.y;
|
|
||||||
|
|
||||||
uint32_t endRun = 0;
|
uint32_t endRun = 0;
|
||||||
if (c + 1 < numRuns) {
|
if (c + 1 < numRuns) {
|
||||||
endRun = runs[c + 1].mCharacterOffset;
|
endRun = runs[c + 1].mCharacterOffset;
|
||||||
|
@ -3194,53 +3174,23 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoRestoreTransform sidewaysRestore;
|
|
||||||
if (runs[c].mOrientation ==
|
|
||||||
gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT) {
|
|
||||||
sidewaysRestore.Init(mCtx->mTarget);
|
|
||||||
// TODO: The baseline adjustment here is kinda ad-hoc; eventually
|
|
||||||
// perhaps we should check for horizontal and vertical baseline data
|
|
||||||
// in the font, and adjust accordingly.
|
|
||||||
// (The same will be true for HTML text layout.)
|
|
||||||
const gfxFont::Metrics& metrics = mTextRun->GetFontGroup()->
|
|
||||||
GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal);
|
|
||||||
mCtx->mTarget->SetTransform(mCtx->mTarget->GetTransform().Copy().
|
|
||||||
PreTranslate(baselineOrigin). // translate origin for rotation
|
|
||||||
PreRotate(gfx::Float(M_PI / 2.0)). // turn 90deg clockwise
|
|
||||||
PreTranslate(-baselineOrigin). // undo the translation
|
|
||||||
PreTranslate(Point(0, metrics.emAscent - metrics.emDescent) / 2));
|
|
||||||
// and offset the (alphabetic) baseline of the
|
|
||||||
// horizontally-shaped text from the (centered)
|
|
||||||
// default baseline used for vertical
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<GlyphRenderingOptions> renderingOptions = font->GetGlyphRenderingOptions();
|
RefPtr<GlyphRenderingOptions> renderingOptions = font->GetGlyphRenderingOptions();
|
||||||
|
|
||||||
GlyphBuffer buffer;
|
GlyphBuffer buffer;
|
||||||
|
|
||||||
std::vector<Glyph> glyphBuf;
|
std::vector<Glyph> glyphBuf;
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// This more-or-less duplicates the code found in gfxTextRun::Draw
|
|
||||||
// and the gfxFont methods that uses (Draw, DrawGlyphs, DrawOneGlyph);
|
|
||||||
// it would be nice to refactor and share that code.
|
|
||||||
for (uint32_t i = runs[c].mCharacterOffset; i < endRun; i++) {
|
for (uint32_t i = runs[c].mCharacterOffset; i < endRun; i++) {
|
||||||
Glyph newGlyph;
|
Glyph newGlyph;
|
||||||
|
|
||||||
float& inlinePos =
|
|
||||||
verticalFont ? newGlyph.mPosition.y : newGlyph.mPosition.x;
|
|
||||||
float& blockPos =
|
|
||||||
verticalFont ? newGlyph.mPosition.x : newGlyph.mPosition.y;
|
|
||||||
|
|
||||||
if (glyphs[i].IsSimpleGlyph()) {
|
if (glyphs[i].IsSimpleGlyph()) {
|
||||||
newGlyph.mIndex = glyphs[i].GetSimpleGlyph();
|
newGlyph.mIndex = glyphs[i].GetSimpleGlyph();
|
||||||
if (rtl) {
|
if (mTextRun->IsRightToLeft()) {
|
||||||
inlinePos = baselineOriginInline - advanceSum -
|
newGlyph.mPosition.x = baselineOrigin.x - advanceSum -
|
||||||
glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
|
glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
|
||||||
} else {
|
} else {
|
||||||
inlinePos = baselineOriginInline + advanceSum;
|
newGlyph.mPosition.x = baselineOrigin.x + advanceSum;
|
||||||
}
|
}
|
||||||
blockPos = baselineOriginBlock;
|
newGlyph.mPosition.y = baselineOrigin.y;
|
||||||
advanceSum += glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
|
advanceSum += glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
|
||||||
glyphBuf.push_back(newGlyph);
|
glyphBuf.push_back(newGlyph);
|
||||||
continue;
|
continue;
|
||||||
|
@ -3250,34 +3200,34 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gfxTextRun::DetailedGlyph *d = mTextRun->GetDetailedGlyphs(i);
|
gfxTextRun::DetailedGlyph *detailedGlyphs =
|
||||||
|
mTextRun->GetDetailedGlyphs(i);
|
||||||
|
|
||||||
if (glyphs[i].IsMissing()) {
|
if (glyphs[i].IsMissing()) {
|
||||||
newGlyph.mIndex = 0;
|
newGlyph.mIndex = 0;
|
||||||
if (rtl) {
|
if (mTextRun->IsRightToLeft()) {
|
||||||
inlinePos = baselineOriginInline - advanceSum -
|
newGlyph.mPosition.x = baselineOrigin.x - advanceSum -
|
||||||
d->mAdvance * devUnitsPerAppUnit;
|
detailedGlyphs[0].mAdvance * devUnitsPerAppUnit;
|
||||||
} else {
|
} else {
|
||||||
inlinePos = baselineOriginInline + advanceSum;
|
newGlyph.mPosition.x = baselineOrigin.x + advanceSum;
|
||||||
}
|
}
|
||||||
blockPos = baselineOriginBlock;
|
newGlyph.mPosition.y = baselineOrigin.y;
|
||||||
advanceSum += d->mAdvance * devUnitsPerAppUnit;
|
advanceSum += detailedGlyphs[0].mAdvance * devUnitsPerAppUnit;
|
||||||
glyphBuf.push_back(newGlyph);
|
glyphBuf.push_back(newGlyph);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t c = 0; c < glyphs[i].GetGlyphCount(); c++, d++) {
|
for (uint32_t c = 0; c < glyphs[i].GetGlyphCount(); c++) {
|
||||||
newGlyph.mIndex = d->mGlyphID;
|
newGlyph.mIndex = detailedGlyphs[c].mGlyphID;
|
||||||
if (rtl) {
|
if (mTextRun->IsRightToLeft()) {
|
||||||
inlinePos = baselineOriginInline - advanceSum -
|
newGlyph.mPosition.x = baselineOrigin.x + detailedGlyphs[c].mXOffset * devUnitsPerAppUnit -
|
||||||
d->mAdvance * devUnitsPerAppUnit;
|
advanceSum - detailedGlyphs[c].mAdvance * devUnitsPerAppUnit;
|
||||||
} else {
|
} else {
|
||||||
inlinePos = baselineOriginInline + advanceSum;
|
newGlyph.mPosition.x = baselineOrigin.x + detailedGlyphs[c].mXOffset * devUnitsPerAppUnit + advanceSum;
|
||||||
}
|
}
|
||||||
inlinePos += d->mXOffset * devUnitsPerAppUnit;
|
newGlyph.mPosition.y = baselineOrigin.y + detailedGlyphs[c].mYOffset * devUnitsPerAppUnit;
|
||||||
blockPos = baselineOriginBlock + d->mYOffset * devUnitsPerAppUnit;
|
|
||||||
glyphBuf.push_back(newGlyph);
|
glyphBuf.push_back(newGlyph);
|
||||||
advanceSum += d->mAdvance * devUnitsPerAppUnit;
|
advanceSum += detailedGlyphs[c].mAdvance * devUnitsPerAppUnit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3352,9 +3302,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||||
// union of bounding boxes of all runs, needed for shadows
|
// union of bounding boxes of all runs, needed for shadows
|
||||||
gfxRect mBoundingBox;
|
gfxRect mBoundingBox;
|
||||||
|
|
||||||
// flags to use when creating textrun, based on CSS style
|
|
||||||
uint32_t mTextRunFlags;
|
|
||||||
|
|
||||||
// true iff the bounding box should be measured
|
// true iff the bounding box should be measured
|
||||||
bool mDoMeasureBoundingBox;
|
bool mDoMeasureBoundingBox;
|
||||||
};
|
};
|
||||||
|
@ -3394,10 +3341,9 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
||||||
// for now, default to ltr if not in doc
|
// for now, default to ltr if not in doc
|
||||||
bool isRTL = false;
|
bool isRTL = false;
|
||||||
|
|
||||||
nsRefPtr<nsStyleContext> canvasStyle;
|
|
||||||
if (mCanvasElement && mCanvasElement->IsInDoc()) {
|
if (mCanvasElement && mCanvasElement->IsInDoc()) {
|
||||||
// try to find the closest context
|
// try to find the closest context
|
||||||
canvasStyle =
|
nsRefPtr<nsStyleContext> canvasStyle =
|
||||||
nsComputedDOMStyle::GetStyleContextForElement(mCanvasElement,
|
nsComputedDOMStyle::GetStyleContextForElement(mCanvasElement,
|
||||||
nullptr,
|
nullptr,
|
||||||
presShell);
|
presShell);
|
||||||
|
@ -3432,14 +3378,6 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
||||||
|
|
||||||
CanvasBidiProcessor processor;
|
CanvasBidiProcessor processor;
|
||||||
|
|
||||||
// If we don't have a style context, we can't set up vertical-text flags
|
|
||||||
// (for now, at least; perhaps we need new Canvas API to control this).
|
|
||||||
processor.mTextRunFlags = canvasStyle ?
|
|
||||||
nsLayoutUtils::GetTextRunFlagsForStyle(canvasStyle,
|
|
||||||
canvasStyle->StyleFont(),
|
|
||||||
canvasStyle->StyleText(),
|
|
||||||
0) : 0;
|
|
||||||
|
|
||||||
GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, nullptr);
|
GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, nullptr);
|
||||||
processor.mPt = gfxPoint(aX, aY);
|
processor.mPt = gfxPoint(aX, aY);
|
||||||
processor.mThebes =
|
processor.mThebes =
|
||||||
|
@ -3506,9 +3444,7 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
||||||
// offset pt.y based on text baseline
|
// offset pt.y based on text baseline
|
||||||
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
||||||
const gfxFont::Metrics& fontMetrics =
|
const gfxFont::Metrics& fontMetrics =
|
||||||
processor.mFontgrp->GetFirstValidFont()->GetMetrics(
|
processor.mFontgrp->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
|
||||||
processor.mTextRun->IsVertical() ? gfxFont::eVertical :
|
|
||||||
gfxFont::eHorizontal);
|
|
||||||
|
|
||||||
gfxFloat anchorY;
|
gfxFloat anchorY;
|
||||||
|
|
||||||
|
|
|
@ -153,16 +153,9 @@ WebGL2Context::TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat
|
||||||
GLsizei h = height;
|
GLsizei h = height;
|
||||||
for (size_t l = 0; l < size_t(levels); l++) {
|
for (size_t l = 0; l < size_t(levels); l++) {
|
||||||
for (size_t f = 0; f < facesCount; f++) {
|
for (size_t f = 0; f < facesCount; f++) {
|
||||||
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(target, f);
|
tex->SetImageInfo(TexImageTargetForTargetAndFace(target, f),
|
||||||
// FIXME: SetImageInfo wants a type, to go with the internalformat that it stores.
|
l, w, h,
|
||||||
// 'type' is deprecated by sized internalformats, which are how TexStorage works.
|
internalformat,
|
||||||
// We must fix WebGLTexture::ImageInfo to store an "effective internalformat",
|
|
||||||
// which in the present case is just the sized internalformat, and drop 'types'
|
|
||||||
// altogether. For now, we just pass LOCAL_GL_UNSIGNED_BYTE, which works For
|
|
||||||
// the most commonly used formats.
|
|
||||||
const GLenum type = LOCAL_GL_UNSIGNED_BYTE;
|
|
||||||
tex->SetImageInfo(imageTarget, l, w, h,
|
|
||||||
internalformat, type,
|
|
||||||
WebGLImageDataStatus::UninitializedImageData);
|
WebGLImageDataStatus::UninitializedImageData);
|
||||||
}
|
}
|
||||||
w = std::max(1, w/2);
|
w = std::max(1, w/2);
|
||||||
|
|
|
@ -1760,6 +1760,13 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
|
||||||
GLenum internalformat, GLenum format, GLenum type,
|
GLenum internalformat, GLenum format, GLenum type,
|
||||||
mozilla::dom::Element& elt)
|
mozilla::dom::Element& elt)
|
||||||
{
|
{
|
||||||
|
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||||
|
type = LOCAL_GL_HALF_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
||||||
|
return false;
|
||||||
|
|
||||||
HTMLVideoElement* video = HTMLVideoElement::FromContentOrNull(&elt);
|
HTMLVideoElement* video = HTMLVideoElement::FromContentOrNull(&elt);
|
||||||
if (!video) {
|
if (!video) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1807,8 +1814,11 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
|
||||||
}
|
}
|
||||||
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget.get(), mPixelStoreFlipY);
|
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget.get(), mPixelStoreFlipY);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height, internalformat, type,
|
TexInternalFormat effectiveinternalformat =
|
||||||
WebGLImageDataStatus::InitializedImageData);
|
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||||
|
MOZ_ASSERT(effectiveinternalformat != LOCAL_GL_NONE);
|
||||||
|
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height,
|
||||||
|
effectiveinternalformat, WebGLImageDataStatus::InitializedImageData);
|
||||||
tex->Bind(TexImageTargetToTexTarget(texImageTarget));
|
tex->Bind(TexImageTargetToTexTarget(texImageTarget));
|
||||||
}
|
}
|
||||||
srcImage = nullptr;
|
srcImage = nullptr;
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace gfx {
|
||||||
class SourceSurface;
|
class SourceSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format, TexType type);
|
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
|
||||||
|
|
||||||
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
|
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
|
||||||
|
|
||||||
|
@ -490,9 +490,6 @@ public:
|
||||||
|
|
||||||
const TexImageTarget texImageTarget(rawTexImgTarget);
|
const TexImageTarget texImageTarget(rawTexImgTarget);
|
||||||
|
|
||||||
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (level < 0)
|
if (level < 0)
|
||||||
return ErrorInvalidValue("texImage2D: level is negative");
|
return ErrorInvalidValue("texImage2D: level is negative");
|
||||||
|
|
||||||
|
@ -560,9 +557,6 @@ public:
|
||||||
|
|
||||||
const TexImageTarget texImageTarget(rawTexImageTarget);
|
const TexImageTarget texImageTarget(rawTexImageTarget);
|
||||||
|
|
||||||
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (level < 0)
|
if (level < 0)
|
||||||
return ErrorInvalidValue("texSubImage2D: level is negative");
|
return ErrorInvalidValue("texSubImage2D: level is negative");
|
||||||
|
|
||||||
|
@ -575,7 +569,7 @@ public:
|
||||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||||
}
|
}
|
||||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
const TexInternalFormat internalformat = imageInfo.InternalFormat();
|
const TexInternalFormat internalformat = imageInfo.EffectiveInternalFormat();
|
||||||
|
|
||||||
// Trying to handle the video by GPU directly first
|
// Trying to handle the video by GPU directly first
|
||||||
if (TexImageFromVideoElement(texImageTarget, level,
|
if (TexImageFromVideoElement(texImageTarget, level,
|
||||||
|
@ -1145,8 +1139,6 @@ protected:
|
||||||
GLsizei width, GLsizei height,
|
GLsizei width, GLsizei height,
|
||||||
uint32_t byteLength, WebGLTexImageFunc func);
|
uint32_t byteLength, WebGLTexImageFunc func);
|
||||||
|
|
||||||
static uint32_t GetBitsPerTexel(TexInternalFormat format, TexType type);
|
|
||||||
|
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
void DestroyResourcesAndContext();
|
void DestroyResourcesAndContext();
|
||||||
|
|
||||||
|
@ -1203,7 +1195,7 @@ protected:
|
||||||
|
|
||||||
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
GLint level,
|
GLint level,
|
||||||
GLenum internalformat,
|
TexInternalFormat internalformat,
|
||||||
GLint xoffset,
|
GLint xoffset,
|
||||||
GLint yoffset,
|
GLint yoffset,
|
||||||
GLint x,
|
GLint x,
|
||||||
|
@ -1363,7 +1355,7 @@ protected:
|
||||||
webgl.mColorWriteMask[3] != false;
|
webgl.mColorWriteMask[3] != false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedMaskWorkaround(WebGLContext& webgl);
|
explicit ScopedMaskWorkaround(WebGLContext& aWebgl);
|
||||||
|
|
||||||
~ScopedMaskWorkaround();
|
~ScopedMaskWorkaround();
|
||||||
};
|
};
|
||||||
|
|
|
@ -676,7 +676,7 @@ WebGLContext::BindFakeBlackTexturesHelper(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
|
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
|
||||||
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().InternalFormat());
|
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().EffectiveInternalFormat());
|
||||||
UniquePtr<FakeBlackTexture>&
|
UniquePtr<FakeBlackTexture>&
|
||||||
blackTexturePtr = alpha
|
blackTexturePtr = alpha
|
||||||
? transparentTextureScopedPtr
|
? transparentTextureScopedPtr
|
||||||
|
|
|
@ -354,7 +354,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
|
||||||
void
|
void
|
||||||
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
GLint level,
|
GLint level,
|
||||||
GLenum internalformat,
|
TexInternalFormat internalformat,
|
||||||
GLint xoffset,
|
GLint xoffset,
|
||||||
GLint yoffset,
|
GLint yoffset,
|
||||||
GLint x,
|
GLint x,
|
||||||
|
@ -372,7 +372,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
|
|
||||||
// TODO: This changes with color_buffer_float. Reassess when the
|
// TODO: This changes with color_buffer_float. Reassess when the
|
||||||
// patch lands.
|
// patch lands.
|
||||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
if (!ValidateTexImage(2, texImageTarget, level, internalformat.get(),
|
||||||
xoffset, yoffset, 0,
|
xoffset, yoffset, 0,
|
||||||
width, height, 0,
|
width, height, 0,
|
||||||
0,
|
0,
|
||||||
|
@ -382,7 +382,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ValidateCopyTexImage(internalformat, func))
|
if (!ValidateCopyTexImage(internalformat.get(), func))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!mBoundFramebuffer)
|
if (!mBoundFramebuffer)
|
||||||
|
@ -401,50 +401,50 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexType framebuffertype = LOCAL_GL_NONE;
|
||||||
|
if (mBoundFramebuffer) {
|
||||||
|
TexInternalFormat framebuffereffectiveformat = mBoundFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
|
||||||
|
framebuffertype = TypeFromInternalFormat(framebuffereffectiveformat);
|
||||||
|
} else {
|
||||||
|
// FIXME - here we're assuming that the default framebuffer is backed by UNSIGNED_BYTE
|
||||||
|
// that might not always be true, say if we had a 16bpp default framebuffer.
|
||||||
|
framebuffertype = LOCAL_GL_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexInternalFormat effectiveinternalformat =
|
||||||
|
EffectiveInternalFormatFromUnsizedInternalFormatAndType(internalformat, framebuffertype);
|
||||||
|
|
||||||
|
// this should never fail, validation happened earlier.
|
||||||
|
MOZ_ASSERT(effectiveinternalformat != LOCAL_GL_NONE);
|
||||||
|
|
||||||
|
// check if the memory size of this texture may change with this call
|
||||||
|
bool sizeMayChange = !sub;
|
||||||
|
if (!sub && tex->HasImageInfoAt(texImageTarget, level)) {
|
||||||
|
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
|
sizeMayChange = width != imageInfo.Width() ||
|
||||||
|
height != imageInfo.Height() ||
|
||||||
|
effectiveinternalformat != imageInfo.EffectiveInternalFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeMayChange)
|
||||||
|
GetAndFlushUnderlyingGLErrors();
|
||||||
|
|
||||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
|
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
|
||||||
if (sub)
|
if (sub)
|
||||||
gl->fCopyTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, x, y, width, height);
|
gl->fCopyTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, x, y, width, height);
|
||||||
else
|
else
|
||||||
gl->fCopyTexImage2D(texImageTarget.get(), level, internalformat, x, y, width, height, 0);
|
gl->fCopyTexImage2D(texImageTarget.get(), level, internalformat.get(), x, y, width, height, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// the rect doesn't fit in the framebuffer
|
// the rect doesn't fit in the framebuffer
|
||||||
|
|
||||||
/*** first, we initialize the texture as black ***/
|
// first, we initialize the texture as black
|
||||||
|
if (!sub) {
|
||||||
// first, compute the size of the buffer we should allocate to initialize the texture as black
|
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||||
|
effectiveinternalformat,
|
||||||
if (!ValidateTexInputData(LOCAL_GL_UNSIGNED_BYTE, -1, func))
|
WebGLImageDataStatus::UninitializedImageData);
|
||||||
return;
|
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||||
|
}
|
||||||
uint32_t texelSize = GetBitsPerTexel(internalformat, LOCAL_GL_UNSIGNED_BYTE) / 8;
|
|
||||||
|
|
||||||
CheckedUint32 checked_neededByteLength =
|
|
||||||
GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
|
|
||||||
|
|
||||||
if (!checked_neededByteLength.isValid())
|
|
||||||
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
|
|
||||||
|
|
||||||
uint32_t bytesNeeded = checked_neededByteLength.value();
|
|
||||||
|
|
||||||
// now that the size is known, create the buffer
|
|
||||||
|
|
||||||
// We need some zero pages, because GL doesn't guarantee the
|
|
||||||
// contents of a texture allocated with nullptr data.
|
|
||||||
// Hopefully calloc will just mmap zero pages here.
|
|
||||||
void* tempZeroData = calloc(1, bytesNeeded);
|
|
||||||
if (!tempZeroData)
|
|
||||||
return ErrorOutOfMemory("%s: could not allocate %d bytes (for zero fill)", info, bytesNeeded);
|
|
||||||
|
|
||||||
// now initialize the texture as black
|
|
||||||
|
|
||||||
if (sub)
|
|
||||||
gl->fTexSubImage2D(texImageTarget.get(), level, 0, 0, width, height,
|
|
||||||
internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
|
||||||
else
|
|
||||||
gl->fTexImage2D(texImageTarget.get(), level, internalformat, width, height,
|
|
||||||
0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
|
||||||
free(tempZeroData);
|
|
||||||
|
|
||||||
// if we are completely outside of the framebuffer, we can exit now with our black texture
|
// if we are completely outside of the framebuffer, we can exit now with our black texture
|
||||||
if ( x >= framebufferWidth
|
if ( x >= framebufferWidth
|
||||||
|
@ -468,6 +468,20 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||||
|
|
||||||
gl->fCopyTexSubImage2D(texImageTarget.get(), level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
|
gl->fCopyTexSubImage2D(texImageTarget.get(), level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sizeMayChange) {
|
||||||
|
GLenum error = GetAndFlushUnderlyingGLErrors();
|
||||||
|
if (error) {
|
||||||
|
GenerateWarning("copyTexImage2D generated error %s", ErrorName(error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sub) {
|
||||||
|
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||||
|
effectiveinternalformat,
|
||||||
|
WebGLImageDataStatus::InitializedImageData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -504,37 +518,7 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
|
||||||
if (!mBoundFramebuffer)
|
if (!mBoundFramebuffer)
|
||||||
ClearBackbufferIfNeeded();
|
ClearBackbufferIfNeeded();
|
||||||
|
|
||||||
const TexImageTarget texImageTarget(rawTexImgTarget);
|
CopyTexSubImage2D_base(rawTexImgTarget, level, internalformat, 0, 0, x, y, width, height, false);
|
||||||
|
|
||||||
// check if the memory size of this texture may change with this call
|
|
||||||
bool sizeMayChange = true;
|
|
||||||
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
|
||||||
if (tex->HasImageInfoAt(texImageTarget, level)) {
|
|
||||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
|
||||||
|
|
||||||
sizeMayChange = width != imageInfo.Width() ||
|
|
||||||
height != imageInfo.Height() ||
|
|
||||||
internalformat != imageInfo.InternalFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sizeMayChange)
|
|
||||||
GetAndFlushUnderlyingGLErrors();
|
|
||||||
|
|
||||||
CopyTexSubImage2D_base(texImageTarget, level, internalformat, 0, 0, x, y, width, height, false);
|
|
||||||
|
|
||||||
if (sizeMayChange) {
|
|
||||||
GLenum error = GetAndFlushUnderlyingGLErrors();
|
|
||||||
if (error) {
|
|
||||||
GenerateWarning("copyTexImage2D generated error %s", ErrorName(error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
|
||||||
internalformat,
|
|
||||||
LOCAL_GL_UNSIGNED_BYTE, /* dummy, artifact of us storing
|
|
||||||
the wrong data in ImageInfo */
|
|
||||||
WebGLImageDataStatus::InitializedImageData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -602,7 +586,11 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
|
||||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CopyTexSubImage2D_base(texImageTarget, level, imageInfo.InternalFormat().get(), xoffset, yoffset, x, y, width, height, true);
|
TexInternalFormat internalformat;
|
||||||
|
TexType type;
|
||||||
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(imageInfo.EffectiveInternalFormat(),
|
||||||
|
&internalformat, &type);
|
||||||
|
return CopyTexSubImage2D_base(texImageTarget, level, internalformat, xoffset, yoffset, x, y, width, height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -922,7 +910,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
|
||||||
if (!tex->IsFirstImagePowerOfTwo())
|
if (!tex->IsFirstImagePowerOfTwo())
|
||||||
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
|
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
|
||||||
|
|
||||||
TexInternalFormat internalformat = tex->ImageInfoAt(imageTarget, 0).InternalFormat();
|
TexInternalFormat internalformat = tex->ImageInfoAt(imageTarget, 0).EffectiveInternalFormat();
|
||||||
if (IsTextureFormatCompressed(internalformat))
|
if (IsTextureFormatCompressed(internalformat))
|
||||||
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
|
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
|
||||||
|
|
||||||
|
@ -1183,12 +1171,17 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
|
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
|
||||||
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
|
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
|
||||||
const TexInternalFormat internalformat =
|
const TexInternalFormat effectiveinternalformat =
|
||||||
fba.Texture()->ImageInfoBase().InternalFormat();
|
fba.Texture()->ImageInfoBase().EffectiveInternalFormat();
|
||||||
return (internalformat == LOCAL_GL_SRGB ||
|
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
|
||||||
internalformat == LOCAL_GL_SRGB_ALPHA) ?
|
TexType type = LOCAL_GL_NONE;
|
||||||
JS::NumberValue(uint32_t(LOCAL_GL_SRGB)) :
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(
|
||||||
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
effectiveinternalformat, &unsizedinternalformat, &type);
|
||||||
|
MOZ_ASSERT(unsizedinternalformat != LOCAL_GL_NONE);
|
||||||
|
const bool srgb = unsizedinternalformat == LOCAL_GL_SRGB ||
|
||||||
|
unsizedinternalformat == LOCAL_GL_SRGB_ALPHA;
|
||||||
|
return srgb ? JS::NumberValue(uint32_t(LOCAL_GL_SRGB))
|
||||||
|
: JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1224,9 +1217,10 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||||
if (!fba.IsComplete())
|
if (!fba.IsComplete())
|
||||||
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
|
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
|
||||||
|
|
||||||
uint32_t ret = LOCAL_GL_NONE;
|
TexInternalFormat effectiveinternalformat =
|
||||||
TexType type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
|
fba.Texture()->ImageInfoAt(fba.ImageTarget(), fba.MipLevel()).EffectiveInternalFormat();
|
||||||
fba.MipLevel()).Type();
|
TexType type = TypeFromInternalFormat(effectiveinternalformat);
|
||||||
|
GLenum ret = LOCAL_GL_NONE;
|
||||||
switch (type.get()) {
|
switch (type.get()) {
|
||||||
case LOCAL_GL_UNSIGNED_BYTE:
|
case LOCAL_GL_UNSIGNED_BYTE:
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||||
|
@ -1235,7 +1229,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||||
ret = LOCAL_GL_UNSIGNED_NORMALIZED;
|
ret = LOCAL_GL_UNSIGNED_NORMALIZED;
|
||||||
break;
|
break;
|
||||||
case LOCAL_GL_FLOAT:
|
case LOCAL_GL_FLOAT:
|
||||||
case LOCAL_GL_HALF_FLOAT_OES:
|
case LOCAL_GL_HALF_FLOAT:
|
||||||
ret = LOCAL_GL_FLOAT;
|
ret = LOCAL_GL_FLOAT;
|
||||||
break;
|
break;
|
||||||
case LOCAL_GL_UNSIGNED_SHORT:
|
case LOCAL_GL_UNSIGNED_SHORT:
|
||||||
|
@ -3353,7 +3347,7 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget,
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalformat, width, height, border, byteLength, view.Data());
|
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalformat, width, height, border, byteLength, view.Data());
|
||||||
|
|
||||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE,
|
tex->SetImageInfo(texImageTarget, level, width, height, internalformat,
|
||||||
WebGLImageDataStatus::InitializedImageData);
|
WebGLImageDataStatus::InitializedImageData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3387,7 +3381,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||||
MOZ_ASSERT(tex);
|
MOZ_ASSERT(tex);
|
||||||
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
|
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
|
|
||||||
if (internalformat != levelInfo.InternalFormat()) {
|
if (internalformat != levelInfo.EffectiveInternalFormat()) {
|
||||||
return ErrorInvalidOperation("compressedTexImage2D: internalformat does not match the existing image");
|
return ErrorInvalidOperation("compressedTexImage2D: internalformat does not match the existing image");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3599,7 +3593,7 @@ WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
|
||||||
|
|
||||||
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||||
GLint level,
|
GLint level,
|
||||||
TexInternalFormat internalFormat,
|
TexInternalFormat internalformat,
|
||||||
GLsizei width,
|
GLsizei width,
|
||||||
GLsizei height,
|
GLsizei height,
|
||||||
GLint border,
|
GLint border,
|
||||||
|
@ -3610,20 +3604,26 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||||
MOZ_ASSERT(tex != nullptr, "no texture bound");
|
MOZ_ASSERT(tex != nullptr, "no texture bound");
|
||||||
|
|
||||||
|
TexInternalFormat effectiveInternalFormat =
|
||||||
|
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||||
bool sizeMayChange = true;
|
bool sizeMayChange = true;
|
||||||
|
|
||||||
if (tex->HasImageInfoAt(texImageTarget, level)) {
|
if (tex->HasImageInfoAt(texImageTarget, level)) {
|
||||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
sizeMayChange = width != imageInfo.Width() ||
|
sizeMayChange = width != imageInfo.Width() ||
|
||||||
height != imageInfo.Height() ||
|
height != imageInfo.Height() ||
|
||||||
internalFormat != imageInfo.InternalFormat();
|
effectiveInternalFormat != imageInfo.EffectiveInternalFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to format and type required by OpenGL 'driver'.
|
// Convert to format and type required by OpenGL 'driver'.
|
||||||
GLenum driverType = DriverTypeFromType(gl, type);
|
GLenum driverType = LOCAL_GL_NONE;
|
||||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||||
GLenum driverFormat = LOCAL_GL_NONE;
|
GLenum driverFormat = LOCAL_GL_NONE;
|
||||||
DriverFormatsFromFormatAndType(gl, internalFormat, type, &driverInternalFormat, &driverFormat);
|
DriverFormatsFromEffectiveInternalFormat(gl,
|
||||||
|
effectiveInternalFormat,
|
||||||
|
&driverInternalFormat,
|
||||||
|
&driverFormat,
|
||||||
|
&driverType);
|
||||||
|
|
||||||
if (sizeMayChange) {
|
if (sizeMayChange) {
|
||||||
GetAndFlushUnderlyingGLErrors();
|
GetAndFlushUnderlyingGLErrors();
|
||||||
|
@ -3652,6 +3652,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
{
|
{
|
||||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
|
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
|
||||||
|
|
||||||
|
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||||
|
type = LOCAL_GL_HALF_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
width, height, 0,
|
width, height, 0,
|
||||||
|
@ -3674,7 +3678,14 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
TexInternalFormat effectiveinternalformat =
|
||||||
|
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||||
|
|
||||||
|
if (effectiveinternalformat == LOCAL_GL_NONE) {
|
||||||
|
return ErrorInvalidOperation("texImage2D: bad combination of internalformat and type");
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(effectiveinternalformat);
|
||||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||||
|
|
||||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||||
|
@ -3712,8 +3723,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::UninitializedImageData;
|
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::UninitializedImageData;
|
||||||
|
|
||||||
if (byteLength) {
|
if (byteLength) {
|
||||||
|
size_t bitspertexel = GetBitsPerTexel(effectiveinternalformat);
|
||||||
|
MOZ_ASSERT((bitspertexel % 8) == 0); // should not have compressed formats here.
|
||||||
|
size_t dstTexelSize = bitspertexel / 8;
|
||||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
|
||||||
size_t dstPlainRowSize = dstTexelSize * width;
|
size_t dstPlainRowSize = dstTexelSize * width;
|
||||||
size_t unpackAlignment = mPixelStoreUnpackAlignment;
|
size_t unpackAlignment = mPixelStoreUnpackAlignment;
|
||||||
size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
|
size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
|
||||||
|
@ -3752,7 +3765,8 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
// have NoImageData at this point.
|
// have NoImageData at this point.
|
||||||
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
|
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
|
||||||
|
|
||||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, type, imageInfoStatusIfSuccess);
|
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||||
|
effectiveinternalformat, imageInfoStatusIfSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3830,14 +3844,28 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
{
|
{
|
||||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
|
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
|
||||||
|
|
||||||
|
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||||
|
type = LOCAL_GL_HALF_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||||
if (!tex) {
|
if (!tex) {
|
||||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||||
}
|
}
|
||||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
|
||||||
const TexInternalFormat internalformat = imageInfo.InternalFormat();
|
|
||||||
|
|
||||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat.get(),
|
if (!tex->HasImageInfoAt(texImageTarget, level)) {
|
||||||
|
return ErrorInvalidOperation("texSubImage2D: no previously defined texture image");
|
||||||
|
}
|
||||||
|
|
||||||
|
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
|
const TexInternalFormat existingEffectiveInternalFormat = imageInfo.EffectiveInternalFormat();
|
||||||
|
TexInternalFormat existingUnsizedInternalFormat = LOCAL_GL_NONE;
|
||||||
|
TexType existingType = LOCAL_GL_NONE;
|
||||||
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(existingEffectiveInternalFormat,
|
||||||
|
&existingUnsizedInternalFormat,
|
||||||
|
&existingType);
|
||||||
|
|
||||||
|
if (!ValidateTexImage(2, texImageTarget, level, existingUnsizedInternalFormat.get(),
|
||||||
xoffset, yoffset, 0,
|
xoffset, yoffset, 0,
|
||||||
width, height, 0,
|
width, height, 0,
|
||||||
0, format, type, func))
|
0, format, type, func))
|
||||||
|
@ -3848,11 +3876,11 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (imageInfo.Type() != type) {
|
if (type != existingType) {
|
||||||
return ErrorInvalidOperation("texSubImage2D: type parameter does not match the existing image");
|
return ErrorInvalidOperation("texSubImage2D: type differs from that of the existing image");
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(existingEffectiveInternalFormat);
|
||||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||||
|
|
||||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||||
|
@ -3882,7 +3910,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
uint32_t dstTexelSize = GetBitsPerTexel(existingEffectiveInternalFormat) / 8;
|
||||||
size_t dstPlainRowSize = dstTexelSize * width;
|
size_t dstPlainRowSize = dstTexelSize * width;
|
||||||
// There are checks above to ensure that this won't overflow.
|
// There are checks above to ensure that this won't overflow.
|
||||||
size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
|
size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
|
||||||
|
@ -3906,10 +3934,14 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||||
pixels = reinterpret_cast<void*>(convertedData.get());
|
pixels = reinterpret_cast<void*>(convertedData.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum driverType = DriverTypeFromType(gl, type);
|
GLenum driverType = LOCAL_GL_NONE;
|
||||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||||
GLenum driverFormat = LOCAL_GL_NONE;
|
GLenum driverFormat = LOCAL_GL_NONE;
|
||||||
DriverFormatsFromFormatAndType(gl, internalformat, type, &driverInternalFormat, &driverFormat);
|
DriverFormatsFromEffectiveInternalFormat(gl,
|
||||||
|
existingEffectiveInternalFormat,
|
||||||
|
&driverInternalFormat,
|
||||||
|
&driverFormat,
|
||||||
|
&driverType);
|
||||||
|
|
||||||
gl->fTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
|
gl->fTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
|
||||||
}
|
}
|
||||||
|
@ -4066,119 +4098,37 @@ BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WebGLTexelFormat mozilla::GetWebGLTexelFormat(TexInternalFormat internalformat, TexType type)
|
WebGLTexelFormat
|
||||||
|
mozilla::GetWebGLTexelFormat(TexInternalFormat effectiveinternalformat)
|
||||||
{
|
{
|
||||||
//
|
switch (effectiveinternalformat.get()) {
|
||||||
// WEBGL_depth_texture
|
case LOCAL_GL_DEPTH_COMPONENT16: return WebGLTexelFormat::D16;
|
||||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT) {
|
case LOCAL_GL_DEPTH_COMPONENT24: return WebGLTexelFormat::D32;
|
||||||
switch (type.get()) {
|
case LOCAL_GL_DEPTH24_STENCIL8: return WebGLTexelFormat::D24S8;
|
||||||
case LOCAL_GL_UNSIGNED_SHORT:
|
case LOCAL_GL_RGBA8: return WebGLTexelFormat::RGBA8;
|
||||||
return WebGLTexelFormat::D16;
|
case LOCAL_GL_SRGB8_ALPHA8: return WebGLTexelFormat::RGBA8;
|
||||||
case LOCAL_GL_UNSIGNED_INT:
|
case LOCAL_GL_RGB8: return WebGLTexelFormat::RGB8;
|
||||||
return WebGLTexelFormat::D32;
|
case LOCAL_GL_SRGB8: return WebGLTexelFormat::RGB8;
|
||||||
}
|
case LOCAL_GL_ALPHA8: return WebGLTexelFormat::A8;
|
||||||
|
case LOCAL_GL_LUMINANCE8: return WebGLTexelFormat::R8;
|
||||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
case LOCAL_GL_LUMINANCE8_ALPHA8: return WebGLTexelFormat::RA8;
|
||||||
}
|
case LOCAL_GL_RGBA32F: return WebGLTexelFormat::RGBA32F;
|
||||||
|
case LOCAL_GL_RGB32F: return WebGLTexelFormat::RGB32F;
|
||||||
if (internalformat == LOCAL_GL_DEPTH_STENCIL) {
|
case LOCAL_GL_ALPHA32F_EXT: return WebGLTexelFormat::A32F;
|
||||||
switch (type.get()) {
|
case LOCAL_GL_LUMINANCE32F_EXT: return WebGLTexelFormat::R32F;
|
||||||
case LOCAL_GL_UNSIGNED_INT_24_8_EXT:
|
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT: return WebGLTexelFormat::RA32F;
|
||||||
return WebGLTexelFormat::D24S8;
|
case LOCAL_GL_RGBA16F: return WebGLTexelFormat::RGBA16F;
|
||||||
}
|
case LOCAL_GL_RGB16F: return WebGLTexelFormat::RGB16F;
|
||||||
|
case LOCAL_GL_ALPHA16F_EXT: return WebGLTexelFormat::A16F;
|
||||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
case LOCAL_GL_LUMINANCE16F_EXT: return WebGLTexelFormat::R16F;
|
||||||
}
|
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT: return WebGLTexelFormat::RA16F;
|
||||||
|
case LOCAL_GL_RGBA4: return WebGLTexelFormat::RGBA4444;
|
||||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT16) {
|
case LOCAL_GL_RGB5_A1: return WebGLTexelFormat::RGBA5551;
|
||||||
return WebGLTexelFormat::D16;
|
case LOCAL_GL_RGB565: return WebGLTexelFormat::RGB565;
|
||||||
}
|
|
||||||
|
|
||||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT32) {
|
|
||||||
return WebGLTexelFormat::D32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (internalformat == LOCAL_GL_DEPTH24_STENCIL8) {
|
|
||||||
return WebGLTexelFormat::D24S8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
|
||||||
switch (internalformat.get()) {
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
|
||||||
return WebGLTexelFormat::RGBA8;
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
case LOCAL_GL_SRGB_EXT:
|
|
||||||
return WebGLTexelFormat::RGB8;
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
return WebGLTexelFormat::A8;
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
return WebGLTexelFormat::R8;
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
return WebGLTexelFormat::RA8;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == LOCAL_GL_FLOAT) {
|
|
||||||
// OES_texture_float
|
|
||||||
switch (internalformat.get()) {
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
case LOCAL_GL_RGBA32F:
|
|
||||||
return WebGLTexelFormat::RGBA32F;
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
case LOCAL_GL_RGB32F:
|
|
||||||
return WebGLTexelFormat::RGB32F;
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
case LOCAL_GL_ALPHA32F_ARB:
|
|
||||||
return WebGLTexelFormat::A32F;
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
case LOCAL_GL_LUMINANCE32F_ARB:
|
|
||||||
return WebGLTexelFormat::R32F;
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA32F_ARB:
|
|
||||||
return WebGLTexelFormat::RA32F;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
|
||||||
} else if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
|
||||||
// OES_texture_half_float
|
|
||||||
switch (internalformat.get()) {
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
case LOCAL_GL_RGBA16F:
|
|
||||||
return WebGLTexelFormat::RGBA16F;
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
case LOCAL_GL_RGB16F:
|
|
||||||
return WebGLTexelFormat::RGB16F;
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
case LOCAL_GL_ALPHA16F_ARB:
|
|
||||||
return WebGLTexelFormat::A16F;
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
case LOCAL_GL_LUMINANCE16F_ARB:
|
|
||||||
return WebGLTexelFormat::R16F;
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA16F_ARB:
|
|
||||||
return WebGLTexelFormat::RA16F;
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT(false, "Coding mistake?! Should never reach this point.");
|
|
||||||
return WebGLTexelFormat::BadFormat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type.get()) {
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
|
||||||
return WebGLTexelFormat::RGBA4444;
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
|
||||||
return WebGLTexelFormat::RGBA5551;
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
|
||||||
return WebGLTexelFormat::RGB565;
|
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "Coding mistake?! Should never reach this point.");
|
MOZ_CRASH("Unhandled format");
|
||||||
return WebGLTexelFormat::BadFormat;
|
return WebGLTexelFormat::BadFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -31,29 +31,28 @@ namespace mozilla {
|
||||||
using namespace gl;
|
using namespace gl;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IsGLDepthFormat(TexInternalFormat webGLFormat)
|
IsGLDepthFormat(TexInternalFormat internalformat)
|
||||||
{
|
{
|
||||||
return (webGLFormat == LOCAL_GL_DEPTH_COMPONENT ||
|
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
|
return unsizedformat == LOCAL_GL_DEPTH_COMPONENT;
|
||||||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IsGLDepthStencilFormat(TexInternalFormat webGLFormat)
|
IsGLDepthStencilFormat(TexInternalFormat internalformat)
|
||||||
{
|
{
|
||||||
return (webGLFormat == LOCAL_GL_DEPTH_STENCIL ||
|
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||||
webGLFormat == LOCAL_GL_DEPTH24_STENCIL8);
|
return unsizedformat == LOCAL_GL_DEPTH_STENCIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FormatHasAlpha(TexInternalFormat webGLFormat)
|
FormatHasAlpha(TexInternalFormat internalformat)
|
||||||
{
|
{
|
||||||
return webGLFormat == LOCAL_GL_RGBA ||
|
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||||
webGLFormat == LOCAL_GL_LUMINANCE_ALPHA ||
|
return unsizedformat == LOCAL_GL_RGBA ||
|
||||||
webGLFormat == LOCAL_GL_ALPHA ||
|
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||||
webGLFormat == LOCAL_GL_RGBA4 ||
|
unsizedformat == LOCAL_GL_ALPHA ||
|
||||||
webGLFormat == LOCAL_GL_RGB5_A1 ||
|
unsizedformat == LOCAL_GL_SRGB_ALPHA ||
|
||||||
webGLFormat == LOCAL_GL_SRGB_ALPHA;
|
unsizedformat == LOCAL_GL_RGBA_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
TexTarget
|
TexTarget
|
||||||
|
@ -76,11 +75,12 @@ TexImageTargetToTexTarget(TexImageTarget texImageTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLComponents::GLComponents(TexInternalFormat format)
|
GLComponents::GLComponents(TexInternalFormat internalformat)
|
||||||
{
|
{
|
||||||
|
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||||
mComponents = 0;
|
mComponents = 0;
|
||||||
|
|
||||||
switch (format.get()) {
|
switch (unsizedformat.get()) {
|
||||||
case LOCAL_GL_RGBA:
|
case LOCAL_GL_RGBA:
|
||||||
case LOCAL_GL_RGBA4:
|
case LOCAL_GL_RGBA4:
|
||||||
case LOCAL_GL_RGBA8:
|
case LOCAL_GL_RGBA8:
|
||||||
|
@ -117,152 +117,277 @@ GLComponents::IsSubsetOf(const GLComponents& other) const
|
||||||
return (mComponents | other.mComponents) == other.mComponents;
|
return (mComponents | other.mComponents) == other.mComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexType
|
||||||
|
TypeFromInternalFormat(TexInternalFormat internalformat)
|
||||||
|
{
|
||||||
|
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||||
|
if (internalformat == table_effectiveinternalformat) { \
|
||||||
|
return table_type; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "WebGLInternalFormatsTable.h"
|
||||||
|
|
||||||
|
// if we're here, then internalformat is not an effective internalformat i.e. is an unsized internalformat.
|
||||||
|
return LOCAL_GL_NONE; // no size, no type
|
||||||
|
}
|
||||||
|
|
||||||
|
TexInternalFormat
|
||||||
|
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat)
|
||||||
|
{
|
||||||
|
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||||
|
if (internalformat == table_effectiveinternalformat) { \
|
||||||
|
return table_internalformat; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "WebGLInternalFormatsTable.h"
|
||||||
|
|
||||||
|
// if we're here, then internalformat is not an effective internalformat i.e. is an unsized internalformat.
|
||||||
|
// so we can just return it.
|
||||||
|
return internalformat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that the following two functions are inverse of each other:
|
||||||
|
* EffectiveInternalFormatFromInternalFormatAndType and
|
||||||
|
* InternalFormatAndTypeFromEffectiveInternalFormat both implement OpenGL ES 3.0.3 Table 3.2
|
||||||
|
* but in opposite directions.
|
||||||
|
*/
|
||||||
|
TexInternalFormat
|
||||||
|
EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat internalformat,
|
||||||
|
TexType type)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(TypeFromInternalFormat(internalformat) == LOCAL_GL_NONE);
|
||||||
|
|
||||||
|
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||||
|
if (internalformat == table_internalformat && type == table_type) { \
|
||||||
|
return table_effectiveinternalformat; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "WebGLInternalFormatsTable.h"
|
||||||
|
|
||||||
|
// If we're here, that means that type was incompatible with the given internalformat.
|
||||||
|
return LOCAL_GL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
|
||||||
|
TexInternalFormat* out_internalformat,
|
||||||
|
TexType* out_type)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(TypeFromInternalFormat(effectiveinternalformat) != LOCAL_GL_NONE);
|
||||||
|
|
||||||
|
MOZ_ASSERT(out_internalformat);
|
||||||
|
MOZ_ASSERT(out_type);
|
||||||
|
|
||||||
|
GLenum internalformat = LOCAL_GL_NONE;
|
||||||
|
GLenum type = LOCAL_GL_NONE;
|
||||||
|
|
||||||
|
switch (effectiveinternalformat.get()) {
|
||||||
|
|
||||||
|
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||||
|
case table_effectiveinternalformat: \
|
||||||
|
internalformat = table_internalformat; \
|
||||||
|
type = table_type; \
|
||||||
|
break;
|
||||||
|
|
||||||
|
#include "WebGLInternalFormatsTable.h"
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH(); // impossible to get here
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_internalformat = internalformat;
|
||||||
|
*out_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexInternalFormat
|
||||||
|
EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalformat,
|
||||||
|
TexType type)
|
||||||
|
{
|
||||||
|
TexType typeOfInternalFormat = TypeFromInternalFormat(internalformat);
|
||||||
|
if (typeOfInternalFormat == LOCAL_GL_NONE) {
|
||||||
|
return EffectiveInternalFormatFromUnsizedInternalFormatAndType(internalformat, type);
|
||||||
|
} else if (typeOfInternalFormat == type) {
|
||||||
|
return internalformat;
|
||||||
|
} else {
|
||||||
|
return LOCAL_GL_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert WebGL/ES format and type into GL internal
|
* Convert effective internalformat into GL function parameters
|
||||||
* format valid for underlying driver.
|
* valid for underlying driver.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
DriverFormatsFromFormatAndType(GLContext* gl, TexInternalFormat webGLInternalFormat, TexType webGLType,
|
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
||||||
GLenum* out_driverInternalFormat, GLenum* out_driverFormat)
|
TexInternalFormat effectiveinternalformat,
|
||||||
|
GLenum* out_driverInternalFormat,
|
||||||
|
GLenum* out_driverFormat,
|
||||||
|
GLenum* out_driverType)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(out_driverInternalFormat);
|
MOZ_ASSERT(out_driverInternalFormat);
|
||||||
MOZ_ASSERT(out_driverFormat);
|
MOZ_ASSERT(out_driverFormat);
|
||||||
|
MOZ_ASSERT(out_driverType);
|
||||||
|
|
||||||
// ES2 requires that format == internalformat; floating-point is
|
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
|
||||||
// indicated purely by the type that's loaded. For desktop GL, we
|
TexType type = LOCAL_GL_NONE;
|
||||||
// have to specify a floating point internal format.
|
|
||||||
if (gl->IsGLES()) {
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(effectiveinternalformat,
|
||||||
*out_driverFormat = *out_driverInternalFormat = webGLInternalFormat.get();
|
&unsizedinternalformat, &type);
|
||||||
return;
|
|
||||||
|
// driverType: almost always the generic type that we just got, except on ES
|
||||||
|
// we must replace HALF_FLOAT by HALF_FLOAT_OES
|
||||||
|
GLenum driverType = type.get();
|
||||||
|
if (gl->IsGLES() && type == LOCAL_GL_HALF_FLOAT) {
|
||||||
|
driverType = LOCAL_GL_HALF_FLOAT_OES;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum internalFormat = LOCAL_GL_NONE;
|
// driverFormat: always just the unsized internalformat that we just got
|
||||||
GLenum format = LOCAL_GL_NONE;
|
GLenum driverFormat = unsizedinternalformat.get();
|
||||||
|
|
||||||
if (webGLInternalFormat == LOCAL_GL_DEPTH_COMPONENT) {
|
// driverInternalFormat: almost always the same as driverFormat, but on desktop GL,
|
||||||
format = LOCAL_GL_DEPTH_COMPONENT;
|
// in some cases we must pass a different value. On ES, they are equal by definition
|
||||||
if (webGLType == LOCAL_GL_UNSIGNED_SHORT)
|
// as it is an error to pass internalformat!=format.
|
||||||
internalFormat = LOCAL_GL_DEPTH_COMPONENT16;
|
GLenum driverInternalFormat = driverFormat;
|
||||||
else if (webGLType == LOCAL_GL_UNSIGNED_INT)
|
if (!gl->IsGLES()) {
|
||||||
internalFormat = LOCAL_GL_DEPTH_COMPONENT32;
|
// Cases where desktop OpenGL requires a tweak to 'format'
|
||||||
} else if (webGLInternalFormat == LOCAL_GL_DEPTH_STENCIL) {
|
if (driverFormat == LOCAL_GL_SRGB) {
|
||||||
format = LOCAL_GL_DEPTH_STENCIL;
|
driverFormat = LOCAL_GL_RGB;
|
||||||
if (webGLType == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
|
} else if (driverFormat == LOCAL_GL_SRGB_ALPHA) {
|
||||||
internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
|
driverFormat = LOCAL_GL_RGBA;
|
||||||
} else {
|
|
||||||
switch (webGLType.get()) {
|
|
||||||
case LOCAL_GL_UNSIGNED_BYTE:
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
|
||||||
format = internalFormat = webGLInternalFormat.get();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_FLOAT:
|
|
||||||
switch (webGLInternalFormat.get()) {
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
format = LOCAL_GL_RGBA;
|
|
||||||
internalFormat = LOCAL_GL_RGBA32F;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
format = LOCAL_GL_RGB;
|
|
||||||
internalFormat = LOCAL_GL_RGB32F;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
format = LOCAL_GL_ALPHA;
|
|
||||||
internalFormat = LOCAL_GL_ALPHA32F_ARB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
format = LOCAL_GL_LUMINANCE;
|
|
||||||
internalFormat = LOCAL_GL_LUMINANCE32F_ARB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
format = LOCAL_GL_LUMINANCE_ALPHA;
|
|
||||||
internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_HALF_FLOAT_OES:
|
|
||||||
switch (webGLInternalFormat.get()) {
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
format = LOCAL_GL_RGBA;
|
|
||||||
internalFormat = LOCAL_GL_RGBA16F;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
format = LOCAL_GL_RGB;
|
|
||||||
internalFormat = LOCAL_GL_RGB16F;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
format = LOCAL_GL_ALPHA;
|
|
||||||
internalFormat = LOCAL_GL_ALPHA16F_ARB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
format = LOCAL_GL_LUMINANCE;
|
|
||||||
internalFormat = LOCAL_GL_LUMINANCE16F_ARB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
format = LOCAL_GL_LUMINANCE_ALPHA;
|
|
||||||
internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
|
// Cases where desktop OpenGL requires a sized internalformat,
|
||||||
// requires that format == internalformat, but GL will fail in this case.
|
// as opposed to the unsized internalformat that had the same
|
||||||
// GL requires:
|
// GLenum value as 'format', in order to get the precise
|
||||||
// format -> internalformat
|
// semantics that we want. For example, for floating-point formats,
|
||||||
// GL_RGB GL_SRGB_EXT
|
// we seem to need a sized internalformat to get non-clamped floating
|
||||||
// GL_RGBA GL_SRGB_ALPHA_EXT
|
// point texture sampling. Can't find the spec reference for that,
|
||||||
switch (webGLInternalFormat.get()) {
|
// but that's at least the case on my NVIDIA driver version 331.
|
||||||
case LOCAL_GL_SRGB:
|
if (unsizedinternalformat == LOCAL_GL_DEPTH_COMPONENT ||
|
||||||
format = LOCAL_GL_RGB;
|
unsizedinternalformat == LOCAL_GL_DEPTH_STENCIL ||
|
||||||
internalFormat = LOCAL_GL_SRGB;
|
type == LOCAL_GL_FLOAT ||
|
||||||
break;
|
type == LOCAL_GL_HALF_FLOAT)
|
||||||
case LOCAL_GL_SRGB_ALPHA:
|
{
|
||||||
format = LOCAL_GL_RGBA;
|
driverInternalFormat = effectiveinternalformat.get();
|
||||||
internalFormat = LOCAL_GL_SRGB_ALPHA;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(webGLInternalFormat != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
|
*out_driverInternalFormat = driverInternalFormat;
|
||||||
"Coding mistake -- bad format/type passed?");
|
*out_driverFormat = driverFormat;
|
||||||
|
*out_driverType = driverType;
|
||||||
*out_driverInternalFormat = internalFormat;
|
|
||||||
*out_driverFormat = format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum
|
/**
|
||||||
DriverTypeFromType(GLContext* gl, TexType webGLType)
|
* Return the bits per texel for format & type combination.
|
||||||
|
* Assumes that format & type are a valid combination as checked with
|
||||||
|
* ValidateTexImageFormatAndType().
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
GetBitsPerTexel(TexInternalFormat effectiveinternalformat)
|
||||||
{
|
{
|
||||||
GLenum type = webGLType.get();
|
switch (effectiveinternalformat.get()) {
|
||||||
|
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
||||||
|
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
||||||
|
return 2;
|
||||||
|
|
||||||
if (gl->IsGLES())
|
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||||
return type;
|
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
|
case LOCAL_GL_ATC_RGB:
|
||||||
|
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
||||||
|
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
||||||
|
case LOCAL_GL_ETC1_RGB8_OES:
|
||||||
|
return 4;
|
||||||
|
|
||||||
// convert type for half float if not on GLES2
|
case LOCAL_GL_ALPHA8:
|
||||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
case LOCAL_GL_LUMINANCE8:
|
||||||
if (gl->IsSupported(gl::GLFeature::texture_half_float)) {
|
case LOCAL_GL_R8:
|
||||||
return LOCAL_GL_HALF_FLOAT;
|
case LOCAL_GL_R8I:
|
||||||
} else {
|
case LOCAL_GL_R8UI:
|
||||||
MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float));
|
case LOCAL_GL_R8_SNORM:
|
||||||
}
|
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||||
|
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
|
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
||||||
|
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
case LOCAL_GL_LUMINANCE8_ALPHA8:
|
||||||
|
case LOCAL_GL_RGBA4:
|
||||||
|
case LOCAL_GL_RGB5_A1:
|
||||||
|
case LOCAL_GL_DEPTH_COMPONENT16:
|
||||||
|
case LOCAL_GL_RG8:
|
||||||
|
case LOCAL_GL_R16I:
|
||||||
|
case LOCAL_GL_R16UI:
|
||||||
|
case LOCAL_GL_RGB565:
|
||||||
|
case LOCAL_GL_R16F:
|
||||||
|
case LOCAL_GL_RG8I:
|
||||||
|
case LOCAL_GL_RG8UI:
|
||||||
|
case LOCAL_GL_RG8_SNORM:
|
||||||
|
case LOCAL_GL_ALPHA16F_EXT:
|
||||||
|
case LOCAL_GL_LUMINANCE16F_EXT:
|
||||||
|
return 16;
|
||||||
|
|
||||||
|
case LOCAL_GL_RGB8:
|
||||||
|
case LOCAL_GL_DEPTH_COMPONENT24:
|
||||||
|
case LOCAL_GL_SRGB8:
|
||||||
|
case LOCAL_GL_RGB8UI:
|
||||||
|
case LOCAL_GL_RGB8I:
|
||||||
|
case LOCAL_GL_RGB8_SNORM:
|
||||||
|
return 24;
|
||||||
|
|
||||||
|
case LOCAL_GL_RGBA8:
|
||||||
|
case LOCAL_GL_RGB10_A2:
|
||||||
|
case LOCAL_GL_R32F:
|
||||||
|
case LOCAL_GL_RG16F:
|
||||||
|
case LOCAL_GL_R32I:
|
||||||
|
case LOCAL_GL_R32UI:
|
||||||
|
case LOCAL_GL_RG16I:
|
||||||
|
case LOCAL_GL_RG16UI:
|
||||||
|
case LOCAL_GL_DEPTH24_STENCIL8:
|
||||||
|
case LOCAL_GL_R11F_G11F_B10F:
|
||||||
|
case LOCAL_GL_RGB9_E5:
|
||||||
|
case LOCAL_GL_SRGB8_ALPHA8:
|
||||||
|
case LOCAL_GL_DEPTH_COMPONENT32F:
|
||||||
|
case LOCAL_GL_RGBA8UI:
|
||||||
|
case LOCAL_GL_RGBA8I:
|
||||||
|
case LOCAL_GL_RGBA8_SNORM:
|
||||||
|
case LOCAL_GL_RGB10_A2UI:
|
||||||
|
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT:
|
||||||
|
case LOCAL_GL_ALPHA32F_EXT:
|
||||||
|
case LOCAL_GL_LUMINANCE32F_EXT:
|
||||||
|
return 32;
|
||||||
|
|
||||||
|
case LOCAL_GL_DEPTH32F_STENCIL8:
|
||||||
|
return 40;
|
||||||
|
|
||||||
|
case LOCAL_GL_RGB16F:
|
||||||
|
case LOCAL_GL_RGB16UI:
|
||||||
|
case LOCAL_GL_RGB16I:
|
||||||
|
return 48;
|
||||||
|
|
||||||
|
case LOCAL_GL_RG32F:
|
||||||
|
case LOCAL_GL_RG32I:
|
||||||
|
case LOCAL_GL_RG32UI:
|
||||||
|
case LOCAL_GL_RGBA16F:
|
||||||
|
case LOCAL_GL_RGBA16UI:
|
||||||
|
case LOCAL_GL_RGBA16I:
|
||||||
|
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT:
|
||||||
|
return 64;
|
||||||
|
|
||||||
|
case LOCAL_GL_RGB32F:
|
||||||
|
case LOCAL_GL_RGB32UI:
|
||||||
|
case LOCAL_GL_RGB32I:
|
||||||
|
return 96;
|
||||||
|
|
||||||
|
case LOCAL_GL_RGBA32F:
|
||||||
|
case LOCAL_GL_RGBA32UI:
|
||||||
|
case LOCAL_GL_RGBA32I:
|
||||||
|
return 128;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT(false, "Unhandled format");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -16,9 +16,28 @@ namespace mozilla {
|
||||||
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
|
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
|
||||||
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
|
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
|
||||||
bool FormatHasAlpha(TexInternalFormat webGLFormat);
|
bool FormatHasAlpha(TexInternalFormat webGLFormat);
|
||||||
void DriverFormatsFromFormatAndType(gl::GLContext* gl, TexInternalFormat webGLFormat, TexType webGLType,
|
void
|
||||||
GLenum* out_driverInternalFormat, GLenum* out_driverFormat);
|
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
||||||
GLenum DriverTypeFromType(gl::GLContext* gl, TexType webGLType);
|
TexInternalFormat internalformat,
|
||||||
|
GLenum* out_driverInternalFormat,
|
||||||
|
GLenum* out_driverFormat,
|
||||||
|
GLenum* out_driverType);
|
||||||
|
TexInternalFormat
|
||||||
|
EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalformat,
|
||||||
|
TexType type);
|
||||||
|
TexInternalFormat
|
||||||
|
EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat internalformat,
|
||||||
|
TexType type);
|
||||||
|
void
|
||||||
|
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
|
||||||
|
TexInternalFormat* out_internalformat,
|
||||||
|
TexType* out_type);
|
||||||
|
TexType
|
||||||
|
TypeFromInternalFormat(TexInternalFormat internalformat);
|
||||||
|
TexInternalFormat
|
||||||
|
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat);
|
||||||
|
size_t
|
||||||
|
GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
|
||||||
|
|
||||||
// For use with the different texture calls, i.e.
|
// For use with the different texture calls, i.e.
|
||||||
// TexImage2D, CopyTex[Sub]Image2D, ...
|
// TexImage2D, CopyTex[Sub]Image2D, ...
|
||||||
|
|
|
@ -673,7 +673,7 @@ WebGLContext::ValidateTexImageType(GLenum type,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OES_texture_half_float add types */
|
/* OES_texture_half_float add types */
|
||||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
if (type == LOCAL_GL_HALF_FLOAT) {
|
||||||
bool validType = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float);
|
bool validType = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float);
|
||||||
if (!validType)
|
if (!validType)
|
||||||
ErrorInvalidEnum("%s: invalid type %s: need OES_texture_half_float enabled",
|
ErrorInvalidEnum("%s: invalid type %s: need OES_texture_half_float enabled",
|
||||||
|
@ -1025,95 +1025,6 @@ WebGLContext::ValidateTexSubImageSize(GLint xoffset, GLint yoffset, GLint /*zoff
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the bits per texel for format & type combination.
|
|
||||||
* Assumes that format & type are a valid combination as checked with
|
|
||||||
* ValidateTexImageFormatAndType().
|
|
||||||
*/
|
|
||||||
uint32_t
|
|
||||||
WebGLContext::GetBitsPerTexel(TexInternalFormat format, TexType type)
|
|
||||||
{
|
|
||||||
/* Known fixed-sized types */
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
|
||||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
|
||||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
|
|
||||||
{
|
|
||||||
return 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == LOCAL_GL_UNSIGNED_INT_24_8)
|
|
||||||
return 32;
|
|
||||||
|
|
||||||
int bitsPerComponent = 0;
|
|
||||||
switch (type.get()) {
|
|
||||||
case LOCAL_GL_UNSIGNED_BYTE:
|
|
||||||
bitsPerComponent = 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_HALF_FLOAT:
|
|
||||||
case LOCAL_GL_HALF_FLOAT_OES:
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT:
|
|
||||||
bitsPerComponent = 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOCAL_GL_FLOAT:
|
|
||||||
case LOCAL_GL_UNSIGNED_INT:
|
|
||||||
bitsPerComponent = 32;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT(false, "Unhandled type.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (format.get()) {
|
|
||||||
// Uncompressed formats
|
|
||||||
case LOCAL_GL_ALPHA:
|
|
||||||
case LOCAL_GL_LUMINANCE:
|
|
||||||
case LOCAL_GL_DEPTH_COMPONENT:
|
|
||||||
case LOCAL_GL_DEPTH_STENCIL:
|
|
||||||
return 1 * bitsPerComponent;
|
|
||||||
|
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
|
||||||
return 2 * bitsPerComponent;
|
|
||||||
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
case LOCAL_GL_RGB32F:
|
|
||||||
case LOCAL_GL_SRGB_EXT:
|
|
||||||
return 3 * bitsPerComponent;
|
|
||||||
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
case LOCAL_GL_RGBA32F:
|
|
||||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
|
||||||
return 4 * bitsPerComponent;
|
|
||||||
|
|
||||||
// Compressed formats
|
|
||||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
|
||||||
case LOCAL_GL_ATC_RGB:
|
|
||||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
|
||||||
case LOCAL_GL_ETC1_RGB8_OES:
|
|
||||||
return 4;
|
|
||||||
|
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
|
||||||
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
|
||||||
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
|
||||||
return 8;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(false, "Unhandled format+type combo.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform validation of format/type combinations for TexImage variants.
|
* Perform validation of format/type combinations for TexImage variants.
|
||||||
* Returns true if the format/type is a valid combination, false otherwise.
|
* Returns true if the format/type is a valid combination, false otherwise.
|
||||||
|
@ -1141,7 +1052,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||||
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||||
type == LOCAL_GL_HALF_FLOAT ||
|
type == LOCAL_GL_HALF_FLOAT ||
|
||||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
|
||||||
type == LOCAL_GL_FLOAT);
|
type == LOCAL_GL_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1150,7 +1060,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||||
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
|
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
|
||||||
type == LOCAL_GL_HALF_FLOAT ||
|
type == LOCAL_GL_HALF_FLOAT ||
|
||||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
|
||||||
type == LOCAL_GL_FLOAT);
|
type == LOCAL_GL_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1160,7 +1069,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||||
type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
||||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
||||||
type == LOCAL_GL_HALF_FLOAT ||
|
type == LOCAL_GL_HALF_FLOAT ||
|
||||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
|
||||||
type == LOCAL_GL_FLOAT);
|
type == LOCAL_GL_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1291,7 +1199,6 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOCAL_GL_HALF_FLOAT:
|
case LOCAL_GL_HALF_FLOAT:
|
||||||
case LOCAL_GL_HALF_FLOAT_OES:
|
|
||||||
case LOCAL_GL_UNSIGNED_SHORT:
|
case LOCAL_GL_UNSIGNED_SHORT:
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||||
|
@ -1449,6 +1356,7 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||||
|
|
||||||
if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
|
if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
|
||||||
width, height, depth,
|
width, height, depth,
|
||||||
imageInfo.Width(), imageInfo.Height(), 0,
|
imageInfo.Width(), imageInfo.Height(), 0,
|
||||||
|
|
|
@ -79,7 +79,7 @@ WebGLFramebuffer::Attachment::HasAlpha() const
|
||||||
MOZ_ASSERT(HasImage());
|
MOZ_ASSERT(HasImage());
|
||||||
|
|
||||||
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
||||||
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat());
|
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat());
|
||||||
else if (Renderbuffer())
|
else if (Renderbuffer())
|
||||||
return FormatHasAlpha(Renderbuffer()->InternalFormat());
|
return FormatHasAlpha(Renderbuffer()->InternalFormat());
|
||||||
else return false;
|
else return false;
|
||||||
|
@ -96,7 +96,7 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
|
||||||
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
|
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
|
||||||
|
|
||||||
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
|
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
|
||||||
return imgInfo.InternalFormat().get();
|
return imgInfo.EffectiveInternalFormat().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment.Renderbuffer())
|
if (attachment.Renderbuffer())
|
||||||
|
@ -105,37 +105,30 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
|
||||||
return LOCAL_GL_NONE;
|
return LOCAL_GL_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
TexInternalFormat
|
||||||
WebGLFramebuffer::Attachment::IsReadableFloat() const
|
WebGLFramebuffer::Attachment::EffectiveInternalFormat() const
|
||||||
{
|
{
|
||||||
const WebGLTexture* tex = Texture();
|
const WebGLTexture* tex = Texture();
|
||||||
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
||||||
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).Type().get();
|
return tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat();
|
||||||
switch (type) {
|
|
||||||
case LOCAL_GL_FLOAT:
|
|
||||||
case LOCAL_GL_HALF_FLOAT_OES:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebGLRenderbuffer* rb = Renderbuffer();
|
const WebGLRenderbuffer* rb = Renderbuffer();
|
||||||
if (rb) {
|
if (rb) {
|
||||||
GLenum format = rb->InternalFormat();
|
return rb->InternalFormat();
|
||||||
switch (format) {
|
|
||||||
case LOCAL_GL_RGB16F:
|
|
||||||
case LOCAL_GL_RGBA16F:
|
|
||||||
case LOCAL_GL_RGB32F:
|
|
||||||
case LOCAL_GL_RGBA32F:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we arrive here Attachment isn't correct setup because it has
|
return LOCAL_GL_NONE;
|
||||||
// no texture nor render buffer pointer.
|
}
|
||||||
MOZ_ASSERT(false, "Should not get here.");
|
|
||||||
return false;
|
bool
|
||||||
|
WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||||
|
{
|
||||||
|
TexInternalFormat internalformat = EffectiveInternalFormat();
|
||||||
|
MOZ_ASSERT(internalformat != LOCAL_GL_NONE);
|
||||||
|
TexType type = TypeFromInternalFormat(internalformat);
|
||||||
|
return type == LOCAL_GL_FLOAT ||
|
||||||
|
type == LOCAL_GL_HALF_FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -230,7 +223,7 @@ WebGLFramebuffer::Attachment::RectangleObject() const
|
||||||
corresponds to the state that is stored in
|
corresponds to the state that is stored in
|
||||||
WebGLTexture::ImageInfo::InternalFormat()*/
|
WebGLTexture::ImageInfo::InternalFormat()*/
|
||||||
static inline bool
|
static inline bool
|
||||||
IsValidFBOTextureColorFormat(GLenum internalFormat)
|
IsValidFBOTextureColorFormat(TexInternalFormat internalformat)
|
||||||
{
|
{
|
||||||
/* These formats are internal formats for each texture -- the actual
|
/* These formats are internal formats for each texture -- the actual
|
||||||
* low level format, which we might have to do conversions for when
|
* low level format, which we might have to do conversions for when
|
||||||
|
@ -239,46 +232,26 @@ IsValidFBOTextureColorFormat(GLenum internalFormat)
|
||||||
* This function just handles all of them whether desktop GL or ES.
|
* This function just handles all of them whether desktop GL or ES.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return (
|
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||||
/* linear 8-bit formats */
|
return unsizedformat == LOCAL_GL_ALPHA ||
|
||||||
internalFormat == LOCAL_GL_ALPHA ||
|
unsizedformat == LOCAL_GL_LUMINANCE ||
|
||||||
internalFormat == LOCAL_GL_LUMINANCE ||
|
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA ||
|
unsizedformat == LOCAL_GL_RGB ||
|
||||||
internalFormat == LOCAL_GL_RGB ||
|
unsizedformat == LOCAL_GL_RGBA ||
|
||||||
internalFormat == LOCAL_GL_RGBA ||
|
unsizedformat == LOCAL_GL_SRGB ||
|
||||||
/* sRGB 8-bit formats */
|
unsizedformat == LOCAL_GL_SRGB_ALPHA;
|
||||||
internalFormat == LOCAL_GL_SRGB_EXT ||
|
|
||||||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
|
|
||||||
/* linear float32 formats */
|
|
||||||
internalFormat == LOCAL_GL_ALPHA32F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_LUMINANCE32F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA32F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_RGB32F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_RGBA32F_ARB ||
|
|
||||||
/* texture_half_float formats */
|
|
||||||
internalFormat == LOCAL_GL_ALPHA16F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_LUMINANCE16F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA16F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_RGB16F_ARB ||
|
|
||||||
internalFormat == LOCAL_GL_RGBA16F_ARB
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
IsValidFBOTextureDepthFormat(GLenum internalFormat)
|
IsValidFBOTextureDepthFormat(GLenum internalformat)
|
||||||
{
|
{
|
||||||
return (
|
return IsGLDepthFormat(internalformat);
|
||||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT ||
|
|
||||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
|
|
||||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
IsValidFBOTextureDepthStencilFormat(GLenum internalFormat)
|
IsValidFBOTextureDepthStencilFormat(GLenum internalformat)
|
||||||
{
|
{
|
||||||
return (
|
return IsGLDepthStencilFormat(internalformat);
|
||||||
internalFormat == LOCAL_GL_DEPTH_STENCIL ||
|
|
||||||
internalFormat == LOCAL_GL_DEPTH24_STENCIL8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following IsValidFBORenderbufferXXX functions check the internal
|
/* The following IsValidFBORenderbufferXXX functions check the internal
|
||||||
|
@ -330,7 +303,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
||||||
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
|
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
|
||||||
const WebGLTexture::ImageInfo& imageInfo =
|
const WebGLTexture::ImageInfo& imageInfo =
|
||||||
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
||||||
GLenum internalformat = imageInfo.InternalFormat().get();
|
GLenum internalformat = imageInfo.EffectiveInternalFormat().get();
|
||||||
|
|
||||||
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
|
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
|
||||||
return IsValidFBOTextureDepthFormat(internalformat);
|
return IsValidFBOTextureDepthFormat(internalformat);
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
|
|
||||||
bool IsDeleteRequested() const;
|
bool IsDeleteRequested() const;
|
||||||
|
|
||||||
|
TexInternalFormat EffectiveInternalFormat() const;
|
||||||
|
|
||||||
bool HasAlpha() const;
|
bool HasAlpha() const;
|
||||||
bool IsReadableFloat() const;
|
bool IsReadableFloat() const;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
// intentionally no include guard here.
|
||||||
|
|
||||||
|
#ifndef HANDLE_WEBGL_INTERNAL_FORMAT
|
||||||
|
#error This header is meant to be included by other files defining HANDLE_WEBGL_INTERNAL_FORMAT.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WEBGL_INTERNAL_FORMAT(effectiveinternalformat, unsizedinternalformat, type) \
|
||||||
|
HANDLE_WEBGL_INTERNAL_FORMAT(LOCAL_GL_##effectiveinternalformat, \
|
||||||
|
LOCAL_GL_##unsizedinternalformat, \
|
||||||
|
LOCAL_GL_##type)
|
||||||
|
|
||||||
|
// OpenGL ES 3.0.3, Table 3.2
|
||||||
|
//
|
||||||
|
// Maps effective internal formats to (unsized internal format, type) pairs.
|
||||||
|
//
|
||||||
|
// Effective int. fmt. Unsized int. fmt. Type
|
||||||
|
WEBGL_INTERNAL_FORMAT(ALPHA8, ALPHA, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE8, LUMINANCE, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE8_ALPHA8, LUMINANCE_ALPHA, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB8, RGB, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA4, RGBA, UNSIGNED_SHORT_4_4_4_4)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB5_A1, RGBA, UNSIGNED_SHORT_5_5_5_1)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA8, RGBA, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB10_A2, RGB, UNSIGNED_INT_2_10_10_10_REV)
|
||||||
|
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT16, DEPTH_COMPONENT, UNSIGNED_SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT24, DEPTH_COMPONENT, UNSIGNED_INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R8, RED, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG8, RG, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R16F, RED, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R32F, RED, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG16F, RG, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG32F, RG, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R8I, RED_INTEGER, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R8UI, RED_INTEGER, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R16I, RED_INTEGER, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R16UI, RED_INTEGER, UNSIGNED_SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R32I, RED_INTEGER, INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R32UI, RED_INTEGER, UNSIGNED_INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG8I, RG_INTEGER, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG8UI, RG_INTEGER, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG16I, RG_INTEGER, SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG16UI, RG_INTEGER, UNSIGNED_SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG32I, RG_INTEGER, INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG32UI, RG_INTEGER, UNSIGNED_INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA32F, RGBA, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB32F, RGB, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(ALPHA32F_EXT, ALPHA, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE32F_EXT, LUMINANCE, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE_ALPHA32F_EXT, LUMINANCE_ALPHA, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA16F, RGBA, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB16F, RGB, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(ALPHA16F_EXT, ALPHA, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE16F_EXT, LUMINANCE, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(LUMINANCE_ALPHA16F_EXT, LUMINANCE_ALPHA, HALF_FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(DEPTH24_STENCIL8, DEPTH_STENCIL, UNSIGNED_INT_24_8)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R11F_G11F_B10F, RGB, UNSIGNED_INT_10F_11F_11F_REV)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB9_E5, RGB, UNSIGNED_INT_5_9_9_9_REV)
|
||||||
|
WEBGL_INTERNAL_FORMAT(SRGB8, SRGB, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(SRGB8_ALPHA8, SRGB_ALPHA, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT32F, DEPTH_COMPONENT, FLOAT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(DEPTH32F_STENCIL8, DEPTH_STENCIL, FLOAT_32_UNSIGNED_INT_24_8_REV)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB565, RGB, UNSIGNED_SHORT_5_6_5)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA32UI, RGBA_INTEGER, UNSIGNED_INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB32UI, RGB_INTEGER, UNSIGNED_INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA16UI, RGBA_INTEGER, UNSIGNED_SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB16UI, RGB_INTEGER, UNSIGNED_SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA8UI, RGBA_INTEGER, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB8UI, RGB_INTEGER, UNSIGNED_BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA32I, RGBA_INTEGER, INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB32I, RGB_INTEGER, INT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA16I, RGBA_INTEGER, SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB16I, RGB_INTEGER, SHORT)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA8I, RGBA_INTEGER, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB8I, RGB_INTEGER, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(R8_SNORM, RED, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RG8_SNORM, RG, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB8_SNORM, RGB, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGBA8_SNORM, RGBA, BYTE)
|
||||||
|
WEBGL_INTERNAL_FORMAT(RGB10_A2UI, RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV)
|
||||||
|
|
||||||
|
#undef WEBGL_INTERNAL_FORMAT
|
||||||
|
#undef HANDLE_WEBGL_INTERNAL_FORMAT
|
|
@ -299,6 +299,9 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
|
||||||
STRONG_GLENUM_VALUE(RGBA),
|
STRONG_GLENUM_VALUE(RGBA),
|
||||||
STRONG_GLENUM_VALUE(LUMINANCE),
|
STRONG_GLENUM_VALUE(LUMINANCE),
|
||||||
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA),
|
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA),
|
||||||
|
STRONG_GLENUM_VALUE(ALPHA8),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE8),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE8_ALPHA8),
|
||||||
STRONG_GLENUM_VALUE(RGB8),
|
STRONG_GLENUM_VALUE(RGB8),
|
||||||
STRONG_GLENUM_VALUE(RGBA4),
|
STRONG_GLENUM_VALUE(RGBA4),
|
||||||
STRONG_GLENUM_VALUE(RGB5_A1),
|
STRONG_GLENUM_VALUE(RGB5_A1),
|
||||||
|
@ -332,8 +335,14 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
|
||||||
STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
|
STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
|
||||||
STRONG_GLENUM_VALUE(RGBA32F),
|
STRONG_GLENUM_VALUE(RGBA32F),
|
||||||
STRONG_GLENUM_VALUE(RGB32F),
|
STRONG_GLENUM_VALUE(RGB32F),
|
||||||
|
STRONG_GLENUM_VALUE(ALPHA32F_EXT),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE32F_EXT),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA32F_EXT),
|
||||||
STRONG_GLENUM_VALUE(RGBA16F),
|
STRONG_GLENUM_VALUE(RGBA16F),
|
||||||
STRONG_GLENUM_VALUE(RGB16F),
|
STRONG_GLENUM_VALUE(RGB16F),
|
||||||
|
STRONG_GLENUM_VALUE(ALPHA16F_EXT),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE16F_EXT),
|
||||||
|
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA16F_EXT),
|
||||||
STRONG_GLENUM_VALUE(DEPTH24_STENCIL8),
|
STRONG_GLENUM_VALUE(DEPTH24_STENCIL8),
|
||||||
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_4BPPV1),
|
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_4BPPV1),
|
||||||
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_2BPPV1),
|
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_2BPPV1),
|
||||||
|
|
|
@ -52,7 +52,7 @@ int64_t
|
||||||
WebGLTexture::ImageInfo::MemoryUsage() const {
|
WebGLTexture::ImageInfo::MemoryUsage() const {
|
||||||
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
|
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
|
||||||
return 0;
|
return 0;
|
||||||
int64_t bitsPerTexel = WebGLContext::GetBitsPerTexel(mInternalFormat, mType);
|
int64_t bitsPerTexel = GetBitsPerTexel(mEffectiveInternalFormat);
|
||||||
return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8;
|
return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,8 +138,7 @@ WebGLTexture::Bind(TexTarget aTexTarget) {
|
||||||
void
|
void
|
||||||
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
|
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
|
||||||
GLsizei aWidth, GLsizei aHeight,
|
GLsizei aWidth, GLsizei aHeight,
|
||||||
TexInternalFormat aInternalFormat, TexType aType,
|
TexInternalFormat aEffectiveInternalFormat, WebGLImageDataStatus aStatus)
|
||||||
WebGLImageDataStatus aStatus)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
|
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
|
||||||
if (TexImageTargetToTexTarget(aTexImageTarget) != mTarget)
|
if (TexImageTargetToTexTarget(aTexImageTarget) != mTarget)
|
||||||
|
@ -147,7 +146,7 @@ WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
|
||||||
|
|
||||||
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
|
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
|
||||||
|
|
||||||
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aInternalFormat, aType, aStatus);
|
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aEffectiveInternalFormat, aStatus);
|
||||||
|
|
||||||
if (aLevel > 0)
|
if (aLevel > 0)
|
||||||
SetCustomMipmap();
|
SetCustomMipmap();
|
||||||
|
@ -329,7 +328,9 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImageInfoBase().mType == LOCAL_GL_FLOAT &&
|
TexType type = TypeFromInternalFormat(ImageInfoBase().mEffectiveInternalFormat);
|
||||||
|
|
||||||
|
if (type == LOCAL_GL_FLOAT &&
|
||||||
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_float_linear))
|
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_float_linear))
|
||||||
{
|
{
|
||||||
if (mMinFilter == LOCAL_GL_LINEAR ||
|
if (mMinFilter == LOCAL_GL_LINEAR ||
|
||||||
|
@ -349,7 +350,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||||
"Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
|
"Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
|
||||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||||
}
|
}
|
||||||
} else if (ImageInfoBase().mType == LOCAL_GL_HALF_FLOAT_OES &&
|
} else if (type == LOCAL_GL_HALF_FLOAT &&
|
||||||
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float_linear))
|
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float_linear))
|
||||||
{
|
{
|
||||||
if (mMinFilter == LOCAL_GL_LINEAR ||
|
if (mMinFilter == LOCAL_GL_LINEAR ||
|
||||||
|
@ -534,13 +535,11 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
|
||||||
mContext->MakeContextCurrent();
|
mContext->MakeContextCurrent();
|
||||||
|
|
||||||
// Try to clear with glCLear.
|
// Try to clear with glCLear.
|
||||||
TexInternalFormat internalformat = imageInfo.mInternalFormat;
|
|
||||||
TexType type = imageInfo.mType;
|
|
||||||
WebGLTexelFormat texelformat = GetWebGLTexelFormat(internalformat, type);
|
|
||||||
|
|
||||||
bool cleared = ClearWithTempFB(mContext, GLName(),
|
bool cleared = ClearWithTempFB(mContext, GLName(),
|
||||||
imageTarget, level,
|
imageTarget, level,
|
||||||
internalformat, imageInfo.mHeight, imageInfo.mWidth);
|
imageInfo.mEffectiveInternalFormat,
|
||||||
|
imageInfo.mHeight, imageInfo.mWidth);
|
||||||
if (cleared) {
|
if (cleared) {
|
||||||
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||||
return;
|
return;
|
||||||
|
@ -549,22 +548,26 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
|
||||||
// That didn't work. Try uploading zeros then.
|
// That didn't work. Try uploading zeros then.
|
||||||
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
|
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
|
||||||
|
|
||||||
uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
|
size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat);
|
||||||
|
MOZ_ASSERT((bitspertexel % 8) == 0); // that would only happen for compressed images, which
|
||||||
|
// cannot use deferred initialization.
|
||||||
|
size_t bytespertexel = bitspertexel / 8;
|
||||||
CheckedUint32 checked_byteLength
|
CheckedUint32 checked_byteLength
|
||||||
= WebGLContext::GetImageSize(
|
= WebGLContext::GetImageSize(
|
||||||
imageInfo.mHeight,
|
imageInfo.mHeight,
|
||||||
imageInfo.mWidth,
|
imageInfo.mWidth,
|
||||||
texelsize,
|
bytespertexel,
|
||||||
mContext->mPixelStoreUnpackAlignment);
|
mContext->mPixelStoreUnpackAlignment);
|
||||||
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
|
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
|
||||||
ScopedFreePtr<void> zeros;
|
ScopedFreePtr<void> zeros;
|
||||||
zeros = calloc(1, checked_byteLength.value());
|
zeros = calloc(1, checked_byteLength.value());
|
||||||
|
|
||||||
gl::GLContext* gl = mContext->gl;
|
gl::GLContext* gl = mContext->gl;
|
||||||
GLenum driverType = DriverTypeFromType(gl, type);
|
|
||||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||||
GLenum driverFormat = LOCAL_GL_NONE;
|
GLenum driverFormat = LOCAL_GL_NONE;
|
||||||
DriverFormatsFromFormatAndType(gl, internalformat, type, &driverInternalFormat, &driverFormat);
|
GLenum driverType = LOCAL_GL_NONE;
|
||||||
|
DriverFormatsFromEffectiveInternalFormat(gl, imageInfo.mEffectiveInternalFormat,
|
||||||
|
&driverInternalFormat, &driverFormat, &driverType);
|
||||||
|
|
||||||
mContext->GetAndFlushUnderlyingGLErrors();
|
mContext->GetAndFlushUnderlyingGLErrors();
|
||||||
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
|
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
|
||||||
|
|
|
@ -67,19 +67,16 @@ public:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageInfo()
|
ImageInfo()
|
||||||
: mInternalFormat(LOCAL_GL_NONE)
|
: mEffectiveInternalFormat(LOCAL_GL_NONE)
|
||||||
, mType(LOCAL_GL_NONE)
|
|
||||||
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
|
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ImageInfo(GLsizei width,
|
ImageInfo(GLsizei width,
|
||||||
GLsizei height,
|
GLsizei height,
|
||||||
TexInternalFormat internalFormat,
|
TexInternalFormat effectiveInternalFormat,
|
||||||
TexType type,
|
|
||||||
WebGLImageDataStatus status)
|
WebGLImageDataStatus status)
|
||||||
: WebGLRectangleObject(width, height)
|
: WebGLRectangleObject(width, height)
|
||||||
, mInternalFormat(internalFormat)
|
, mEffectiveInternalFormat(effectiveInternalFormat)
|
||||||
, mType(type)
|
|
||||||
, mImageDataStatus(status)
|
, mImageDataStatus(status)
|
||||||
{
|
{
|
||||||
// shouldn't use this constructor to construct a null ImageInfo
|
// shouldn't use this constructor to construct a null ImageInfo
|
||||||
|
@ -90,8 +87,7 @@ public:
|
||||||
return mImageDataStatus == a.mImageDataStatus &&
|
return mImageDataStatus == a.mImageDataStatus &&
|
||||||
mWidth == a.mWidth &&
|
mWidth == a.mWidth &&
|
||||||
mHeight == a.mHeight &&
|
mHeight == a.mHeight &&
|
||||||
mInternalFormat == a.mInternalFormat &&
|
mEffectiveInternalFormat == a.mEffectiveInternalFormat;
|
||||||
mType == a.mType;
|
|
||||||
}
|
}
|
||||||
bool operator!=(const ImageInfo& a) const {
|
bool operator!=(const ImageInfo& a) const {
|
||||||
return !(*this == a);
|
return !(*this == a);
|
||||||
|
@ -110,21 +106,17 @@ public:
|
||||||
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
|
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
|
||||||
}
|
}
|
||||||
int64_t MemoryUsage() const;
|
int64_t MemoryUsage() const;
|
||||||
/*! This is the format passed from JS to WebGL.
|
|
||||||
* It can be converted to a value to be passed to driver with
|
|
||||||
* DriverFormatsFromFormatAndType().
|
|
||||||
*/
|
|
||||||
TexInternalFormat InternalFormat() const { return mInternalFormat; }
|
|
||||||
|
|
||||||
/*! This is the type passed from JS to WebGL.
|
TexInternalFormat EffectiveInternalFormat() const { return mEffectiveInternalFormat; }
|
||||||
* It can be converted to a value to be passed to driver with
|
|
||||||
* DriverTypeFromType().
|
|
||||||
*/
|
|
||||||
TexType Type() const { return mType; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TexInternalFormat mInternalFormat; //!< This is the WebGL/GLES internal format.
|
/*
|
||||||
TexType mType; //!< This is the WebGL/GLES type
|
* This is the "effective internal format" of the texture,
|
||||||
|
* an official OpenGL spec concept, see
|
||||||
|
* OpenGL ES 3.0.3 spec, section 3.8.3, page 126 and below.
|
||||||
|
*/
|
||||||
|
TexInternalFormat mEffectiveInternalFormat;
|
||||||
|
|
||||||
WebGLImageDataStatus mImageDataStatus;
|
WebGLImageDataStatus mImageDataStatus;
|
||||||
|
|
||||||
friend class WebGLTexture;
|
friend class WebGLTexture;
|
||||||
|
@ -230,8 +222,7 @@ public:
|
||||||
|
|
||||||
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
|
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
|
||||||
GLsizei aWidth, GLsizei aHeight,
|
GLsizei aWidth, GLsizei aHeight,
|
||||||
TexInternalFormat aInternalFormat, TexType aType,
|
TexInternalFormat aFormat, WebGLImageDataStatus aStatus);
|
||||||
WebGLImageDataStatus aStatus);
|
|
||||||
|
|
||||||
void SetMinFilter(TexMinFilter aMinFilter) {
|
void SetMinFilter(TexMinFilter aMinFilter) {
|
||||||
mMinFilter = aMinFilter;
|
mMinFilter = aMinFilter;
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_FORWARD_SAFE_NSICELLBROADCASTLISTENER(mCellBroadcast)
|
NS_FORWARD_SAFE_NSICELLBROADCASTLISTENER(mCellBroadcast)
|
||||||
|
|
||||||
Listener(CellBroadcast* aCellBroadcast)
|
explicit Listener(CellBroadcast* aCellBroadcast)
|
||||||
: mCellBroadcast(aCellBroadcast)
|
: mCellBroadcast(aCellBroadcast)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCellBroadcast);
|
MOZ_ASSERT(mCellBroadcast);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head.js
|
head = head.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'gonk'
|
||||||
|
|
||||||
[test_misc.js]
|
[test_misc.js]
|
||||||
[test_utf.js]
|
[test_utf.js]
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Response MOZ_FINAL : public nsISupports
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Response(nsISupports* aOwner);
|
explicit Response(nsISupports* aOwner);
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapObject(JSContext* aCx)
|
WrapObject(JSContext* aCx)
|
||||||
|
|
|
@ -115,6 +115,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||||
[test_blob_worker_crash.html]
|
[test_blob_worker_crash.html]
|
||||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||||
|
[test_blob_worker_xhr_post.html]
|
||||||
|
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||||
[test_blocked_order.html]
|
[test_blocked_order.html]
|
||||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||||
[test_bug937006.html]
|
[test_bug937006.html]
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Indexed Database Property Test</title>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
|
||||||
|
<script type="text/javascript;version=1.7">
|
||||||
|
function testSteps()
|
||||||
|
{
|
||||||
|
const BLOB_DATA = ["fun ", "times ", "all ", "around!"];
|
||||||
|
const BLOB_TYPE = "text/plain";
|
||||||
|
const BLOB_SIZE = BLOB_DATA.join("").length;
|
||||||
|
|
||||||
|
info("Setting up");
|
||||||
|
|
||||||
|
let request = indexedDB.open(window.location.pathname, 1);
|
||||||
|
request.onerror = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = unexpectedSuccessHandler;
|
||||||
|
let event = yield undefined;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
|
ok(db, "Created database");
|
||||||
|
|
||||||
|
info("Creating objectStore");
|
||||||
|
|
||||||
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
event = yield undefined;
|
||||||
|
|
||||||
|
ok(true, "Opened database");
|
||||||
|
|
||||||
|
let blob = new Blob(BLOB_DATA, { type: BLOB_TYPE });
|
||||||
|
|
||||||
|
info("Adding blob to database");
|
||||||
|
|
||||||
|
objectStore = db.transaction("foo", "readwrite").objectStore("foo");
|
||||||
|
objectStore.add(blob).onsuccess = grabEventAndContinueHandler;
|
||||||
|
event = yield undefined;
|
||||||
|
|
||||||
|
let blobKey = event.target.result;
|
||||||
|
ok(blobKey, "Got a key for the blob");
|
||||||
|
|
||||||
|
info("Getting blob from the database");
|
||||||
|
|
||||||
|
objectStore = db.transaction("foo").objectStore("foo");
|
||||||
|
objectStore.get(blobKey).onsuccess = grabEventAndContinueHandler;
|
||||||
|
event = yield undefined;
|
||||||
|
|
||||||
|
blob = event.target.result;
|
||||||
|
|
||||||
|
ok(blob instanceof Blob, "Got a blob");
|
||||||
|
is(blob.size, BLOB_SIZE, "Correct size");
|
||||||
|
is(blob.type, BLOB_TYPE, "Correct type");
|
||||||
|
|
||||||
|
let slice = blob.slice(0, BLOB_DATA[0].length, BLOB_TYPE);
|
||||||
|
|
||||||
|
ok(slice instanceof Blob, "Slice returned a blob");
|
||||||
|
is(slice.size, BLOB_DATA[0].length, "Correct size for slice");
|
||||||
|
is(slice.type, BLOB_TYPE, "Correct type for slice");
|
||||||
|
|
||||||
|
info("Sending slice to a worker");
|
||||||
|
|
||||||
|
function workerScript() {
|
||||||
|
onmessage = function(event) {
|
||||||
|
var blob = event.data;
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
// We just want to make sure the error case doesn't fire; it's fine for
|
||||||
|
// us to just want a 404.
|
||||||
|
xhr.open('POST', 'http://mochi.test:8888/does-not-exist', true);
|
||||||
|
xhr.onload = function() {
|
||||||
|
postMessage({ status: xhr.status });
|
||||||
|
};
|
||||||
|
xhr.onerror = function() {
|
||||||
|
postMessage({ status: 'error' });
|
||||||
|
}
|
||||||
|
xhr.send(blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let workerScriptUrl =
|
||||||
|
URL.createObjectURL(new Blob(["(", workerScript.toSource(), ")()"]));
|
||||||
|
|
||||||
|
let xhrWorker = new Worker(workerScriptUrl);
|
||||||
|
xhrWorker.postMessage(slice);
|
||||||
|
xhrWorker.onmessage = grabEventAndContinueHandler;
|
||||||
|
event = yield undefined;
|
||||||
|
|
||||||
|
is(event.data.status, 404, "XHR generated the expected 404");
|
||||||
|
xhrWorker.terminate();
|
||||||
|
|
||||||
|
URL.revokeObjectURL(workerScriptUrl);
|
||||||
|
|
||||||
|
finishTest();
|
||||||
|
yield undefined;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="runTest();"></body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -6,6 +6,7 @@
|
||||||
dupe-manifest =
|
dupe-manifest =
|
||||||
head = xpcshell-head-child-process.js
|
head = xpcshell-head-child-process.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
GlobalObjectsChild.js
|
GlobalObjectsChild.js
|
||||||
GlobalObjectsComponent.js
|
GlobalObjectsComponent.js
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
dupe-manifest =
|
dupe-manifest =
|
||||||
head = xpcshell-head-parent-process.js
|
head = xpcshell-head-parent-process.js
|
||||||
tail =
|
tail =
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
support-files =
|
support-files =
|
||||||
GlobalObjectsChild.js
|
GlobalObjectsChild.js
|
||||||
GlobalObjectsComponent.js
|
GlobalObjectsComponent.js
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# 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
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
[DEFAULT]
|
||||||
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
[test_add_put.js]
|
[test_add_put.js]
|
||||||
[test_add_twice_failure.js]
|
[test_add_twice_failure.js]
|
||||||
|
|
105
dom/ipc/Blob.cpp
105
dom/ipc/Blob.cpp
|
@ -329,7 +329,7 @@ class RemoteInputStream MOZ_FINAL
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
|
||||||
RemoteInputStream(DOMFileImpl* aBlobImpl)
|
explicit RemoteInputStream(DOMFileImpl* aBlobImpl)
|
||||||
: mMonitor("RemoteInputStream.mMonitor")
|
: mMonitor("RemoteInputStream.mMonitor")
|
||||||
, mBlobImpl(aBlobImpl)
|
, mBlobImpl(aBlobImpl)
|
||||||
, mWeakSeekableStream(nullptr)
|
, mWeakSeekableStream(nullptr)
|
||||||
|
@ -359,17 +359,19 @@ public:
|
||||||
Serialize(InputStreamParams& aParams,
|
Serialize(InputStreamParams& aParams,
|
||||||
FileDescriptorArray& /* aFileDescriptors */)
|
FileDescriptorArray& /* aFileDescriptors */)
|
||||||
{
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(mBlobImpl);
|
||||||
|
|
||||||
nsCOMPtr<nsIRemoteBlob> remote = do_QueryInterface(mBlobImpl);
|
nsCOMPtr<nsIRemoteBlob> remote = do_QueryInterface(mBlobImpl);
|
||||||
MOZ_ASSERT(remote);
|
MOZ_ASSERT(remote);
|
||||||
MOZ_ASSERT(remote->GetBlobChild());
|
|
||||||
|
|
||||||
aParams = RemoteInputStreamParams(
|
BlobChild* actor = remote->GetBlobChild();
|
||||||
nullptr /* sourceParent */,
|
MOZ_ASSERT(actor);
|
||||||
remote->GetBlobChild() /* sourceChild */);
|
|
||||||
|
aParams = RemoteInputStreamParams(actor->ParentID());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Deserialize(const InputStreamParams& aParams,
|
Deserialize(const InputStreamParams& /* aParams */,
|
||||||
const FileDescriptorArray& /* aFileDescriptors */)
|
const FileDescriptorArray& /* aFileDescriptors */)
|
||||||
{
|
{
|
||||||
// See InputStreamUtils.cpp to see how deserialization of a
|
// See InputStreamUtils.cpp to see how deserialization of a
|
||||||
|
@ -419,15 +421,48 @@ public:
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
Available(uint64_t* aAvailable) MOZ_OVERRIDE
|
Available(uint64_t* aAvailable) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
// See large comment in FileInputStreamWrapper::Available.
|
if (!IsOnOwningThread()) {
|
||||||
if (IsOnOwningThread()) {
|
nsresult rv = BlockAndWaitForStream();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = mStream->Available(aAvailable);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
NS_WARNING("Someone is trying to do main-thread I/O...");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
// See if we already have our real stream.
|
||||||
|
nsCOMPtr<nsIInputStream> inputStream;
|
||||||
|
{
|
||||||
|
MonitorAutoLock lock(mMonitor);
|
||||||
|
|
||||||
|
inputStream = mStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we do then just call through.
|
||||||
|
if (inputStream) {
|
||||||
|
rv = inputStream->Available(aAvailable);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the stream is already closed then we can't do anything.
|
||||||
|
if (!mBlobImpl) {
|
||||||
return NS_BASE_STREAM_CLOSED;
|
return NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = BlockAndWaitForStream();
|
// Otherwise fake it...
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_WARNING("Available() called before real stream has been delivered, "
|
||||||
|
"guessing the amount of data available!");
|
||||||
|
|
||||||
rv = mStream->Available(aAvailable);
|
rv = mBlobImpl->GetSize(aAvailable);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -690,7 +725,8 @@ public:
|
||||||
aProcessID,
|
aProcessID,
|
||||||
aBlobImpl,
|
aBlobImpl,
|
||||||
/* aMayCreate */ true,
|
/* aMayCreate */ true,
|
||||||
/* aMayGet */ false);
|
/* aMayGet */ false,
|
||||||
|
/* aIgnoreProcessID */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<IDTableEntry>
|
static already_AddRefed<IDTableEntry>
|
||||||
|
@ -700,7 +736,19 @@ public:
|
||||||
aProcessID,
|
aProcessID,
|
||||||
nullptr,
|
nullptr,
|
||||||
/* aMayCreate */ false,
|
/* aMayCreate */ false,
|
||||||
/* aMayGet */ true);
|
/* aMayGet */ true,
|
||||||
|
/* aIgnoreProcessID */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<IDTableEntry>
|
||||||
|
Get(const nsID& aID)
|
||||||
|
{
|
||||||
|
return GetOrCreateInternal(aID,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
/* aMayCreate */ false,
|
||||||
|
/* aMayGet */ true,
|
||||||
|
/* aIgnoreProcessID */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<IDTableEntry>
|
static already_AddRefed<IDTableEntry>
|
||||||
|
@ -716,7 +764,8 @@ public:
|
||||||
aProcessID,
|
aProcessID,
|
||||||
aBlobImpl,
|
aBlobImpl,
|
||||||
/* aMayCreate */ true,
|
/* aMayCreate */ true,
|
||||||
/* aMayGet */ true);
|
/* aMayGet */ true,
|
||||||
|
/* aIgnoreProcessID */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsID&
|
const nsID&
|
||||||
|
@ -748,7 +797,8 @@ private:
|
||||||
intptr_t aProcessID,
|
intptr_t aProcessID,
|
||||||
DOMFileImpl* aBlobImpl,
|
DOMFileImpl* aBlobImpl,
|
||||||
bool aMayCreate,
|
bool aMayCreate,
|
||||||
bool aMayGet);
|
bool aMayGet,
|
||||||
|
bool aIgnoreProcessID);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Each instance of this class will be dispatched to the network stream thread
|
// Each instance of this class will be dispatched to the network stream thread
|
||||||
|
@ -2917,6 +2967,26 @@ BlobParent::Create(PBackgroundParent* aManager,
|
||||||
return CreateFromParams(aManager, aParams);
|
return CreateFromParams(aManager, aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<DOMFileImpl>
|
||||||
|
BlobParent::GetBlobImplForID(const nsID& aID)
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF(gProcessType != GeckoProcessType_Default)) {
|
||||||
|
ASSERT_UNLESS_FUZZING();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<IDTableEntry> idTableEntry = IDTableEntry::Get(aID);
|
||||||
|
if (NS_WARN_IF(!idTableEntry)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<DOMFileImpl> blobImpl = idTableEntry->BlobImpl();
|
||||||
|
MOZ_ASSERT(blobImpl);
|
||||||
|
|
||||||
|
return blobImpl.forget();
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
template <class ParentManagerType>
|
template <class ParentManagerType>
|
||||||
BlobParent*
|
BlobParent*
|
||||||
|
@ -3550,7 +3620,8 @@ IDTableEntry::GetOrCreateInternal(const nsID& aID,
|
||||||
intptr_t aProcessID,
|
intptr_t aProcessID,
|
||||||
DOMFileImpl* aBlobImpl,
|
DOMFileImpl* aBlobImpl,
|
||||||
bool aMayCreate,
|
bool aMayCreate,
|
||||||
bool aMayGet)
|
bool aMayGet,
|
||||||
|
bool aIgnoreProcessID)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
|
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
|
||||||
MOZ_ASSERT(sIDTableMutex);
|
MOZ_ASSERT(sIDTableMutex);
|
||||||
|
@ -3578,7 +3649,7 @@ IDTableEntry::GetOrCreateInternal(const nsID& aID,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(entry->mProcessID != aProcessID)) {
|
if (!aIgnoreProcessID && NS_WARN_IF(entry->mProcessID != aProcessID)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -107,6 +107,9 @@ public:
|
||||||
delete static_cast<BlobParent*>(aActor);
|
delete static_cast<BlobParent*>(aActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<DOMFileImpl>
|
||||||
|
GetBlobImplForID(const nsID& aID);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HasManager() const
|
HasManager() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -3517,14 +3517,14 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentParent::AnswerRpcMessage(const nsString& aMsg,
|
ContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
const InfallibleTArray<CpowEntry>& aCpows,
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
const IPC::Principal& aPrincipal,
|
const IPC::Principal& aPrincipal,
|
||||||
InfallibleTArray<nsString>* aRetvals)
|
InfallibleTArray<nsString>* aRetvals)
|
||||||
{
|
{
|
||||||
return nsIContentParent::AnswerRpcMessage(aMsg, aData, aCpows, aPrincipal,
|
return nsIContentParent::RecvRpcMessage(aMsg, aData, aCpows, aPrincipal,
|
||||||
aRetvals);
|
aRetvals);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче