Merge m-c to b2g-inbound a=merge

--HG--
extra : amend_source : 97412f1e791df737909df250fa3cf08eb9763504
This commit is contained in:
Carsten "Tomcat" Book 2014-10-08 16:06:57 +02:00
commit 9836aad597
473 changed files with 5499 additions and 3942 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1069071: IPDL changes require CLOBBER
Bug 1069071: IPDL changes require CLOBBER (second time around)

View File

@ -739,7 +739,7 @@ namespace {
struct RoleComparator
{
const nsDependentSubstring& mRole;
RoleComparator(const nsDependentSubstring& aRole) : mRole(aRole) {}
explicit RoleComparator(const nsDependentSubstring& aRole) : mRole(aRole) {}
int operator()(const nsRoleMapEntry& aEntry) const {
return Compare(mRole, aEntry.ARIARoleString());
}

View File

@ -67,6 +67,14 @@ Accessible::ScrollTo(uint32_t aHow) const
nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aHow);
}
inline bool
Accessible::UpdateChildren()
{
AutoTreeMutation mut(this);
InvalidateChildren();
return EnsureChildren();
}
} // namespace a11y
} // namespace mozilla

View File

@ -1936,7 +1936,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
mParent = aParent;
mIndexInParent = aIndexInParent;
mParent->InvalidateChildrenGroupInfo();
#ifdef DEBUG
AssertInMutatingSubtree();
#endif
// Note: this is currently only used for richlistitems and their children.
if (mParent->HasNameDependentParent() || mParent->IsXULListItem())
@ -1949,7 +1951,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
void
Accessible::UnbindFromParent()
{
mParent->InvalidateChildrenGroupInfo();
#ifdef DEBUG
AssertInMutatingSubtree();
#endif
mParent = nullptr;
mIndexInParent = -1;
mIndexOfEmbeddedChild = -1;
@ -2658,6 +2662,21 @@ Accessible::StaticAsserts() const
"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

View File

@ -373,11 +373,7 @@ public:
/**
* Update the children cache.
*/
inline bool UpdateChildren()
{
InvalidateChildren();
return EnsureChildren();
}
bool UpdateChildren();
/**
* 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
eHasNumericValue = 1 << 4, // accessible has a numeric value
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
};
@ -1064,7 +1061,7 @@ protected:
int32_t mIndexInParent;
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 kTypeBits = 6;
static const uint8_t kGenericTypesBits = 13;
@ -1079,9 +1076,11 @@ protected:
uint32_t mGenericTypes : kGenericTypesBits;
void StaticAsserts() const;
void AssertInMutatingSubtree() const;
friend class DocAccessible;
friend class xpcAccessible;
friend class AutoTreeMutation;
nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
int32_t mIndexOfEmbeddedChild;
@ -1165,6 +1164,35 @@ private:
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 mozilla

View File

@ -483,7 +483,13 @@ DocAccessible::Shutdown()
mDependentIDsHash.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();
@ -1318,8 +1324,10 @@ DocAccessible::ProcessInvalidationList()
}
// Make sure the subtree is created.
if (accessible)
if (accessible) {
AutoTreeMutation mut(accessible);
CacheChildrenInSubtree(accessible);
}
}
mInvalidationList.Clear();
@ -1425,7 +1433,9 @@ DocAccessible::DoInitialUpdate()
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);
// 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
// there's no inserted accessibles in the end because accessible children
// are created while parent recaches child accessibles.
// XXX Group invalidation here may be redundant with invalidation in
// UpdateTree.
AutoTreeMutation mut(aContainer);
aContainer->InvalidateChildren();
CacheChildrenInSubtree(aContainer);
}
@ -1691,6 +1704,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
#endif
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
AutoTreeMutation mut(aContainer);
if (child) {
updateFlags |= UpdateTreeInternal(child, aIsInsert, reorderEvent);

View File

@ -85,7 +85,8 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
if (!imageMapObj)
return;
bool doReorderEvent = false;
bool treeChanged = false;
AutoTreeMutation mut(this);
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
// 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());
mDoc->FireDelayedEvent(event);
reorderEvent->AddSubMutationEvent(event);
doReorderEvent = true;
}
RemoveChild(area);
treeChanged = true;
}
// Insert new areas into the tree.
@ -123,14 +124,18 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
mDoc->FireDelayedEvent(event);
reorderEvent->AddSubMutationEvent(event);
doReorderEvent = true;
}
treeChanged = true;
}
}
// Fire reorder event if needed.
if (doReorderEvent)
if (treeChanged && aDoFireEvents)
mDoc->FireDelayedEvent(reorderEvent);
if (!treeChanged)
mut.mInvalidationRequired = false;
}
Accessible*

View File

@ -385,6 +385,14 @@ let OutputGenerator = {
this._addLandmark(output, aAccessible);
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;
}
}
};

View File

@ -440,6 +440,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
oldAccOrElmOrID: "grid",
expectedUtterance: [["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.
@ -581,7 +587,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
</ol>
<ol role="row">
<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>
</ol>
</section>

View File

@ -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
# recipe evaluation is deferred, we can set it here after the inclusion.
ifneq (,$(JS_BINARY))
ifndef MOZ_DEBUG
MOZ_PACKAGER_MINIFY_JS=1
endif
endif
ifeq (bundle, $(MOZ_FS_LAYOUT))
BINPATH = $(_BINPATH)

View File

@ -1616,6 +1616,11 @@ pref("loop.debug.loglevel", "Error");
pref("loop.debug.dispatcher", false);
pref("loop.debug.websocket", 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.scope", "https://www.google.com/m8/feeds");

View File

@ -7,8 +7,6 @@
const PREF_INTRO_SHOWN = "browser.newtabpage.introShown";
let gIntro = {
_introShown: Services.prefs.getBoolPref(PREF_INTRO_SHOWN),
_nodeIDSuffixes: [
"panel",
"what",
@ -26,7 +24,7 @@ let gIntro = {
},
showIfNecessary: function() {
if (!this._introShown) {
if (!Services.prefs.getBoolPref(PREF_INTRO_SHOWN)) {
Services.prefs.setBoolPref(PREF_INTRO_SHOWN, true);
this.showPanel();
}

View File

@ -12,6 +12,7 @@ const kObservedTopics = [
];
const PREF_PERMISSION_FAKE = "media.navigator.permission.fake";
const PREF_LOOP_CSP = "loop.CSP";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -162,12 +163,14 @@ fakeLoopAboutModule.prototype = {
let factory = XPCOMUtils._getFactory(fakeLoopAboutModule);
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
let originalLoopCsp = Services.prefs.getCharPref(PREF_LOOP_CSP);
registerCleanupFunction(function() {
gBrowser.removeCurrentTab();
kObservedTopics.forEach(topic => {
Services.obs.removeObserver(observer, topic);
});
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",
run: function checkAudioVideoLoop() {
Services.prefs.setCharPref(PREF_LOOP_CSP, "default-src 'unsafe-inline'");
let classID = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator).generateUUID();
registrar.registerFactory(classID, "",
@ -198,6 +203,7 @@ let gTests = [
yield closeStream();
registrar.unregisterFactory(classID, factory);
Services.prefs.setCharPref(PREF_LOOP_CSP, originalLoopCsp);
}
},

View File

@ -23,7 +23,6 @@ support-files =
offlineEvent.cacheManifest
offlineEvent.cacheManifest^headers^
offlineEvent.html
privateBrowsingMode.js
subtst_contextmenu.html
video.ogg

View File

@ -1,3 +0,0 @@
// This file is only present in per-window private browsing buikds.
var perWindowPrivateBrowsing = true;

View File

@ -15,8 +15,6 @@ Browser context menu tests.
</div>
<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 class="testbody" type="text/javascript">
@ -111,26 +109,15 @@ function runTest(testNum) {
function () {
// Context menu for text link
if (perWindowPrivateBrowsing) {
checkContextMenu(["context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", true,
"---", null,
"context-bookmarklink", true,
"context-savelink", true,
"context-copylink", true,
"context-searchselect", true
].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));
}
checkContextMenu(["context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", true,
"---", null,
"context-bookmarklink", true,
"context-savelink", true,
"context-copylink", true,
"context-searchselect", true
].concat(inspectItems));
closeContextMenu();
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
if (SpecialPowers.Services.appinfo.OS == "Darwin") {
// This test is only enabled on Mac due to bug 736399.
if (perWindowPrivateBrowsing) {
checkContextMenu(["context-openlinkincurrent", true,
"context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", true,
"---", null,
"context-bookmarklink", true,
"context-savelink", true,
"context-copy", true,
"context-selectall", true,
"---", null,
"context-searchselect", true,
"context-viewpartialsource-selection", true
].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));
}
checkContextMenu(["context-openlinkincurrent", true,
"context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", 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();
// clear the selection because following tests don't expect any selection
@ -625,42 +597,23 @@ function runTest(testNum) {
function () {
// Context menu for image link
if (perWindowPrivateBrowsing) {
checkContextMenu(["context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", 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));
} 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));
}
checkContextMenu(["context-openlinkintab", true,
"context-openlink", true,
"context-openlinkprivate", 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();
selectInputText(select_inputtext); // Select text prior to opening context menu.
openContextMenuFor(select_inputtext); // Invoke context menu for next test.

View File

@ -2,6 +2,7 @@
head = head_dirprovider.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_bookmark_pref.js]
[test_keys.js]

View File

@ -2,5 +2,6 @@
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_DownloadsCommon.js]

View File

@ -2,6 +2,7 @@
head = head_feeds.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_355473.js]
[test_758990.js]

View File

@ -9,3 +9,8 @@ set -e
# 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
# 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

View File

@ -2,6 +2,7 @@
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'gonk'
[test_loopapi_hawk_request.js]
[test_looppush_initialize.js]

View File

@ -2,6 +2,7 @@
head = head_migration.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_IE_bookmarks.js]
skip-if = os != "win"

View File

@ -507,7 +507,6 @@ BrowserGlue.prototype = {
NewTabUtils.init();
DirectoryLinksProvider.init();
NewTabUtils.links.addProvider(DirectoryLinksProvider);
BrowserNewTabPreloader.init();
#ifdef NIGHTLY_BUILD
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
SignInToWebsiteUX.init();
@ -2243,7 +2242,7 @@ let DefaultBrowserCheck = {
let iconPixels = win.devicePixelRatio > 1 ? "32" : "16";
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);
this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
iconURL, priority, buttons,

View File

@ -2,6 +2,7 @@
head = head_bookmarks.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
bookmarks.glue.html
bookmarks.glue.json

View File

@ -397,7 +397,6 @@
var menuitem = document.createElementNS(kXULNS, "menuitem");
var name = engines[i].name;
menuitem.setAttribute("label", name);
menuitem.setAttribute("id", name);
menuitem.setAttribute("class", "menuitem-iconic searchbar-engine-menuitem menuitem-with-favicon");
// Since this menu is rebuilt by the observer method whenever a new
// engine is selected, the "selected" attribute does not need to be

View File

@ -187,7 +187,7 @@ skip-if = true # Needs to be rewritten as Marionette test, bug 995916
[browser_739531.js]
[browser_739805.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
[browser_464620_a.js]

View File

@ -2,6 +2,7 @@
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
data/sessionCheckpoints_all.json
data/sessionstore_invalid.js

View File

@ -2,5 +2,6 @@
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_421977.js]

View File

@ -2,6 +2,7 @@
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_cld2.js]
[test_healthreport.js]

View File

@ -49,6 +49,8 @@ function ToolSidebar(tabbox, panel, uid, showTabstripe=true)
if (!showTabstripe) {
this._tabbox.setAttribute("hidetabs", "true");
}
this._toolPanel.emit("sidebar-created", this);
}
exports.ToolSidebar = ToolSidebar;
@ -210,6 +212,8 @@ ToolSidebar.prototype = {
this._tabbox.width = this._width;
}
this._tabbox.removeAttribute("hidden");
this.emit("show");
},
/**
@ -218,6 +222,8 @@ ToolSidebar.prototype = {
hide: function ToolSidebar_hide() {
Services.prefs.setIntPref("devtools.toolsidebar-width." + this._uid, this._tabbox.width);
this._tabbox.setAttribute("hidden", "true");
this.emit("hide");
},
/**
@ -257,6 +263,8 @@ ToolSidebar.prototype = {
this._telemetry.toolClosed(this._currentTool);
}
this._toolPanel.emit("sidebar-destroyed", this);
this._tabs = null;
this._tabbox = null;
this._panelDoc = null;

View File

@ -30,6 +30,7 @@ skip-if = e10s # Bug 1070837 - devtools/framework/toolbox.js |doc| getter not e1
[browser_toolbox_select_event.js]
skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown
[browser_toolbox_sidebar.js]
[browser_toolbox_sidebar_events.js]
[browser_toolbox_tabsswitch_shortcuts.js]
[browser_toolbox_tool_ready.js]
[browser_toolbox_tool_remote_reopen.js]

View File

@ -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();
});
}
}

View File

@ -897,6 +897,15 @@ Toolbox.prototype = {
let panel = built;
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);
this.emit(id + "-build", panel);
@ -915,6 +924,14 @@ Toolbox.prototype = {
promise.resolve(built).then((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);
this.emit(id + "-ready", panel);

View File

@ -54,9 +54,6 @@ var ResourceContainer = Class({
this.expander.setAttribute("open", "");
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.className = "file-label";
this.line.appendChild(this.label);
@ -93,11 +90,10 @@ var ResourceContainer = Class({
destroy: function() {
this.elt.remove();
this.expander.remove();
this.icon.remove();
this.highlighter.remove();
this.children.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.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";
},

View File

@ -45,6 +45,7 @@ const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).de
const Telemetry = require("devtools/shared/telemetry");
const Editor = require("devtools/sourceeditor/editor");
const TargetFactory = require("devtools/framework/target").TargetFactory;
const EventEmitter = require("devtools/toolkit/event-emitter");
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -2169,6 +2170,10 @@ ScratchpadTarget.prototype = Heritage.extend(ScratchpadTab.prototype, {
*/
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 tabbox = document.querySelector("#scratchpad-sidebar");
this._sidebar = new ToolSidebar(tabbox, this, "scratchpad");

View File

@ -2,6 +2,7 @@
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_bezierCanvas.js]
[test_cubicBezier.js]

View File

@ -2,6 +2,7 @@
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_parseDeclarations.js]
[test_parseSingleValue.js]

View File

@ -2,6 +2,7 @@
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
experiments_1.manifest
experiment-1.xpi

View File

@ -444,6 +444,9 @@
@BINPATH@/components/addoncompat.manifest
@BINPATH@/components/multiprocessShims.js
@BINPATH@/components/pluginGlue.manifest
@BINPATH@/components/ProcessSingleton.manifest
@BINPATH@/components/MainProcessSingleton.js
@BINPATH@/components/ContentProcessSingleton.js
@BINPATH@/browser/components/nsSessionStore.manifest
@BINPATH@/browser/components/nsSessionStartup.js
@BINPATH@/browser/components/nsSessionStore.js

View File

@ -74,7 +74,10 @@ else
SEARCHPLUGINS_NAMES = $(shell cat $(call MERGE_FILE,/searchplugins/list.txt))
endif
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
# 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)))
$(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-%:
$(NSINSTALL) -D $(DIST)/install
@$(MAKE) -C ../../toolkit/locales libs-$*

View File

@ -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_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='win'/>";
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
// 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";
function isPreloadingEnabled() {
return Services.prefs.getBoolPref(PREF_NEWTAB_PRELOAD) &&
!Services.prefs.prefHasUserValue(PREF_NEWTAB_URL);
}
function createTimer(obj, delay) {
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.init(obj, delay, Ci.nsITimer.TYPE_ONE_SHOT);
@ -48,18 +55,13 @@ function clearTimer(timer) {
}
this.BrowserNewTabPreloader = {
init: function Preloader_init() {
Preferences.init();
},
uninit: function Preloader_uninit() {
HostFrame.destroy();
Preferences.uninit();
HiddenBrowsers.uninit();
},
newTab: function Preloader_newTab(aTab) {
if (!Preferences.enabled) {
if (!isPreloadingEnabled()) {
return false;
}
@ -81,41 +83,6 @@ this.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 = {
_browsers: null,
_updateTimer: null,

View File

@ -2,6 +2,7 @@
head = head.js
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files = blocklist.xml
[test_social.js]

View File

@ -2,5 +2,6 @@
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_DirectoryLinksProvider.js]

View File

@ -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/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/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/index.css (../shared/devtools/app-manager/index.css)
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)

View File

@ -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/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/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/index.css (../shared/devtools/app-manager/index.css)
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -78,49 +78,6 @@
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 {
border: none;
box-shadow: none;

View File

@ -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/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/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/index.css (../shared/devtools/app-manager/index.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/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/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/index.css (../shared/devtools/app-manager/index.css)
skin/classic/aero/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)

View File

@ -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"
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.

View File

@ -1,6 +1,7 @@
[DEFAULT]
head = head_crtestutils.js
tail =
skip-if = toolkit == 'gonk'
support-files = data/**
[test_abi.js]

View File

@ -1,5 +1,6 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_resolve_uris_ipc.js]

View File

@ -641,6 +641,8 @@ endif
endif # NO_PROFILE_GUIDED_OPTIMIZE
MOZ_PROGRAM_LDFLAGS += $(MOZ_GLUE_PROGRAM_LDFLAGS)
##############################################
checkout:
@ -673,7 +675,7 @@ $(PROGRAM): $(PROGOBJS) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESF
$(REPORT_BUILD)
@$(RM) $@.manifest
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
@if test -f $@.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
endif
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,$@)
endif # WINNT && !GNU_CC
@ -742,7 +744,7 @@ endif
$(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
$(REPORT_BUILD)
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
@if test -f $@.manifest; then \
mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
@ -750,7 +752,7 @@ ifdef MSMANIFEST_TOOL
fi
endif # MSVC with manifest tool
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,$@)
endif # WINNT && !GNU_CC

View File

@ -1412,22 +1412,54 @@ if test "$GNU_CC"; then
fi
fi
# Turn on GNU-specific warnings:
# -Wall - turn on a lot of warnings
# -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
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement"
MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
MOZ_C_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_c_has_werror_int_to_pointer_cast)
MOZ_C_SUPPORTS_WARNING(-W, type-limits, ac_c_has_wtype_limits)
MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
MOZ_C_SUPPORTS_WARNING(-W, sign-compare, ac_c_has_sign_compare)
# -Wall - turn on a lot of warnings
# -Wchar-subscripts - catches array index using signed char
# -Wcomment - catches nested comments
# -Wdeclaration-after-statement - MSVC doesn't like these
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -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:
# -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.
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
# Turn on GNU-specific warnings:
# -Wall - turn on a lot of warnings
# -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
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
MOZ_CXX_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_cxx_has_werror_int_to_pointer_cast)
MOZ_CXX_SUPPORTS_WARNING(-W, error=type-limits, ac_cxx_has_werror_type_limits)
MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
MOZ_CXX_SUPPORTS_WARNING(-W, sign-compare, ac_cxx_has_sign_compare)
# -Wall - turn on a lot of warnings
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces
# -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:
# -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
# 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)
if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then

View File

@ -70,7 +70,7 @@ class ImportLoader MOZ_FINAL : public nsIStreamListener
class Updater {
public:
Updater(ImportLoader* aLoader) : mLoader(aLoader)
explicit Updater(ImportLoader* aLoader) : mLoader(aLoader)
{}
// After a new link is added that refers to this import, we

View File

@ -555,7 +555,7 @@ namespace {
struct PositionComparator
{
Element* const mElement;
PositionComparator(Element* const aElement) : mElement(aElement) {}
explicit PositionComparator(Element* const aElement) : mElement(aElement) {}
int operator()(void* aElement) const {
Element* curElement = static_cast<Element*>(aElement);
@ -2752,6 +2752,33 @@ AppendCSPFromHeader(nsIContentSecurityPolicy* csp,
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
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 (!applyAppDefaultCSP &&
!applyAppManifestCSP &&
!applyLoopCSP &&
cspHeaderValue.IsEmpty() &&
cspROHeaderValue.IsEmpty()) {
#ifdef PR_LOGGING
@ -2880,6 +2911,17 @@ nsDocument::InitCSP(nsIChannel* aChannel)
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 (!cspHeaderValue.IsEmpty()) {
rv = AppendCSPFromHeader(csp, cspHeaderValue, false);

View File

@ -1662,6 +1662,7 @@ private:
void DoUnblockOnload();
nsresult CheckFrameOptions();
bool IsLoopDocument(nsIChannel* aChannel);
nsresult InitCSP(nsIChannel* aChannel);
void FlushCSPWebConsoleErrorQueue()

View File

@ -1735,7 +1735,7 @@ public:
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
IPC::Principal(aPrincipal), aJSONRetVal);
}
return cc->CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
return cc->SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
IPC::Principal(aPrincipal), aJSONRetVal);
}

View File

@ -1873,7 +1873,7 @@ struct interval
struct CombiningComparator
{
const char16_t mUcs;
CombiningComparator(char16_t ucs) : mUcs(ucs) {}
explicit CombiningComparator(char16_t aUcs) : mUcs(aUcs) {}
int operator()(const interval& combining) const {
if (mUcs > combining.last)
return 1;

View File

@ -1,6 +1,7 @@
[DEFAULT]
head = head_utilities.js
tail =
skip-if = toolkit == 'gonk'
support-files =
1_original.xml
1_result.xml

View File

@ -1,6 +1,7 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_bug553888_wrap.js]
[test_xhr_document_ipc.js]

View File

@ -2244,7 +2244,7 @@ namespace {
struct PositionComparator
{
nsIContent* const mElement;
PositionComparator(nsIContent* const element) : mElement(element) {}
explicit PositionComparator(nsIContent* const aElement) : mElement(aElement) {}
int operator()(nsIContent* aElement) const {
if (mElement == aElement) {
@ -2260,7 +2260,7 @@ struct PositionComparator
struct NodeListAdaptor
{
nsINodeList* const mList;
NodeListAdaptor(nsINodeList* aList) : mList(aList) {}
explicit NodeListAdaptor(nsINodeList* aList) : mList(aList) {}
nsIContent* operator[](size_t aIdx) const {
return mList->Item(aIdx);
}

View File

@ -2478,8 +2478,8 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
// will take care of calling MediaDecoder::PlaybackEnded.
if (mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING &&
!mDecoder->GetDecodedStream()) {
int64_t videoTime = HasVideo() ? mVideoFrameEndTime : 0;
int64_t clockTime = std::max(mEndTime, videoTime);
int64_t clockTime = std::max(mAudioEndTime, mVideoFrameEndTime);
clockTime = std::max(int64_t(0), std::max(clockTime, mEndTime));
UpdatePlaybackPosition(clockTime);
{
@ -3143,7 +3143,13 @@ void MediaDecoderStateMachine::OnAudioSinkError()
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(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnDecodeError));
nsresult rv = mDecodeTaskQueue->Dispatch(task);

View File

@ -226,7 +226,7 @@ StealJSArrayDataIntoThreadSharedFloatArrayBufferList(JSContext* aJSContext,
? (uint8_t*) JS_StealArrayBufferContents(aJSContext, arrayBuffer)
: nullptr;
if (stolenData) {
result->SetData(i, stolenData, reinterpret_cast<float*>(stolenData));
result->SetData(i, stolenData, js_free, reinterpret_cast<float*>(stolenData));
} else {
return nullptr;
}

View File

@ -38,12 +38,16 @@ public:
}
struct Storage {
Storage()
{
mDataToFree = nullptr;
mSampleData = nullptr;
Storage() :
mDataToFree(nullptr),
mFree(nullptr),
mSampleData(nullptr)
{}
~Storage() {
if (mFree) {
mFree(mDataToFree);
} else { MOZ_ASSERT(!mDataToFree); }
}
~Storage() { free(mDataToFree); }
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
// NB: mSampleData might not be owned, if it is it just points to
@ -51,6 +55,7 @@ public:
return aMallocSizeOf(mDataToFree);
}
void* mDataToFree;
void (*mFree)(void*);
const float* mSampleData;
};
@ -67,11 +72,17 @@ public:
* Call this only during initialization, before the object is handed to
* 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];
free(s->mDataToFree);
if (s->mFree) {
s->mFree(s->mDataToFree);
} else {
MOZ_ASSERT(!s->mDataToFree);
}
s->mDataToFree = aDataToFree;
s->mFree = aFreeFunc;
s->mSampleData = aData;
}

View File

@ -258,7 +258,7 @@ ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv)
for (uint32_t i = 0; i < data->GetChannels(); ++i) {
PodCopy(channelData + length * i, data->GetData(i), 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;
}

View File

@ -38,9 +38,9 @@ PeriodicWave::PeriodicWave(AudioContext* aContext,
return;
}
PodCopy(buffer, aRealData, aLength);
mCoefficients->SetData(0, buffer, buffer);
mCoefficients->SetData(0, buffer, free, buffer);
PodCopy(buffer+aLength, aImagData, aLength);
mCoefficients->SetData(1, nullptr, buffer+aLength);
mCoefficients->SetData(1, nullptr, free, buffer+aLength);
}
size_t

View File

@ -17,7 +17,7 @@ struct RemoteVoice {
bool localService;
};
intr protocol PSpeechSynthesis
sync protocol PSpeechSynthesis
{
manager PContent;
manages PSpeechSynthesisRequest;

View File

@ -9,7 +9,7 @@ include protocol PSpeechSynthesis;
namespace mozilla {
namespace dom {
intr protocol PSpeechSynthesisRequest
async protocol PSpeechSynthesisRequest
{
manager PSpeechSynthesis;

View File

@ -1,6 +1,7 @@
[DEFAULT]
head = head_content.js
tail =
skip-if = toolkit == 'gonk'
support-files =
empty_document.xml
isequalnode_data.xml

View File

@ -1,6 +1,7 @@
[DEFAULT]
head = head_docshell.js
tail =
skip-if = toolkit == 'gonk'
[test_bug414201_jfif.js]
[test_bug442584.js]

View File

@ -1,6 +1,7 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_pb_notification_ipc.js]
# Bug 751575: Perma-fails with: command timed out: 1200 seconds without output

View File

@ -1,5 +1,6 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'gonk'
[test_activityFilters.js]

View File

@ -6,6 +6,7 @@
#include "URLSearchParams.h"
#include "mozilla/dom/URLSearchParamsBinding.h"
#include "mozilla/dom/EncodingUtils.h"
#include "nsDOMString.h"
namespace mozilla {
namespace dom {
@ -230,7 +231,7 @@ URLSearchParams::RemoveObservers()
void
URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
{
aRetval.Truncate();
SetDOMStringToNull(aRetval);
for (uint32_t i = 0, len = mSearchParams.Length(); i < len; ++i) {
if (mSearchParams[i].mKey.Equals(aName)) {

View File

@ -6,7 +6,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
-->
<head>
<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>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
@ -30,7 +30,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
var u = new URLSearchParams();
ok(u, "URLSearchParams created");
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)');
u.append('foo', 'bar');
@ -275,6 +275,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
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 = [
testSimpleURLSearchParams,
testCopyURLSearchParams,
@ -285,7 +298,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887836
testEncoding,
testMultiURL,
testOrdering,
testDelete
testDelete,
testGetNULL
];
function runTest() {

View File

@ -3091,18 +3091,11 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
{
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,
length,
mThebes,
mAppUnitsPerDevPixel,
flags);
direction==NSBIDI_RTL ? gfxTextRunFactory::TEXT_IS_RTL : 0);
}
virtual nscoord GetWidth()
@ -3128,14 +3121,10 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
virtual void DrawText(nscoord xOffset, nscoord width)
{
gfxPoint point = mPt;
bool rtl = mTextRun->IsRightToLeft();
bool verticalRun = mTextRun->IsVertical();
gfxFloat& inlineCoord = verticalRun ? point.y : point.x;
inlineCoord += xOffset;
point.x += xOffset;
// 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
// right-hand end of run, because this will cause different
// 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,
mThebes,
nullptr);
inlineCoord += textRunMetrics.mAdvanceWidth;
point.x += textRunMetrics.mAdvanceWidth;
// old code was:
// point.x += width * mAppUnitsPerDevPixel;
// TODO: restore this if/when we move to fractional coords
@ -3168,15 +3157,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
mCtx->EnsureTarget();
for (uint32_t c = 0; c < numRuns; c++) {
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;
if (c + 1 < numRuns) {
endRun = runs[c + 1].mCharacterOffset;
@ -3194,53 +3174,23 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
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();
GlyphBuffer buffer;
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++) {
Glyph newGlyph;
float& inlinePos =
verticalFont ? newGlyph.mPosition.y : newGlyph.mPosition.x;
float& blockPos =
verticalFont ? newGlyph.mPosition.x : newGlyph.mPosition.y;
if (glyphs[i].IsSimpleGlyph()) {
newGlyph.mIndex = glyphs[i].GetSimpleGlyph();
if (rtl) {
inlinePos = baselineOriginInline - advanceSum -
if (mTextRun->IsRightToLeft()) {
newGlyph.mPosition.x = baselineOrigin.x - advanceSum -
glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
} else {
inlinePos = baselineOriginInline + advanceSum;
newGlyph.mPosition.x = baselineOrigin.x + advanceSum;
}
blockPos = baselineOriginBlock;
newGlyph.mPosition.y = baselineOrigin.y;
advanceSum += glyphs[i].GetSimpleAdvance() * devUnitsPerAppUnit;
glyphBuf.push_back(newGlyph);
continue;
@ -3250,34 +3200,34 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
continue;
}
const gfxTextRun::DetailedGlyph *d = mTextRun->GetDetailedGlyphs(i);
gfxTextRun::DetailedGlyph *detailedGlyphs =
mTextRun->GetDetailedGlyphs(i);
if (glyphs[i].IsMissing()) {
newGlyph.mIndex = 0;
if (rtl) {
inlinePos = baselineOriginInline - advanceSum -
d->mAdvance * devUnitsPerAppUnit;
if (mTextRun->IsRightToLeft()) {
newGlyph.mPosition.x = baselineOrigin.x - advanceSum -
detailedGlyphs[0].mAdvance * devUnitsPerAppUnit;
} else {
inlinePos = baselineOriginInline + advanceSum;
newGlyph.mPosition.x = baselineOrigin.x + advanceSum;
}
blockPos = baselineOriginBlock;
advanceSum += d->mAdvance * devUnitsPerAppUnit;
newGlyph.mPosition.y = baselineOrigin.y;
advanceSum += detailedGlyphs[0].mAdvance * devUnitsPerAppUnit;
glyphBuf.push_back(newGlyph);
continue;
}
for (uint32_t c = 0; c < glyphs[i].GetGlyphCount(); c++, d++) {
newGlyph.mIndex = d->mGlyphID;
if (rtl) {
inlinePos = baselineOriginInline - advanceSum -
d->mAdvance * devUnitsPerAppUnit;
for (uint32_t c = 0; c < glyphs[i].GetGlyphCount(); c++) {
newGlyph.mIndex = detailedGlyphs[c].mGlyphID;
if (mTextRun->IsRightToLeft()) {
newGlyph.mPosition.x = baselineOrigin.x + detailedGlyphs[c].mXOffset * devUnitsPerAppUnit -
advanceSum - detailedGlyphs[c].mAdvance * devUnitsPerAppUnit;
} else {
inlinePos = baselineOriginInline + advanceSum;
newGlyph.mPosition.x = baselineOrigin.x + detailedGlyphs[c].mXOffset * devUnitsPerAppUnit + advanceSum;
}
inlinePos += d->mXOffset * devUnitsPerAppUnit;
blockPos = baselineOriginBlock + d->mYOffset * devUnitsPerAppUnit;
newGlyph.mPosition.y = baselineOrigin.y + detailedGlyphs[c].mYOffset * devUnitsPerAppUnit;
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
gfxRect mBoundingBox;
// flags to use when creating textrun, based on CSS style
uint32_t mTextRunFlags;
// true iff the bounding box should be measured
bool mDoMeasureBoundingBox;
};
@ -3394,10 +3341,9 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
// for now, default to ltr if not in doc
bool isRTL = false;
nsRefPtr<nsStyleContext> canvasStyle;
if (mCanvasElement && mCanvasElement->IsInDoc()) {
// try to find the closest context
canvasStyle =
nsRefPtr<nsStyleContext> canvasStyle =
nsComputedDOMStyle::GetStyleContextForElement(mCanvasElement,
nullptr,
presShell);
@ -3432,14 +3378,6 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
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);
processor.mPt = gfxPoint(aX, aY);
processor.mThebes =
@ -3506,9 +3444,7 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
// offset pt.y based on text baseline
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
const gfxFont::Metrics& fontMetrics =
processor.mFontgrp->GetFirstValidFont()->GetMetrics(
processor.mTextRun->IsVertical() ? gfxFont::eVertical :
gfxFont::eHorizontal);
processor.mFontgrp->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
gfxFloat anchorY;

View File

@ -153,16 +153,9 @@ WebGL2Context::TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat
GLsizei h = height;
for (size_t l = 0; l < size_t(levels); l++) {
for (size_t f = 0; f < facesCount; f++) {
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(target, f);
// FIXME: SetImageInfo wants a type, to go with the internalformat that it stores.
// 'type' is deprecated by sized internalformats, which are how TexStorage works.
// 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,
tex->SetImageInfo(TexImageTargetForTargetAndFace(target, f),
l, w, h,
internalformat,
WebGLImageDataStatus::UninitializedImageData);
}
w = std::max(1, w/2);

View File

@ -1760,6 +1760,13 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
GLenum internalformat, GLenum format, GLenum type,
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);
if (!video) {
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);
if (ok) {
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height, internalformat, type,
WebGLImageDataStatus::InitializedImageData);
TexInternalFormat effectiveinternalformat =
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));
}
srcImage = nullptr;

View File

@ -94,7 +94,7 @@ namespace gfx {
class SourceSurface;
}
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format, TexType type);
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
@ -490,9 +490,6 @@ public:
const TexImageTarget texImageTarget(rawTexImgTarget);
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
return;
if (level < 0)
return ErrorInvalidValue("texImage2D: level is negative");
@ -560,9 +557,6 @@ public:
const TexImageTarget texImageTarget(rawTexImageTarget);
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
return;
if (level < 0)
return ErrorInvalidValue("texSubImage2D: level is negative");
@ -575,7 +569,7 @@ public:
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
}
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
if (TexImageFromVideoElement(texImageTarget, level,
@ -1145,8 +1139,6 @@ protected:
GLsizei width, GLsizei height,
uint32_t byteLength, WebGLTexImageFunc func);
static uint32_t GetBitsPerTexel(TexInternalFormat format, TexType type);
void Invalidate();
void DestroyResourcesAndContext();
@ -1203,7 +1195,7 @@ protected:
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
GLenum internalformat,
TexInternalFormat internalformat,
GLint xoffset,
GLint yoffset,
GLint x,
@ -1363,7 +1355,7 @@ protected:
webgl.mColorWriteMask[3] != false;
}
ScopedMaskWorkaround(WebGLContext& webgl);
explicit ScopedMaskWorkaround(WebGLContext& aWebgl);
~ScopedMaskWorkaround();
};

View File

@ -676,7 +676,7 @@ WebGLContext::BindFakeBlackTexturesHelper(
}
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().InternalFormat());
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().EffectiveInternalFormat());
UniquePtr<FakeBlackTexture>&
blackTexturePtr = alpha
? transparentTextureScopedPtr

View File

@ -354,7 +354,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
void
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
GLenum internalformat,
TexInternalFormat internalformat,
GLint xoffset,
GLint yoffset,
GLint x,
@ -372,7 +372,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
// TODO: This changes with color_buffer_float. Reassess when the
// patch lands.
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
if (!ValidateTexImage(2, texImageTarget, level, internalformat.get(),
xoffset, yoffset, 0,
width, height, 0,
0,
@ -382,7 +382,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
return;
}
if (!ValidateCopyTexImage(internalformat, func))
if (!ValidateCopyTexImage(internalformat.get(), func))
return;
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 (sub)
gl->fCopyTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, x, y, width, height);
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 {
// the rect doesn't fit in the framebuffer
/*** first, we initialize the texture as black ***/
// first, compute the size of the buffer we should allocate to initialize the texture as black
if (!ValidateTexInputData(LOCAL_GL_UNSIGNED_BYTE, -1, func))
return;
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);
// first, we initialize the texture as black
if (!sub) {
tex->SetImageInfo(texImageTarget, level, width, height,
effectiveinternalformat,
WebGLImageDataStatus::UninitializedImageData);
tex->DoDeferredImageInitialization(texImageTarget, level);
}
// if we are completely outside of the framebuffer, we can exit now with our black texture
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);
}
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
@ -504,37 +518,7 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
if (!mBoundFramebuffer)
ClearBackbufferIfNeeded();
const TexImageTarget texImageTarget(rawTexImgTarget);
// 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);
CopyTexSubImage2D_base(rawTexImgTarget, level, internalformat, 0, 0, x, y, width, height, false);
}
void
@ -602,7 +586,11 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
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())
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))
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
@ -1183,12 +1171,17 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
const TexInternalFormat internalformat =
fba.Texture()->ImageInfoBase().InternalFormat();
return (internalformat == LOCAL_GL_SRGB ||
internalformat == LOCAL_GL_SRGB_ALPHA) ?
JS::NumberValue(uint32_t(LOCAL_GL_SRGB)) :
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
const TexInternalFormat effectiveinternalformat =
fba.Texture()->ImageInfoBase().EffectiveInternalFormat();
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
TexType type = LOCAL_GL_NONE;
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(
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;
@ -1224,9 +1217,10 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
if (!fba.IsComplete())
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
uint32_t ret = LOCAL_GL_NONE;
TexType type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
fba.MipLevel()).Type();
TexInternalFormat effectiveinternalformat =
fba.Texture()->ImageInfoAt(fba.ImageTarget(), fba.MipLevel()).EffectiveInternalFormat();
TexType type = TypeFromInternalFormat(effectiveinternalformat);
GLenum ret = LOCAL_GL_NONE;
switch (type.get()) {
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
@ -1235,7 +1229,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
ret = LOCAL_GL_UNSIGNED_NORMALIZED;
break;
case LOCAL_GL_FLOAT:
case LOCAL_GL_HALF_FLOAT_OES:
case LOCAL_GL_HALF_FLOAT:
ret = LOCAL_GL_FLOAT;
break;
case LOCAL_GL_UNSIGNED_SHORT:
@ -3353,7 +3347,7 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget,
MakeContextCurrent();
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);
}
@ -3387,7 +3381,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
MOZ_ASSERT(tex);
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");
}
@ -3599,7 +3593,7 @@ WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
GLint level,
TexInternalFormat internalFormat,
TexInternalFormat internalformat,
GLsizei width,
GLsizei height,
GLint border,
@ -3610,20 +3604,26 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex != nullptr, "no texture bound");
TexInternalFormat effectiveInternalFormat =
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
bool sizeMayChange = true;
if (tex->HasImageInfoAt(texImageTarget, level)) {
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
sizeMayChange = width != imageInfo.Width() ||
height != imageInfo.Height() ||
internalFormat != imageInfo.InternalFormat();
effectiveInternalFormat != imageInfo.EffectiveInternalFormat();
}
// 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 driverFormat = LOCAL_GL_NONE;
DriverFormatsFromFormatAndType(gl, internalFormat, type, &driverInternalFormat, &driverFormat);
DriverFormatsFromEffectiveInternalFormat(gl,
effectiveInternalFormat,
&driverInternalFormat,
&driverFormat,
&driverType);
if (sizeMayChange) {
GetAndFlushUnderlyingGLErrors();
@ -3652,6 +3652,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
{
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
if (type == LOCAL_GL_HALF_FLOAT_OES) {
type = LOCAL_GL_HALF_FLOAT;
}
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
0, 0, 0,
width, height, 0,
@ -3674,7 +3678,14 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
if (!ValidateTexInputData(type, jsArrayType, func))
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;
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
@ -3712,8 +3723,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::UninitializedImageData;
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();
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
size_t dstPlainRowSize = dstTexelSize * width;
size_t unpackAlignment = mPixelStoreUnpackAlignment;
size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
@ -3752,7 +3765,8 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
// have NoImageData at this point.
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, type, imageInfoStatusIfSuccess);
tex->SetImageInfo(texImageTarget, level, width, height,
effectiveinternalformat, imageInfoStatusIfSuccess);
}
void
@ -3830,14 +3844,28 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
{
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
if (type == LOCAL_GL_HALF_FLOAT_OES) {
type = LOCAL_GL_HALF_FLOAT;
}
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex) {
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,
width, height, 0,
0, format, type, func))
@ -3848,11 +3876,11 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
if (!ValidateTexInputData(type, jsArrayType, func))
return;
if (imageInfo.Type() != type) {
return ErrorInvalidOperation("texSubImage2D: type parameter does not match the existing image");
if (type != existingType) {
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;
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
@ -3882,7 +3910,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
MakeContextCurrent();
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;
// There are checks above to ensure that this won't overflow.
size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
@ -3906,10 +3934,14 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
pixels = reinterpret_cast<void*>(convertedData.get());
}
GLenum driverType = DriverTypeFromType(gl, type);
GLenum driverType = LOCAL_GL_NONE;
GLenum driverInternalFormat = 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);
}
@ -4066,119 +4098,37 @@ BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
}
WebGLTexelFormat mozilla::GetWebGLTexelFormat(TexInternalFormat internalformat, TexType type)
WebGLTexelFormat
mozilla::GetWebGLTexelFormat(TexInternalFormat effectiveinternalformat)
{
//
// WEBGL_depth_texture
if (internalformat == LOCAL_GL_DEPTH_COMPONENT) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_SHORT:
return WebGLTexelFormat::D16;
case LOCAL_GL_UNSIGNED_INT:
return WebGLTexelFormat::D32;
}
MOZ_CRASH("Invalid WebGL texture format/type?");
}
if (internalformat == LOCAL_GL_DEPTH_STENCIL) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_INT_24_8_EXT:
return WebGLTexelFormat::D24S8;
}
MOZ_CRASH("Invalid WebGL texture format/type?");
}
if (internalformat == LOCAL_GL_DEPTH_COMPONENT16) {
return WebGLTexelFormat::D16;
}
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;
switch (effectiveinternalformat.get()) {
case LOCAL_GL_DEPTH_COMPONENT16: return WebGLTexelFormat::D16;
case LOCAL_GL_DEPTH_COMPONENT24: return WebGLTexelFormat::D32;
case LOCAL_GL_DEPTH24_STENCIL8: return WebGLTexelFormat::D24S8;
case LOCAL_GL_RGBA8: return WebGLTexelFormat::RGBA8;
case LOCAL_GL_SRGB8_ALPHA8: return WebGLTexelFormat::RGBA8;
case LOCAL_GL_RGB8: return WebGLTexelFormat::RGB8;
case LOCAL_GL_SRGB8: return WebGLTexelFormat::RGB8;
case LOCAL_GL_ALPHA8: return WebGLTexelFormat::A8;
case LOCAL_GL_LUMINANCE8: return WebGLTexelFormat::R8;
case LOCAL_GL_LUMINANCE8_ALPHA8: return WebGLTexelFormat::RA8;
case LOCAL_GL_RGBA32F: return WebGLTexelFormat::RGBA32F;
case LOCAL_GL_RGB32F: return WebGLTexelFormat::RGB32F;
case LOCAL_GL_ALPHA32F_EXT: return WebGLTexelFormat::A32F;
case LOCAL_GL_LUMINANCE32F_EXT: return WebGLTexelFormat::R32F;
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT: return WebGLTexelFormat::RA32F;
case LOCAL_GL_RGBA16F: return WebGLTexelFormat::RGBA16F;
case LOCAL_GL_RGB16F: return WebGLTexelFormat::RGB16F;
case LOCAL_GL_ALPHA16F_EXT: return WebGLTexelFormat::A16F;
case LOCAL_GL_LUMINANCE16F_EXT: return WebGLTexelFormat::R16F;
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT: return WebGLTexelFormat::RA16F;
case LOCAL_GL_RGBA4: return WebGLTexelFormat::RGBA4444;
case LOCAL_GL_RGB5_A1: return WebGLTexelFormat::RGBA5551;
case LOCAL_GL_RGB565: return WebGLTexelFormat::RGB565;
default:
MOZ_ASSERT(false, "Coding mistake?! Should never reach this point.");
MOZ_CRASH("Unhandled format");
return WebGLTexelFormat::BadFormat;
}
MOZ_CRASH("Invalid WebGL texture format/type?");
}
void

View File

@ -31,29 +31,28 @@ namespace mozilla {
using namespace gl;
bool
IsGLDepthFormat(TexInternalFormat webGLFormat)
IsGLDepthFormat(TexInternalFormat internalformat)
{
return (webGLFormat == LOCAL_GL_DEPTH_COMPONENT ||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT32);
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
return unsizedformat == LOCAL_GL_DEPTH_COMPONENT;
}
bool
IsGLDepthStencilFormat(TexInternalFormat webGLFormat)
IsGLDepthStencilFormat(TexInternalFormat internalformat)
{
return (webGLFormat == LOCAL_GL_DEPTH_STENCIL ||
webGLFormat == LOCAL_GL_DEPTH24_STENCIL8);
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
return unsizedformat == LOCAL_GL_DEPTH_STENCIL;
}
bool
FormatHasAlpha(TexInternalFormat webGLFormat)
FormatHasAlpha(TexInternalFormat internalformat)
{
return webGLFormat == LOCAL_GL_RGBA ||
webGLFormat == LOCAL_GL_LUMINANCE_ALPHA ||
webGLFormat == LOCAL_GL_ALPHA ||
webGLFormat == LOCAL_GL_RGBA4 ||
webGLFormat == LOCAL_GL_RGB5_A1 ||
webGLFormat == LOCAL_GL_SRGB_ALPHA;
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
return unsizedformat == LOCAL_GL_RGBA ||
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
unsizedformat == LOCAL_GL_ALPHA ||
unsizedformat == LOCAL_GL_SRGB_ALPHA ||
unsizedformat == LOCAL_GL_RGBA_INTEGER;
}
TexTarget
@ -76,11 +75,12 @@ TexImageTargetToTexTarget(TexImageTarget texImageTarget)
}
}
GLComponents::GLComponents(TexInternalFormat format)
GLComponents::GLComponents(TexInternalFormat internalformat)
{
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
mComponents = 0;
switch (format.get()) {
switch (unsizedformat.get()) {
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA4:
case LOCAL_GL_RGBA8:
@ -117,152 +117,277 @@ GLComponents::IsSubsetOf(const GLComponents& other) const
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
* format valid for underlying driver.
* Convert effective internalformat into GL function parameters
* valid for underlying driver.
*/
void
DriverFormatsFromFormatAndType(GLContext* gl, TexInternalFormat webGLInternalFormat, TexType webGLType,
GLenum* out_driverInternalFormat, GLenum* out_driverFormat)
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
TexInternalFormat effectiveinternalformat,
GLenum* out_driverInternalFormat,
GLenum* out_driverFormat,
GLenum* out_driverType)
{
MOZ_ASSERT(out_driverInternalFormat);
MOZ_ASSERT(out_driverFormat);
MOZ_ASSERT(out_driverType);
// ES2 requires that format == internalformat; floating-point is
// indicated purely by the type that's loaded. For desktop GL, we
// have to specify a floating point internal format.
if (gl->IsGLES()) {
*out_driverFormat = *out_driverInternalFormat = webGLInternalFormat.get();
return;
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
TexType type = LOCAL_GL_NONE;
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(effectiveinternalformat,
&unsizedinternalformat, &type);
// 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;
GLenum format = LOCAL_GL_NONE;
// driverFormat: always just the unsized internalformat that we just got
GLenum driverFormat = unsizedinternalformat.get();
if (webGLInternalFormat == LOCAL_GL_DEPTH_COMPONENT) {
format = LOCAL_GL_DEPTH_COMPONENT;
if (webGLType == LOCAL_GL_UNSIGNED_SHORT)
internalFormat = LOCAL_GL_DEPTH_COMPONENT16;
else if (webGLType == LOCAL_GL_UNSIGNED_INT)
internalFormat = LOCAL_GL_DEPTH_COMPONENT32;
} else if (webGLInternalFormat == LOCAL_GL_DEPTH_STENCIL) {
format = LOCAL_GL_DEPTH_STENCIL;
if (webGLType == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
} 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;
// driverInternalFormat: almost always the same as driverFormat, but on desktop GL,
// in some cases we must pass a different value. On ES, they are equal by definition
// as it is an error to pass internalformat!=format.
GLenum driverInternalFormat = driverFormat;
if (!gl->IsGLES()) {
// Cases where desktop OpenGL requires a tweak to 'format'
if (driverFormat == LOCAL_GL_SRGB) {
driverFormat = LOCAL_GL_RGB;
} else if (driverFormat == LOCAL_GL_SRGB_ALPHA) {
driverFormat = LOCAL_GL_RGBA;
}
// Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
// requires that format == internalformat, but GL will fail in this case.
// GL requires:
// format -> internalformat
// GL_RGB GL_SRGB_EXT
// GL_RGBA GL_SRGB_ALPHA_EXT
switch (webGLInternalFormat.get()) {
case LOCAL_GL_SRGB:
format = LOCAL_GL_RGB;
internalFormat = LOCAL_GL_SRGB;
break;
case LOCAL_GL_SRGB_ALPHA:
format = LOCAL_GL_RGBA;
internalFormat = LOCAL_GL_SRGB_ALPHA;
break;
// Cases where desktop OpenGL requires a sized internalformat,
// as opposed to the unsized internalformat that had the same
// GLenum value as 'format', in order to get the precise
// semantics that we want. For example, for floating-point formats,
// we seem to need a sized internalformat to get non-clamped floating
// point texture sampling. Can't find the spec reference for that,
// but that's at least the case on my NVIDIA driver version 331.
if (unsizedinternalformat == LOCAL_GL_DEPTH_COMPONENT ||
unsizedinternalformat == LOCAL_GL_DEPTH_STENCIL ||
type == LOCAL_GL_FLOAT ||
type == LOCAL_GL_HALF_FLOAT)
{
driverInternalFormat = effectiveinternalformat.get();
}
}
MOZ_ASSERT(webGLInternalFormat != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
"Coding mistake -- bad format/type passed?");
*out_driverInternalFormat = internalFormat;
*out_driverFormat = format;
*out_driverInternalFormat = driverInternalFormat;
*out_driverFormat = driverFormat;
*out_driverType = driverType;
}
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())
return type;
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;
// convert type for half float if not on GLES2
if (type == LOCAL_GL_HALF_FLOAT_OES) {
if (gl->IsSupported(gl::GLFeature::texture_half_float)) {
return LOCAL_GL_HALF_FLOAT;
} else {
MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float));
}
case LOCAL_GL_ALPHA8:
case LOCAL_GL_LUMINANCE8:
case LOCAL_GL_R8:
case LOCAL_GL_R8I:
case LOCAL_GL_R8UI:
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

View File

@ -16,9 +16,28 @@ namespace mozilla {
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
bool FormatHasAlpha(TexInternalFormat webGLFormat);
void DriverFormatsFromFormatAndType(gl::GLContext* gl, TexInternalFormat webGLFormat, TexType webGLType,
GLenum* out_driverInternalFormat, GLenum* out_driverFormat);
GLenum DriverTypeFromType(gl::GLContext* gl, TexType webGLType);
void
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
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.
// TexImage2D, CopyTex[Sub]Image2D, ...

View File

@ -673,7 +673,7 @@ WebGLContext::ValidateTexImageType(GLenum type,
}
/* 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);
if (!validType)
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 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.
* 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:
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
type == LOCAL_GL_HALF_FLOAT ||
type == LOCAL_GL_HALF_FLOAT_OES ||
type == LOCAL_GL_FLOAT);
break;
@ -1150,7 +1060,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
type == LOCAL_GL_HALF_FLOAT ||
type == LOCAL_GL_HALF_FLOAT_OES ||
type == LOCAL_GL_FLOAT);
break;
@ -1160,7 +1069,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
type == LOCAL_GL_HALF_FLOAT ||
type == LOCAL_GL_HALF_FLOAT_OES ||
type == LOCAL_GL_FLOAT);
break;
@ -1291,7 +1199,6 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
break;
case LOCAL_GL_HALF_FLOAT:
case LOCAL_GL_HALF_FLOAT_OES:
case LOCAL_GL_UNSIGNED_SHORT:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
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);
if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
width, height, depth,
imageInfo.Width(), imageInfo.Height(), 0,

View File

@ -79,7 +79,7 @@ WebGLFramebuffer::Attachment::HasAlpha() const
MOZ_ASSERT(HasImage());
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat());
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat());
else if (Renderbuffer())
return FormatHasAlpha(Renderbuffer()->InternalFormat());
else return false;
@ -96,7 +96,7 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
return imgInfo.InternalFormat().get();
return imgInfo.EffectiveInternalFormat().get();
}
if (attachment.Renderbuffer())
@ -105,37 +105,30 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
return LOCAL_GL_NONE;
}
bool
WebGLFramebuffer::Attachment::IsReadableFloat() const
TexInternalFormat
WebGLFramebuffer::Attachment::EffectiveInternalFormat() const
{
const WebGLTexture* tex = Texture();
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).Type().get();
switch (type) {
case LOCAL_GL_FLOAT:
case LOCAL_GL_HALF_FLOAT_OES:
return true;
}
return false;
return tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat();
}
const WebGLRenderbuffer* rb = Renderbuffer();
if (rb) {
GLenum format = rb->InternalFormat();
switch (format) {
case LOCAL_GL_RGB16F:
case LOCAL_GL_RGBA16F:
case LOCAL_GL_RGB32F:
case LOCAL_GL_RGBA32F:
return true;
}
return false;
return rb->InternalFormat();
}
// If we arrive here Attachment isn't correct setup because it has
// no texture nor render buffer pointer.
MOZ_ASSERT(false, "Should not get here.");
return false;
return LOCAL_GL_NONE;
}
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
@ -230,7 +223,7 @@ WebGLFramebuffer::Attachment::RectangleObject() const
corresponds to the state that is stored in
WebGLTexture::ImageInfo::InternalFormat()*/
static inline bool
IsValidFBOTextureColorFormat(GLenum internalFormat)
IsValidFBOTextureColorFormat(TexInternalFormat internalformat)
{
/* These formats are internal formats for each texture -- the actual
* 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.
*/
return (
/* linear 8-bit formats */
internalFormat == LOCAL_GL_ALPHA ||
internalFormat == LOCAL_GL_LUMINANCE ||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA ||
internalFormat == LOCAL_GL_RGB ||
internalFormat == LOCAL_GL_RGBA ||
/* sRGB 8-bit formats */
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
);
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
return unsizedformat == LOCAL_GL_ALPHA ||
unsizedformat == LOCAL_GL_LUMINANCE ||
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
unsizedformat == LOCAL_GL_RGB ||
unsizedformat == LOCAL_GL_RGBA ||
unsizedformat == LOCAL_GL_SRGB ||
unsizedformat == LOCAL_GL_SRGB_ALPHA;
}
static inline bool
IsValidFBOTextureDepthFormat(GLenum internalFormat)
IsValidFBOTextureDepthFormat(GLenum internalformat)
{
return (
internalFormat == LOCAL_GL_DEPTH_COMPONENT ||
internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
internalFormat == LOCAL_GL_DEPTH_COMPONENT32);
return IsGLDepthFormat(internalformat);
}
static inline bool
IsValidFBOTextureDepthStencilFormat(GLenum internalFormat)
IsValidFBOTextureDepthStencilFormat(GLenum internalformat)
{
return (
internalFormat == LOCAL_GL_DEPTH_STENCIL ||
internalFormat == LOCAL_GL_DEPTH24_STENCIL8);
return IsGLDepthStencilFormat(internalformat);
}
/* The following IsValidFBORenderbufferXXX functions check the internal
@ -330,7 +303,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
const WebGLTexture::ImageInfo& imageInfo =
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
GLenum internalformat = imageInfo.InternalFormat().get();
GLenum internalformat = imageInfo.EffectiveInternalFormat().get();
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
return IsValidFBOTextureDepthFormat(internalformat);

View File

@ -53,6 +53,8 @@ public:
bool IsDeleteRequested() const;
TexInternalFormat EffectiveInternalFormat() const;
bool HasAlpha() const;
bool IsReadableFloat() const;

View File

@ -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

View File

@ -299,6 +299,9 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
STRONG_GLENUM_VALUE(RGBA),
STRONG_GLENUM_VALUE(LUMINANCE),
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(RGBA4),
STRONG_GLENUM_VALUE(RGB5_A1),
@ -332,8 +335,14 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
STRONG_GLENUM_VALUE(RGBA32F),
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(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(COMPRESSED_RGB_PVRTC_4BPPV1),
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_2BPPV1),

View File

@ -52,7 +52,7 @@ int64_t
WebGLTexture::ImageInfo::MemoryUsage() const {
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
return 0;
int64_t bitsPerTexel = WebGLContext::GetBitsPerTexel(mInternalFormat, mType);
int64_t bitsPerTexel = GetBitsPerTexel(mEffectiveInternalFormat);
return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8;
}
@ -138,8 +138,7 @@ WebGLTexture::Bind(TexTarget aTexTarget) {
void
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
TexInternalFormat aInternalFormat, TexType aType,
WebGLImageDataStatus aStatus)
TexInternalFormat aEffectiveInternalFormat, WebGLImageDataStatus aStatus)
{
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
if (TexImageTargetToTexTarget(aTexImageTarget) != mTarget)
@ -147,7 +146,7 @@ WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aInternalFormat, aType, aStatus);
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aEffectiveInternalFormat, aStatus);
if (aLevel > 0)
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))
{
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);
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))
{
if (mMinFilter == LOCAL_GL_LINEAR ||
@ -534,13 +535,11 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
mContext->MakeContextCurrent();
// Try to clear with glCLear.
TexInternalFormat internalformat = imageInfo.mInternalFormat;
TexType type = imageInfo.mType;
WebGLTexelFormat texelformat = GetWebGLTexelFormat(internalformat, type);
bool cleared = ClearWithTempFB(mContext, GLName(),
imageTarget, level,
internalformat, imageInfo.mHeight, imageInfo.mWidth);
imageInfo.mEffectiveInternalFormat,
imageInfo.mHeight, imageInfo.mWidth);
if (cleared) {
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
return;
@ -549,22 +548,26 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
// That didn't work. Try uploading zeros then.
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
= WebGLContext::GetImageSize(
imageInfo.mHeight,
imageInfo.mWidth,
texelsize,
bytespertexel,
mContext->mPixelStoreUnpackAlignment);
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
ScopedFreePtr<void> zeros;
zeros = calloc(1, checked_byteLength.value());
gl::GLContext* gl = mContext->gl;
GLenum driverType = DriverTypeFromType(gl, type);
GLenum driverInternalFormat = 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();
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,

View File

@ -67,19 +67,16 @@ public:
{
public:
ImageInfo()
: mInternalFormat(LOCAL_GL_NONE)
, mType(LOCAL_GL_NONE)
: mEffectiveInternalFormat(LOCAL_GL_NONE)
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
{}
ImageInfo(GLsizei width,
GLsizei height,
TexInternalFormat internalFormat,
TexType type,
TexInternalFormat effectiveInternalFormat,
WebGLImageDataStatus status)
: WebGLRectangleObject(width, height)
, mInternalFormat(internalFormat)
, mType(type)
, mEffectiveInternalFormat(effectiveInternalFormat)
, mImageDataStatus(status)
{
// shouldn't use this constructor to construct a null ImageInfo
@ -90,8 +87,7 @@ public:
return mImageDataStatus == a.mImageDataStatus &&
mWidth == a.mWidth &&
mHeight == a.mHeight &&
mInternalFormat == a.mInternalFormat &&
mType == a.mType;
mEffectiveInternalFormat == a.mEffectiveInternalFormat;
}
bool operator!=(const ImageInfo& a) const {
return !(*this == a);
@ -110,21 +106,17 @@ public:
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
}
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.
* It can be converted to a value to be passed to driver with
* DriverTypeFromType().
*/
TexType Type() const { return mType; }
TexInternalFormat EffectiveInternalFormat() const { return mEffectiveInternalFormat; }
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;
friend class WebGLTexture;
@ -230,8 +222,7 @@ public:
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
TexInternalFormat aInternalFormat, TexType aType,
WebGLImageDataStatus aStatus);
TexInternalFormat aFormat, WebGLImageDataStatus aStatus);
void SetMinFilter(TexMinFilter aMinFilter) {
mMinFilter = aMinFilter;

View File

@ -32,7 +32,7 @@ public:
NS_DECL_ISUPPORTS
NS_FORWARD_SAFE_NSICELLBROADCASTLISTENER(mCellBroadcast)
Listener(CellBroadcast* aCellBroadcast)
explicit Listener(CellBroadcast* aCellBroadcast)
: mCellBroadcast(aCellBroadcast)
{
MOZ_ASSERT(mCellBroadcast);

View File

@ -1,6 +1,7 @@
[DEFAULT]
head = head.js
tail =
skip-if = toolkit == 'gonk'
[test_misc.js]
[test_utf.js]

View File

@ -27,7 +27,7 @@ class Response MOZ_FINAL : public nsISupports
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
public:
Response(nsISupports* aOwner);
explicit Response(nsISupports* aOwner);
JSObject*
WrapObject(JSContext* aCx)

View File

@ -115,6 +115,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_blob_worker_crash.html]
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]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_bug937006.html]

View File

@ -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>

View File

@ -6,6 +6,7 @@
dupe-manifest =
head = xpcshell-head-child-process.js
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
GlobalObjectsChild.js
GlobalObjectsComponent.js

View File

@ -6,6 +6,7 @@
dupe-manifest =
head = xpcshell-head-parent-process.js
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
GlobalObjectsChild.js
GlobalObjectsComponent.js

View File

@ -1,6 +1,8 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT]
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_add_put.js]
[test_add_twice_failure.js]

View File

@ -329,7 +329,7 @@ class RemoteInputStream MOZ_FINAL
public:
NS_DECL_THREADSAFE_ISUPPORTS
RemoteInputStream(DOMFileImpl* aBlobImpl)
explicit RemoteInputStream(DOMFileImpl* aBlobImpl)
: mMonitor("RemoteInputStream.mMonitor")
, mBlobImpl(aBlobImpl)
, mWeakSeekableStream(nullptr)
@ -359,17 +359,19 @@ public:
Serialize(InputStreamParams& aParams,
FileDescriptorArray& /* aFileDescriptors */)
{
MOZ_RELEASE_ASSERT(mBlobImpl);
nsCOMPtr<nsIRemoteBlob> remote = do_QueryInterface(mBlobImpl);
MOZ_ASSERT(remote);
MOZ_ASSERT(remote->GetBlobChild());
aParams = RemoteInputStreamParams(
nullptr /* sourceParent */,
remote->GetBlobChild() /* sourceChild */);
BlobChild* actor = remote->GetBlobChild();
MOZ_ASSERT(actor);
aParams = RemoteInputStreamParams(actor->ParentID());
}
bool
Deserialize(const InputStreamParams& aParams,
Deserialize(const InputStreamParams& /* aParams */,
const FileDescriptorArray& /* aFileDescriptors */)
{
// See InputStreamUtils.cpp to see how deserialization of a
@ -419,15 +421,48 @@ public:
NS_IMETHOD
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;
}
nsresult rv = BlockAndWaitForStream();
NS_ENSURE_SUCCESS(rv, rv);
// Otherwise fake it...
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);
return NS_OK;
@ -690,7 +725,8 @@ public:
aProcessID,
aBlobImpl,
/* aMayCreate */ true,
/* aMayGet */ false);
/* aMayGet */ false,
/* aIgnoreProcessID */ false);
}
static already_AddRefed<IDTableEntry>
@ -700,7 +736,19 @@ public:
aProcessID,
nullptr,
/* 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>
@ -716,7 +764,8 @@ public:
aProcessID,
aBlobImpl,
/* aMayCreate */ true,
/* aMayGet */ true);
/* aMayGet */ true,
/* aIgnoreProcessID */ false);
}
const nsID&
@ -748,7 +797,8 @@ private:
intptr_t aProcessID,
DOMFileImpl* aBlobImpl,
bool aMayCreate,
bool aMayGet);
bool aMayGet,
bool aIgnoreProcessID);
};
// 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);
}
// 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
template <class ParentManagerType>
BlobParent*
@ -3550,7 +3620,8 @@ IDTableEntry::GetOrCreateInternal(const nsID& aID,
intptr_t aProcessID,
DOMFileImpl* aBlobImpl,
bool aMayCreate,
bool aMayGet)
bool aMayGet,
bool aIgnoreProcessID)
{
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
MOZ_ASSERT(sIDTableMutex);
@ -3578,7 +3649,7 @@ IDTableEntry::GetOrCreateInternal(const nsID& aID,
return nullptr;
}
if (NS_WARN_IF(entry->mProcessID != aProcessID)) {
if (!aIgnoreProcessID && NS_WARN_IF(entry->mProcessID != aProcessID)) {
return nullptr;
}
} else {

View File

@ -107,6 +107,9 @@ public:
delete static_cast<BlobParent*>(aActor);
}
static already_AddRefed<DOMFileImpl>
GetBlobImplForID(const nsID& aID);
bool
HasManager() const
{

View File

@ -3517,14 +3517,14 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
}
bool
ContentParent::AnswerRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
ContentParent::RecvRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
return nsIContentParent::AnswerRpcMessage(aMsg, aData, aCpows, aPrincipal,
aRetvals);
return nsIContentParent::RecvRpcMessage(aMsg, aData, aCpows, aPrincipal,
aRetvals);
}
bool

Some files were not shown because too many files have changed in this diff Show More