mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
Merge mozilla-central to autoland
This commit is contained in:
commit
5b47cb2e80
@ -1042,7 +1042,6 @@ toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > #downloads-
|
||||
|
||||
/* Combobox dropdown renderer */
|
||||
#ContentSelectDropdown > menupopup {
|
||||
max-height: 350px;
|
||||
/* The menupopup itself should always be rendered LTR to ensure the scrollbar aligns with
|
||||
* the dropdown arrow on the dropdown widget. If a menuitem is RTL, its style will be set accordingly */
|
||||
direction: ltr;
|
||||
|
@ -7452,7 +7452,7 @@ var gRemoteTabsUI = {
|
||||
* passed via this object.
|
||||
* This object also allows:
|
||||
* - 'ignoreFragment' property to be set to true to exclude fragment-portion
|
||||
* matching when comparing URIs.
|
||||
* matching when comparing URIs. Fragment will be replaced.
|
||||
* - 'ignoreQueryString' property to be set to true to exclude query string
|
||||
* matching when comparing URIs.
|
||||
* - 'replaceQueryString' property to be set to true to exclude query string
|
||||
@ -7488,31 +7488,41 @@ function switchToTabHavingURI(aURI, aOpenNew, aOpenParams={}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Remove the query string, fragment, both, or neither from a given url.
|
||||
function cleanURL(url, removeQuery, removeFragment) {
|
||||
let ret = url;
|
||||
if (removeFragment) {
|
||||
ret = ret.split("#")[0];
|
||||
if (removeQuery) {
|
||||
// This removes a query, if present before the fragment.
|
||||
ret = ret.split("?")[0];
|
||||
}
|
||||
} else if (removeQuery) {
|
||||
// This is needed in case there is a fragment after the query.
|
||||
let fragment = ret.split("#")[1];
|
||||
ret = ret.split("?")[0].concat(
|
||||
(fragment != undefined) ? "#".concat(fragment) : "");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Need to handle nsSimpleURIs here too (e.g. about:...), which don't
|
||||
// work correctly with URL objects - so treat them as strings
|
||||
let requestedCompare = cleanURL(
|
||||
aURI.spec, ignoreQueryString || replaceQueryString, ignoreFragment);
|
||||
let browsers = aWindow.gBrowser.browsers;
|
||||
for (let i = 0; i < browsers.length; i++) {
|
||||
let browser = browsers[i];
|
||||
if (ignoreFragment ? browser.currentURI.equalsExceptRef(aURI) :
|
||||
browser.currentURI.equals(aURI)) {
|
||||
// Focus the matching window & tab
|
||||
let browserCompare = cleanURL(
|
||||
browser.currentURI.spec, ignoreQueryString || replaceQueryString, ignoreFragment);
|
||||
if (requestedCompare == browserCompare) {
|
||||
aWindow.focus();
|
||||
if (ignoreFragment) {
|
||||
let spec = aURI.spec;
|
||||
browser.loadURI(spec);
|
||||
if (ignoreFragment || replaceQueryString) {
|
||||
browser.loadURI(aURI.spec);
|
||||
}
|
||||
aWindow.gBrowser.tabContainer.selectedIndex = i;
|
||||
return true;
|
||||
}
|
||||
if (ignoreQueryString || replaceQueryString) {
|
||||
if (browser.currentURI.spec.split("?")[0] == aURI.spec.split("?")[0]) {
|
||||
// Focus the matching window & tab
|
||||
aWindow.focus();
|
||||
if (replaceQueryString) {
|
||||
browser.loadURI(aURI.spec);
|
||||
}
|
||||
aWindow.gBrowser.tabContainer.selectedIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -223,8 +223,9 @@ nsContextMenu.prototype = {
|
||||
this.showItem("context-sendvideo", this.onVideo);
|
||||
this.showItem("context-castvideo", this.onVideo);
|
||||
this.showItem("context-sendaudio", this.onAudio);
|
||||
this.setItemAttr("context-sendvideo", "disabled", !this.mediaURL);
|
||||
this.setItemAttr("context-sendaudio", "disabled", !this.mediaURL);
|
||||
let mediaIsBlob = this.mediaURL.startsWith("blob:");
|
||||
this.setItemAttr("context-sendvideo", "disabled", !this.mediaURL || mediaIsBlob);
|
||||
this.setItemAttr("context-sendaudio", "disabled", !this.mediaURL || mediaIsBlob);
|
||||
let shouldShowCast = Services.prefs.getBoolPref("browser.casting.enabled");
|
||||
// getServicesForVideo alone would be sufficient here (it depends on
|
||||
// SimpleServiceDiscovery.services), but SimpleServiceDiscovery is guaranteed
|
||||
@ -382,7 +383,7 @@ nsContextMenu.prototype = {
|
||||
this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink);
|
||||
this.showItem("context-shareimage", shareEnabled && this.onImage);
|
||||
this.showItem("context-sharevideo", shareEnabled && this.onVideo);
|
||||
this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL);
|
||||
this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL || this.mediaURL.startsWith("blob:"));
|
||||
},
|
||||
|
||||
initSpellingItems: function() {
|
||||
@ -1641,7 +1642,10 @@ nsContextMenu.prototype = {
|
||||
},
|
||||
|
||||
isMediaURLReusable: function(aURL) {
|
||||
return !/^(?:blob|mediasource):/.test(aURL);
|
||||
if (aURL.startsWith("blob:")) {
|
||||
return URL.isValidURL(aURL);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
|
@ -368,6 +368,7 @@ add_task(function* test_large_popup() {
|
||||
select.add(new content.Option("Test" + i));
|
||||
}
|
||||
|
||||
select.options[60].selected = true;
|
||||
select.focus();
|
||||
});
|
||||
|
||||
@ -388,6 +389,16 @@ add_task(function* test_large_popup() {
|
||||
ok(rect.top >= browserRect.top, "Popup top position in within browser area");
|
||||
ok(rect.bottom <= browserRect.bottom, "Popup bottom position in within browser area");
|
||||
|
||||
// Don't check the scroll position for the last step as the popup will be cut off.
|
||||
if (positions.length == 1) {
|
||||
let cs = window.getComputedStyle(selectPopup);
|
||||
let bpBottom = parseFloat(cs.paddingBottom) + parseFloat(cs.borderBottomWidth);
|
||||
|
||||
is(selectPopup.childNodes[60].getBoundingClientRect().bottom,
|
||||
selectPopup.getBoundingClientRect().bottom - bpBottom,
|
||||
"Popup scroll at correct position " + bpBottom);
|
||||
}
|
||||
|
||||
yield hideSelectPopup(selectPopup, false);
|
||||
|
||||
position = positions.shift();
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
add_task(function test_ignoreFragment() {
|
||||
add_task(function *test_ignoreFragment() {
|
||||
let tabRefAboutHome = gBrowser.addTab("about:home#1");
|
||||
yield promiseTabLoaded(tabRefAboutHome);
|
||||
let tabRefAboutMozilla = gBrowser.addTab("about:mozilla");
|
||||
@ -35,7 +35,7 @@ add_task(function test_ignoreFragment() {
|
||||
cleanupTestTabs();
|
||||
});
|
||||
|
||||
add_task(function test_ignoreQueryString() {
|
||||
add_task(function* test_ignoreQueryString() {
|
||||
let tabRefAboutHome = gBrowser.addTab("about:home?hello=firefox");
|
||||
yield promiseTabLoaded(tabRefAboutHome);
|
||||
let tabRefAboutMozilla = gBrowser.addTab("about:mozilla");
|
||||
@ -52,7 +52,7 @@ add_task(function test_ignoreQueryString() {
|
||||
cleanupTestTabs();
|
||||
});
|
||||
|
||||
add_task(function test_replaceQueryString() {
|
||||
add_task(function* test_replaceQueryString() {
|
||||
let tabRefAboutHome = gBrowser.addTab("about:home?hello=firefox");
|
||||
yield promiseTabLoaded(tabRefAboutHome);
|
||||
let tabRefAboutMozilla = gBrowser.addTab("about:mozilla");
|
||||
@ -72,6 +72,38 @@ add_task(function test_replaceQueryString() {
|
||||
cleanupTestTabs();
|
||||
});
|
||||
|
||||
add_task(function* test_replaceQueryStringAndFragment() {
|
||||
let tabRefAboutHome = gBrowser.addTab("about:home?hello=firefox#aaa");
|
||||
yield promiseTabLoaded(tabRefAboutHome);
|
||||
let tabRefAboutMozilla = gBrowser.addTab("about:mozilla?hello=firefoxos#aaa");
|
||||
yield promiseTabLoaded(tabRefAboutMozilla);
|
||||
gBrowser.selectedTab = tabRefAboutMozilla;
|
||||
|
||||
switchTab("about:home", false);
|
||||
gBrowser.removeCurrentTab();
|
||||
switchTab("about:home?hello=firefox#aaa", true);
|
||||
is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
|
||||
switchTab("about:mozilla?hello=firefox#bbb", true, { replaceQueryString: true, ignoreFragment: true });
|
||||
is(tabRefAboutMozilla, gBrowser.selectedTab, "Selected tab should be the initial about:mozilla tab");
|
||||
switchTab("about:home?hello=firefoxos#bbb", true, { ignoreQueryString: true, ignoreFragment: true });
|
||||
is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
|
||||
cleanupTestTabs();
|
||||
});
|
||||
|
||||
add_task(function* test_ignoreQueryStringIgnoresFragment() {
|
||||
let tabRefAboutHome = gBrowser.addTab("about:home?hello=firefox#aaa");
|
||||
yield promiseTabLoaded(tabRefAboutHome);
|
||||
let tabRefAboutMozilla = gBrowser.addTab("about:mozilla?hello=firefoxos#aaa");
|
||||
yield promiseTabLoaded(tabRefAboutMozilla);
|
||||
gBrowser.selectedTab = tabRefAboutMozilla;
|
||||
|
||||
switchTab("about:home?hello=firefox#bbb", false, { ignoreQueryString: true });
|
||||
gBrowser.removeCurrentTab();
|
||||
switchTab("about:home?hello=firefoxos#aaa", true, { ignoreQueryString: true });
|
||||
is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
|
||||
cleanupTestTabs();
|
||||
});
|
||||
|
||||
// Begin helpers
|
||||
|
||||
function cleanupTestTabs() {
|
||||
|
@ -627,7 +627,7 @@ function openPreferences(paneID, extraArgs)
|
||||
win = Services.ww.openWindow(null, Services.prefs.getCharPref("browser.chromeURL"),
|
||||
"_blank", "chrome,dialog=no,all", windowArguments);
|
||||
} else {
|
||||
newLoad = !win.switchToTabHavingURI(preferencesURL, true, {ignoreFragment: true});
|
||||
newLoad = !win.switchToTabHavingURI(preferencesURL, true, { ignoreFragment: true, replaceQueryString: true });
|
||||
browser = win.gBrowser.selectedBrowser;
|
||||
}
|
||||
|
||||
|
@ -140,12 +140,24 @@ toolbarbutton.bookmark-item:not(.subviewbutton):not(:hover):not(:active):not([op
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:not(.subviewbutton) {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
transition-property: background-color, border-color;
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([open]) {
|
||||
background-color: var(--toolbarbutton-hover-background);
|
||||
border-color: var(--toolbarbutton-hover-bordercolor);
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:not(.subviewbutton):hover:active,
|
||||
toolbarbutton.bookmark-item[open="true"] {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 1px;
|
||||
padding-inline-start: 4px;
|
||||
padding-inline-end: 2px;
|
||||
background: var(--toolbarbutton-active-background);
|
||||
box-shadow: var(--toolbarbutton-active-boxshadow);
|
||||
border-color: var(--toolbarbutton-active-bordercolor);
|
||||
}
|
||||
|
||||
.bookmark-item > .toolbarbutton-icon,
|
||||
@ -1670,7 +1682,7 @@ toolbarbutton.chevron {
|
||||
list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
|
||||
}
|
||||
|
||||
toolbar[brighttext] toolbarbutton.chevron:not(:hover):not([open="true"]) {
|
||||
toolbar[brighttext] toolbarbutton.chevron {
|
||||
list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important;
|
||||
}
|
||||
|
||||
|
@ -464,14 +464,20 @@ toolbarbutton.bookmark-item:not(.subviewbutton),
|
||||
#personal-bookmarks[cui-areatype="toolbar"]:not([overflowedItem=true]) > #bookmarks-toolbar-placeholder {
|
||||
margin: 0;
|
||||
padding: 2px 3px;
|
||||
-moz-appearance: none;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:not([disabled="true"]):not(.subviewbutton):hover:active,
|
||||
toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not([open]) {
|
||||
border-color: var(--toolbarbutton-hover-bordercolor);
|
||||
background: var(--toolbarbutton-hover-background);
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:not(.subviewbutton):hover:active:not([disabled="true"]),
|
||||
toolbarbutton.bookmark-item[open="true"] {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 1px;
|
||||
padding-inline-start: 4px;
|
||||
padding-inline-end: 2px;
|
||||
border-color: var(--toolbarbutton-active-bordercolor);
|
||||
box-shadow: var(--toolbarbutton-active-boxshadow);
|
||||
background: var(--toolbarbutton-active-background);
|
||||
}
|
||||
|
||||
.bookmark-item > .toolbarbutton-icon,
|
||||
|
@ -1,7 +1,16 @@
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#aaa">
|
||||
<path fill-opacity=".3" d="M6.6 8.4c0-.6-1.7.3-1.7-.3 0-.4-1.7-2.7-1.7-2.7H13s-1.8 2-1.8 2.7c0 .3-2.1-.1-2.1.3v6.1H7s-.4-4.1-.4-6.1z"/>
|
||||
<path d="M2 2v2.3L4.7 9H6v5.4l2.1 1 1.8-.9V9h1.3L14 4.3V2H2zm11 2l-2.2 4H9v5.8l-.9.4-1.1-.5V8H5.2L3 4V3h10v1z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#0b0b0b">
|
||||
<style>
|
||||
/* Use a fill that's visible on both light and dark themes for filter inputs */
|
||||
#filterinput:target + #icon {
|
||||
fill: #aaa;
|
||||
}
|
||||
</style>
|
||||
<g id="filterinput"/>
|
||||
<g id="icon">
|
||||
<path fill-opacity=".3" d="M6.6 8.4c0-.6-1.7.3-1.7-.3 0-.4-1.7-2.7-1.7-2.7H13s-1.8 2-1.8 2.7c0 .3-2.1-.1-2.1.3v6.1H7s-.4-4.1-.4-6.1z"/>
|
||||
<path d="M2 2v2.3L4.7 9H6v5.4l2.1 1 1.8-.9V9h1.3L14 4.3V2H2zm11 2l-2.2 4H9v5.8l-.9.4-1.1-.5V8H5.2L3 4V3h10v1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 785 B |
@ -364,7 +364,7 @@
|
||||
}
|
||||
|
||||
.devtools-filterinput {
|
||||
background-image: var(--filter-image);
|
||||
background-image: url(images/filter.svg#filterinput);
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl),
|
||||
|
113
dom/base/CustomElementsRegistry.cpp
Normal file
113
dom/base/CustomElementsRegistry.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/CustomElementsRegistry.h"
|
||||
#include "mozilla/dom/CustomElementsRegistryBinding.h"
|
||||
#include "mozilla/dom/WebComponentsBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
||||
// Only needed for refcounted objects.
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CustomElementsRegistry, mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomElementsRegistry)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomElementsRegistry)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomElementsRegistry)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/* static */ bool
|
||||
CustomElementsRegistry::IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
if (Preferences::GetBool("dom.webcomponents.customelements.enabled") ||
|
||||
nsDocument::IsWebComponentsEnabled(aCx, obj)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<CustomElementsRegistry>
|
||||
CustomElementsRegistry::Create(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aWindow->IsInnerWindow());
|
||||
|
||||
if (!aWindow->GetDocShell()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> customElementsRegistry =
|
||||
new CustomElementsRegistry(aWindow);
|
||||
return customElementsRegistry.forget();
|
||||
}
|
||||
|
||||
CustomElementsRegistry::CustomElementsRegistry(nsPIDOMWindowInner* aWindow)
|
||||
: mWindow(aWindow)
|
||||
{
|
||||
}
|
||||
|
||||
CustomElementsRegistry::~CustomElementsRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
CustomElementsRegistry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return CustomElementsRegistryBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* CustomElementsRegistry::GetParentObject() const
|
||||
{
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
void CustomElementsRegistry::Define(const nsAString& aName,
|
||||
Function& aFunctionConstructor,
|
||||
const ElementDefinitionOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// TODO: This function will be implemented in bug 1275835
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::Get(JSContext* aCx, const nsAString& aName,
|
||||
JS::MutableHandle<JS::Value> aRetVal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// TODO: This function will be implemented in bug 1275838
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
CustomElementsRegistry::WhenDefined(const nsAString& name, ErrorResult& aRv)
|
||||
{
|
||||
// TODO: This function will be implemented in bug 1275839
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomElementDefinition::CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder)
|
||||
: mPrototype(aPrototype),
|
||||
mType(aType),
|
||||
mLocalName(aLocalName),
|
||||
mCallbacks(aCallbacks),
|
||||
mNamespaceID(aNamespaceID),
|
||||
mDocOrder(aDocOrder)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
136
dom/base/CustomElementsRegistry.h
Normal file
136
dom/base/CustomElementsRegistry.h
Normal file
@ -0,0 +1,136 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_CustomElementsRegistry_h
|
||||
#define mozilla_dom_CustomElementsRegistry_h
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct ElementDefinitionOptions;
|
||||
struct LifecycleCallbacks;
|
||||
class Function;
|
||||
class Promise;
|
||||
|
||||
class CustomElementHashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef CustomElementHashKey *KeyType;
|
||||
typedef const CustomElementHashKey *KeyTypePointer;
|
||||
|
||||
CustomElementHashKey(int32_t aNamespaceID, nsIAtom *aAtom)
|
||||
: mNamespaceID(aNamespaceID),
|
||||
mAtom(aAtom)
|
||||
{}
|
||||
explicit CustomElementHashKey(const CustomElementHashKey* aKey)
|
||||
: mNamespaceID(aKey->mNamespaceID),
|
||||
mAtom(aKey->mAtom)
|
||||
{}
|
||||
~CustomElementHashKey()
|
||||
{}
|
||||
|
||||
KeyType GetKey() const { return const_cast<KeyType>(this); }
|
||||
bool KeyEquals(const KeyTypePointer aKey) const
|
||||
{
|
||||
MOZ_ASSERT(mNamespaceID != kNameSpaceID_Unknown,
|
||||
"This equals method is not transitive, nor symmetric. "
|
||||
"A key with a namespace of kNamespaceID_Unknown should "
|
||||
"not be stored in a hashtable.");
|
||||
return (kNameSpaceID_Unknown == aKey->mNamespaceID ||
|
||||
mNamespaceID == aKey->mNamespaceID) &&
|
||||
aKey->mAtom == mAtom;
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(const KeyTypePointer aKey)
|
||||
{
|
||||
return aKey->mAtom->hash();
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
private:
|
||||
int32_t mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mAtom;
|
||||
};
|
||||
|
||||
// The required information for a custom element as defined in:
|
||||
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
|
||||
struct CustomElementDefinition
|
||||
{
|
||||
CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
mozilla::dom::LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder);
|
||||
|
||||
// The prototype to use for new custom elements of this type.
|
||||
JS::Heap<JSObject *> mPrototype;
|
||||
|
||||
// The type (name) for this custom element.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
|
||||
// The localname to (e.g. <button is=type> -- this would be button).
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
|
||||
// The lifecycle callbacks to call for this custom element.
|
||||
nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
|
||||
|
||||
// Whether we're currently calling the created callback for a custom element
|
||||
// of this type.
|
||||
bool mElementIsBeingCreated;
|
||||
|
||||
// Element namespace.
|
||||
int32_t mNamespaceID;
|
||||
|
||||
// The document custom element order.
|
||||
uint32_t mDocOrder;
|
||||
};
|
||||
|
||||
class CustomElementsRegistry final : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementsRegistry)
|
||||
|
||||
public:
|
||||
static bool IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject);
|
||||
static already_AddRefed<CustomElementsRegistry> Create(nsPIDOMWindowInner* aWindow);
|
||||
already_AddRefed<nsIDocument> GetOwnerDocument() const;
|
||||
|
||||
private:
|
||||
explicit CustomElementsRegistry(nsPIDOMWindowInner* aWindow);
|
||||
~CustomElementsRegistry();
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
|
||||
public:
|
||||
nsISupports* GetParentObject() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void Define(const nsAString& aName, Function& aFunctionConstructor,
|
||||
const ElementDefinitionOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
void Get(JSContext* cx, const nsAString& name,
|
||||
JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> WhenDefined(const nsAString& name, ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // mozilla_dom_CustomElementsRegistry_h
|
@ -560,7 +560,7 @@ File::Constructor(const GlobalObject& aGlobal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
aRv.ThrowTypeError<MSG_NOT_SEQUENCE>(NS_LITERAL_STRING("Argument 1 of File.constructor"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,7 @@ EXPORTS.mozilla.dom += [
|
||||
'ChromeNodeList.h',
|
||||
'ChromeUtils.h',
|
||||
'Comment.h',
|
||||
'CustomElementsRegistry.h',
|
||||
'DirectionalityUtils.h',
|
||||
'DocumentFragment.h',
|
||||
'DocumentType.h',
|
||||
@ -216,6 +217,7 @@ UNIFIED_SOURCES += [
|
||||
'ChromeUtils.cpp',
|
||||
'Comment.cpp',
|
||||
'Crypto.cpp',
|
||||
'CustomElementsRegistry.cpp',
|
||||
'DirectionalityUtils.cpp',
|
||||
'DocumentFragment.cpp',
|
||||
'DocumentType.cpp',
|
||||
|
@ -30,6 +30,7 @@
|
||||
#ifdef MOZ_FMP4
|
||||
#include "MP4Decoder.h"
|
||||
#endif
|
||||
#include "CubebUtils.h"
|
||||
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
||||
@ -2326,6 +2327,13 @@ nsDOMWindowUtils::GetSupportsHardwareH264Decoding(JS::MutableHandle<JS::Value> a
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend)
|
||||
{
|
||||
CubebUtils::GetCurrentBackend(aBackend);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
|
||||
{
|
||||
|
@ -469,21 +469,6 @@ CustomElementCallback::CustomElementCallback(Element* aThisObject,
|
||||
{
|
||||
}
|
||||
|
||||
CustomElementDefinition::CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder)
|
||||
: mPrototype(aPrototype),
|
||||
mType(aType),
|
||||
mLocalName(aLocalName),
|
||||
mCallbacks(aCallbacks),
|
||||
mNamespaceID(aNamespaceID),
|
||||
mDocOrder(aDocOrder)
|
||||
{
|
||||
}
|
||||
|
||||
CustomElementData::CustomElementData(nsIAtom* aType)
|
||||
: mType(aType),
|
||||
mCurrentCallback(-1),
|
||||
@ -4768,7 +4753,8 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
}
|
||||
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled") ||
|
||||
Preferences::GetBool("dom.webcomponents.customelements.enabled")) {
|
||||
mRegistry = new Registry();
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "jsfriendapi.h"
|
||||
#include "ImportManager.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "CustomElementsRegistry.h"
|
||||
|
||||
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
|
||||
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
|
||||
@ -132,7 +133,7 @@ public:
|
||||
* and 'id' mappings of a given string. This is so that
|
||||
* nsHTMLDocument::ResolveName only has to do one hash lookup instead
|
||||
* of two. It's not clear whether this still matters for performance.
|
||||
*
|
||||
*
|
||||
* We also store the document.all result list here. This is mainly so that
|
||||
* when all elements with the given ID are removed and we remove
|
||||
* the ID's nsIdentifierMapEntry, the document.all result is released too.
|
||||
@ -263,48 +264,6 @@ private:
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CustomElementHashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef CustomElementHashKey *KeyType;
|
||||
typedef const CustomElementHashKey *KeyTypePointer;
|
||||
|
||||
CustomElementHashKey(int32_t aNamespaceID, nsIAtom *aAtom)
|
||||
: mNamespaceID(aNamespaceID),
|
||||
mAtom(aAtom)
|
||||
{}
|
||||
explicit CustomElementHashKey(const CustomElementHashKey* aKey)
|
||||
: mNamespaceID(aKey->mNamespaceID),
|
||||
mAtom(aKey->mAtom)
|
||||
{}
|
||||
~CustomElementHashKey()
|
||||
{}
|
||||
|
||||
KeyType GetKey() const { return const_cast<KeyType>(this); }
|
||||
bool KeyEquals(const KeyTypePointer aKey) const
|
||||
{
|
||||
MOZ_ASSERT(mNamespaceID != kNameSpaceID_Unknown,
|
||||
"This equals method is not transitive, nor symmetric. "
|
||||
"A key with a namespace of kNamespaceID_Unknown should "
|
||||
"not be stored in a hashtable.");
|
||||
return (kNameSpaceID_Unknown == aKey->mNamespaceID ||
|
||||
mNamespaceID == aKey->mNamespaceID) &&
|
||||
aKey->mAtom == mAtom;
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(const KeyTypePointer aKey)
|
||||
{
|
||||
return aKey->mAtom->hash();
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
private:
|
||||
int32_t mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mAtom;
|
||||
};
|
||||
|
||||
struct LifecycleCallbackArgs
|
||||
{
|
||||
nsString name;
|
||||
@ -376,40 +335,6 @@ private:
|
||||
virtual ~CustomElementData() {}
|
||||
};
|
||||
|
||||
// The required information for a custom element as defined in:
|
||||
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
|
||||
struct CustomElementDefinition
|
||||
{
|
||||
CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
mozilla::dom::LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder);
|
||||
|
||||
// The prototype to use for new custom elements of this type.
|
||||
JS::Heap<JSObject *> mPrototype;
|
||||
|
||||
// The type (name) for this custom element.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
|
||||
// The localname to (e.g. <button is=type> -- this would be button).
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
|
||||
// The lifecycle callbacks to call for this custom element.
|
||||
nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
|
||||
|
||||
// Whether we're currently calling the created callback for a custom element
|
||||
// of this type.
|
||||
bool mElementIsBeingCreated;
|
||||
|
||||
// Element namespace.
|
||||
int32_t mNamespaceID;
|
||||
|
||||
// The document custom element order.
|
||||
uint32_t mDocOrder;
|
||||
};
|
||||
|
||||
class Registry : public nsISupports
|
||||
{
|
||||
public:
|
||||
@ -616,7 +541,7 @@ protected:
|
||||
// don't hand out references to the docshell. The shims should all allow
|
||||
// getInterface back on us, but other than that each one should only
|
||||
// implement one interface.
|
||||
|
||||
|
||||
// XXXbz I wish we could just derive the _allcaps thing from _i
|
||||
#define DECL_SHIM(_i, _allcaps) \
|
||||
class _i##Shim final : public nsIInterfaceRequestor, \
|
||||
@ -655,7 +580,7 @@ protected:
|
||||
nsresult AddExternalResource(nsIURI* aURI, nsIContentViewer* aViewer,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
nsIDocument* aDisplayDocument);
|
||||
|
||||
|
||||
nsClassHashtable<nsURIHashKey, ExternalResource> mMap;
|
||||
nsRefPtrHashtable<nsURIHashKey, PendingLoad> mPendingLoads;
|
||||
bool mHaveShutDown;
|
||||
|
@ -1565,6 +1565,7 @@ nsGlobalWindow::CleanUp()
|
||||
mScrollbars = nullptr;
|
||||
mLocation = nullptr;
|
||||
mHistory = nullptr;
|
||||
mCustomElements = nullptr;
|
||||
mFrames = nullptr;
|
||||
mWindowUtils = nullptr;
|
||||
mApplicationCache = nullptr;
|
||||
@ -1695,6 +1696,7 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
|
||||
mLocation = nullptr;
|
||||
mHistory = nullptr;
|
||||
mCustomElements = nullptr;
|
||||
|
||||
if (mNavigator) {
|
||||
mNavigator->OnNavigation();
|
||||
@ -1877,6 +1879,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHistory)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCustomElements)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStorage)
|
||||
@ -1950,6 +1953,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)
|
||||
if (tmp->mApplicationCache) {
|
||||
@ -3832,6 +3836,17 @@ nsGlobalWindow::GetHistory(ErrorResult& aError)
|
||||
return mHistory;
|
||||
}
|
||||
|
||||
CustomElementsRegistry*
|
||||
nsGlobalWindow::CustomElements()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
if (!mCustomElements) {
|
||||
mCustomElements = CustomElementsRegistry::Create(AsInner());
|
||||
}
|
||||
|
||||
return mCustomElements;
|
||||
}
|
||||
|
||||
Performance*
|
||||
nsPIDOMWindowInner::GetPerformance()
|
||||
{
|
||||
|
@ -106,6 +106,7 @@ class BarProp;
|
||||
struct ChannelPixelLayout;
|
||||
class Console;
|
||||
class Crypto;
|
||||
class CustomElementsRegistry;
|
||||
class External;
|
||||
class Function;
|
||||
class Gamepad;
|
||||
@ -205,7 +206,6 @@ public:
|
||||
// stack depth at which timeout is firing
|
||||
uint32_t mFiringDepth;
|
||||
|
||||
//
|
||||
uint32_t mNestingLevel;
|
||||
|
||||
// The popup state at timeout creation time if not created from
|
||||
@ -878,6 +878,7 @@ public:
|
||||
nsLocation* GetLocation(mozilla::ErrorResult& aError);
|
||||
nsIDOMLocation* GetLocation() override;
|
||||
nsHistory* GetHistory(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::CustomElementsRegistry* CustomElements() override;
|
||||
mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::BarProp* GetPersonalbar(mozilla::ErrorResult& aError);
|
||||
@ -1838,6 +1839,7 @@ protected:
|
||||
uint32_t mTimeoutFiringDepth;
|
||||
RefPtr<nsLocation> mLocation;
|
||||
RefPtr<nsHistory> mHistory;
|
||||
RefPtr<mozilla::dom::CustomElementsRegistry> mCustomElements;
|
||||
|
||||
// These member variables are used on both inner and the outer windows.
|
||||
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
|
||||
|
@ -576,6 +576,12 @@ nsHostObjectProtocolHandler::RemoveDataEntries()
|
||||
gDataTable = nullptr;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsHostObjectProtocolHandler::HasDataEntry(const nsACString& aUri)
|
||||
{
|
||||
return !!GetDataInfo(aUri);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHostObjectProtocolHandler::GenerateURIString(const nsACString &aScheme,
|
||||
nsIPrincipal* aPrincipal,
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
// This is for IPC only.
|
||||
static void RemoveDataEntries();
|
||||
|
||||
static bool HasDataEntry(const nsACString& aUri);
|
||||
|
||||
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
|
||||
static void Traverse(const nsACString& aUri, nsCycleCollectionTraversalCallback& aCallback);
|
||||
|
||||
|
@ -44,6 +44,7 @@ class AudioContext;
|
||||
class Element;
|
||||
class Performance;
|
||||
class ServiceWorkerRegistration;
|
||||
class CustomElementsRegistry;
|
||||
} // namespace dom
|
||||
namespace gfx {
|
||||
class VRDeviceProxy;
|
||||
@ -96,7 +97,7 @@ public:
|
||||
const nsPIDOMWindowOuter* AsOuter() const;
|
||||
|
||||
virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
|
||||
|
||||
virtual mozilla::dom::CustomElementsRegistry* CustomElements() = 0;
|
||||
// Outer windows only.
|
||||
virtual void ActivateOrDeactivate(bool aActivate) = 0;
|
||||
|
||||
@ -321,7 +322,7 @@ public:
|
||||
{
|
||||
return mMayHavePaintEventListener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this to indicate that some node (this window, its document,
|
||||
* or content in that document) has a touch event listener.
|
||||
|
@ -87,6 +87,13 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptLoadRequest)
|
||||
nsScriptLoadRequest::~nsScriptLoadRequest()
|
||||
{
|
||||
js_free(mScriptTextBuf);
|
||||
|
||||
// We should always clean up any off-thread script parsing resources.
|
||||
MOZ_ASSERT(!mOffThreadToken);
|
||||
|
||||
// But play it safe in release builds and try to clean them up here
|
||||
// as a fail safe.
|
||||
MaybeCancelOffThreadScript();
|
||||
}
|
||||
|
||||
void
|
||||
@ -96,6 +103,27 @@ nsScriptLoadRequest::SetReady()
|
||||
mProgress = Progress::Ready;
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptLoadRequest::Cancel()
|
||||
{
|
||||
MaybeCancelOffThreadScript();
|
||||
mIsCanceled = true;
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptLoadRequest::MaybeCancelOffThreadScript()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mOffThreadToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext* cx = JS_GetContext(xpc::GetJSRuntime());
|
||||
JS::CancelOffThreadScript(cx, mOffThreadToken);
|
||||
mOffThreadToken = nullptr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// nsModuleLoadRequest
|
||||
//////////////////////////////////////////////////////////////
|
||||
@ -1829,9 +1857,7 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
// (disappearing window, some other error, ...). Finish the
|
||||
// request to avoid leaks in the JS engine.
|
||||
MOZ_ASSERT(!aRequest->IsModuleRequest());
|
||||
JSContext* cx = JS_GetContext(xpc::GetJSRuntime());
|
||||
JS::CancelOffThreadScript(cx, aRequest->mOffThreadToken);
|
||||
aRequest->mOffThreadToken = nullptr;
|
||||
aRequest->MaybeCancelOffThreadScript();
|
||||
}
|
||||
|
||||
// Free any source data.
|
||||
|
@ -118,10 +118,7 @@ public:
|
||||
return mElement == nullptr;
|
||||
}
|
||||
|
||||
virtual void Cancel()
|
||||
{
|
||||
mIsCanceled = true;
|
||||
}
|
||||
virtual void Cancel();
|
||||
|
||||
bool IsCanceled() const
|
||||
{
|
||||
@ -152,6 +149,8 @@ public:
|
||||
(IsReadyToRun() && mWasCompiledOMT);
|
||||
}
|
||||
|
||||
void MaybeCancelOffThreadScript();
|
||||
|
||||
using super::getNext;
|
||||
using super::isInList;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef _CANVASUTILS_H_
|
||||
#define _CANVASUTILS_H_
|
||||
|
||||
#include "CanvasRenderingContextHelper.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -7,11 +7,11 @@
|
||||
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLTexelConversions.h"
|
||||
#include "WebGLTexture.h"
|
||||
@ -131,6 +131,12 @@ FormatForPackingInfo(const PackingInfo& pi)
|
||||
|
||||
////////////////////
|
||||
|
||||
static uint32_t
|
||||
ZeroOn2D(TexImageTarget target, uint32_t val)
|
||||
{
|
||||
return (IsTarget3D(target) ? val : 0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
FallbackOnZero(uint32_t val, uint32_t fallback)
|
||||
{
|
||||
@ -142,27 +148,31 @@ TexUnpackBlob::TexUnpackBlob(const WebGLContext* webgl, TexImageTarget target,
|
||||
uint32_t depth, bool isSrcPremult)
|
||||
: mAlignment(webgl->mPixelStore_UnpackAlignment)
|
||||
, mRowLength(rowLength)
|
||||
, mImageHeight(FallbackOnZero(webgl->mPixelStore_UnpackImageHeight, height))
|
||||
, mImageHeight(FallbackOnZero(ZeroOn2D(target,
|
||||
webgl->mPixelStore_UnpackImageHeight),
|
||||
height))
|
||||
|
||||
, mSkipPixels(webgl->mPixelStore_UnpackSkipPixels)
|
||||
, mSkipRows(webgl->mPixelStore_UnpackSkipRows)
|
||||
, mSkipImages(IsTarget3D(target) ? webgl->mPixelStore_UnpackSkipImages : 0)
|
||||
, mSkipImages(ZeroOn2D(target, webgl->mPixelStore_UnpackSkipImages))
|
||||
|
||||
, mWidth(width)
|
||||
, mHeight(height)
|
||||
, mDepth(depth)
|
||||
|
||||
, mIsSrcPremult(isSrcPremult)
|
||||
|
||||
, mNeedsExactUpload(false)
|
||||
{
|
||||
MOZ_ASSERT_IF(!IsTarget3D(target), mDepth == 1);
|
||||
}
|
||||
|
||||
bool
|
||||
TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
|
||||
const void* srcBytes, uint32_t srcStride, uint8_t srcBPP,
|
||||
WebGLTexelFormat srcFormat,
|
||||
const uint8_t* srcBytes, uint32_t srcStride,
|
||||
uint8_t srcBPP, WebGLTexelFormat srcFormat,
|
||||
const webgl::DriverUnpackInfo* dstDUI,
|
||||
const void** const out_bytes,
|
||||
const uint8_t** const out_bytes,
|
||||
UniqueBuffer* const out_anchoredBuffer) const
|
||||
{
|
||||
*out_bytes = srcBytes;
|
||||
@ -181,7 +191,7 @@ TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
|
||||
}
|
||||
const uint32_t skipBytes = offset.value();
|
||||
|
||||
auto const srcBegin = (const uint8_t*)srcBytes + skipBytes;
|
||||
auto const srcBegin = srcBytes + skipBytes;
|
||||
|
||||
//////
|
||||
|
||||
@ -237,13 +247,15 @@ TexUnpackBlob::ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
|
||||
// We need some sort of conversion, so create the dest buffer.
|
||||
|
||||
*out_anchoredBuffer = calloc(1, dstSize.value());
|
||||
*out_bytes = out_anchoredBuffer->get();
|
||||
if (!*out_bytes) {
|
||||
const auto dstBytes = (uint8_t*)out_anchoredBuffer->get();
|
||||
|
||||
if (!dstBytes) {
|
||||
webgl->ErrorOutOfMemory("%s: Unable to allocate buffer during conversion.",
|
||||
funcName);
|
||||
return false;
|
||||
}
|
||||
const auto dstBegin = (uint8_t*)(*out_bytes) + skipBytes;
|
||||
*out_bytes = dstBytes;
|
||||
const auto dstBegin = dstBytes + skipBytes;
|
||||
|
||||
//////
|
||||
// Row conversion
|
||||
@ -319,11 +331,12 @@ DoTexOrSubImage(bool isSubImage, gl::GLContext* gl, TexImageTarget target, GLint
|
||||
|
||||
TexUnpackBytes::TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target,
|
||||
uint32_t width, uint32_t height, uint32_t depth,
|
||||
const void* bytes)
|
||||
bool isClientData, const uint8_t* ptr)
|
||||
: TexUnpackBlob(webgl, target,
|
||||
FallbackOnZero(webgl->mPixelStore_UnpackRowLength, width), width,
|
||||
height, depth, false)
|
||||
, mBytes(bytes)
|
||||
, mIsClientData(isClientData)
|
||||
, mPtr(ptr)
|
||||
{ }
|
||||
|
||||
bool
|
||||
@ -345,16 +358,99 @@ TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
|
||||
|
||||
const auto format = FormatForPackingInfo(pi);
|
||||
|
||||
const void* uploadBytes;
|
||||
auto uploadPtr = mPtr;
|
||||
UniqueBuffer tempBuffer;
|
||||
if (!ConvertIfNeeded(webgl, funcName, mBytes, rowStride.value(), bytesPerPixel,
|
||||
format, dui, &uploadBytes, &tempBuffer))
|
||||
if (mIsClientData &&
|
||||
!ConvertIfNeeded(webgl, funcName, mPtr, rowStride.value(), bytesPerPixel, format,
|
||||
dui, &uploadPtr, &tempBuffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*out_error = DoTexOrSubImage(isSubImage, webgl->gl, target, level, dui, xOffset,
|
||||
yOffset, zOffset, mWidth, mHeight, mDepth, uploadBytes);
|
||||
const auto& gl = webgl->gl;
|
||||
|
||||
//////
|
||||
|
||||
bool useParanoidHandling = false;
|
||||
if (mNeedsExactUpload && webgl->mBoundPixelUnpackBuffer) {
|
||||
webgl->GenerateWarning("%s: Uploads from a buffer with a final row with a byte"
|
||||
" count smaller than the row stride can incur extra"
|
||||
" overhead.",
|
||||
funcName);
|
||||
|
||||
if (gl->WorkAroundDriverBugs()) {
|
||||
useParanoidHandling |= (gl->Vendor() == gl::GLVendor::NVIDIA);
|
||||
}
|
||||
}
|
||||
|
||||
if (!useParanoidHandling) {
|
||||
*out_error = DoTexOrSubImage(isSubImage, gl, target, level, dui, xOffset, yOffset,
|
||||
zOffset, mWidth, mHeight, mDepth, uploadPtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
MOZ_ASSERT(webgl->mBoundPixelUnpackBuffer);
|
||||
|
||||
if (!isSubImage) {
|
||||
// Alloc first to catch OOMs.
|
||||
gl->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
*out_error = DoTexOrSubImage(false, gl, target, level, dui, xOffset, yOffset,
|
||||
zOffset, mWidth, mHeight, mDepth, nullptr);
|
||||
gl->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
|
||||
webgl->mBoundPixelUnpackBuffer->mGLName);
|
||||
if (*out_error)
|
||||
return false;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
// Make our sometimes-implicit values explicit. Also this keeps them constant when we
|
||||
// ask for height=mHeight-1 and such.
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, mRowLength);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, mImageHeight);
|
||||
|
||||
if (mDepth > 1) {
|
||||
*out_error = DoTexOrSubImage(true, gl, target, level, dui, xOffset, yOffset,
|
||||
zOffset, mWidth, mHeight, mDepth-1, uploadPtr);
|
||||
}
|
||||
|
||||
// Skip the images we uploaded.
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, mSkipImages + mDepth - 1);
|
||||
|
||||
if (mHeight > 1) {
|
||||
*out_error = DoTexOrSubImage(true, gl, target, level, dui, xOffset, yOffset,
|
||||
zOffset+mDepth-1, mWidth, mHeight-1, 1, uploadPtr);
|
||||
}
|
||||
|
||||
const auto totalSkipRows = CheckedUint32(mSkipImages) * mImageHeight + mSkipRows;
|
||||
const auto totalFullRows = CheckedUint32(mDepth - 1) * mImageHeight + mHeight - 1;
|
||||
const auto tailOffsetRows = totalSkipRows + totalFullRows;
|
||||
|
||||
const auto tailOffsetBytes = tailOffsetRows * rowStride;
|
||||
|
||||
uploadPtr += tailOffsetBytes.value();
|
||||
|
||||
//////
|
||||
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); // No stride padding.
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0); // No padding in general.
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, 0); // Don't skip images,
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, 0); // or rows.
|
||||
// Keep skipping pixels though!
|
||||
|
||||
*out_error = DoTexOrSubImage(true, gl, target, level, dui, xOffset,
|
||||
yOffset+mHeight-1, zOffset+mDepth-1, mWidth, 1, 1,
|
||||
uploadPtr);
|
||||
|
||||
// Reset all our modified state.
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, webgl->mPixelStore_UnpackAlignment);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, webgl->mPixelStore_UnpackImageHeight);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, webgl->mPixelStore_UnpackRowLength);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, webgl->mPixelStore_UnpackSkipImages);
|
||||
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, webgl->mPixelStore_UnpackSkipRows);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -370,6 +466,9 @@ TexUnpackImage::TexUnpackImage(const WebGLContext* webgl, TexImageTarget target,
|
||||
, mImage(image)
|
||||
{ }
|
||||
|
||||
TexUnpackImage::~TexUnpackImage()
|
||||
{ }
|
||||
|
||||
bool
|
||||
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
@ -440,9 +539,9 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
|
||||
" upload.",
|
||||
funcName);
|
||||
|
||||
const RefPtr<SourceSurface> surf = mImage->GetAsSourceSurface();
|
||||
const RefPtr<gfx::SourceSurface> surf = mImage->GetAsSourceSurface();
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf;
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf;
|
||||
if (surf) {
|
||||
// WARNING: OSX can lose our MakeCurrent here.
|
||||
dataSurf = surf->GetDataSurface();
|
||||
@ -555,7 +654,7 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
|
||||
webgl->GenerateWarning("%s: Incurred CPU-side conversion, which is very slow.",
|
||||
funcName);
|
||||
|
||||
const void* uploadBytes;
|
||||
const uint8_t* uploadBytes;
|
||||
UniqueBuffer tempBuffer;
|
||||
if (!ConvertIfNeeded(webgl, funcName, srcBytes, srcStride, srcBPP, srcFormat,
|
||||
dstDUI, &uploadBytes, &tempBuffer))
|
||||
|
@ -7,14 +7,11 @@
|
||||
#define TEX_UNPACK_BLOB_H_
|
||||
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLTypes.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
|
||||
template <class T>
|
||||
class RefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class UniqueBuffer;
|
||||
@ -31,10 +28,6 @@ namespace gfx {
|
||||
class DataSourceSurface;
|
||||
} // namespace gfx
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
} // namespace gl
|
||||
|
||||
namespace layers {
|
||||
class Image;
|
||||
class ImageContainer;
|
||||
@ -59,6 +52,8 @@ public:
|
||||
const uint32_t mDepth;
|
||||
const bool mIsSrcPremult;
|
||||
|
||||
bool mNeedsExactUpload;
|
||||
|
||||
protected:
|
||||
TexUnpackBlob(const WebGLContext* webgl, TexImageTarget target, uint32_t rowLength,
|
||||
uint32_t width, uint32_t height, uint32_t depth, bool isSrcPremult);
|
||||
@ -67,10 +62,11 @@ public:
|
||||
virtual ~TexUnpackBlob() { }
|
||||
|
||||
protected:
|
||||
bool ConvertIfNeeded(WebGLContext* webgl, const char* funcName, const void* srcBytes,
|
||||
uint32_t srcStride, uint8_t srcBPP, WebGLTexelFormat srcFormat,
|
||||
bool ConvertIfNeeded(WebGLContext* webgl, const char* funcName,
|
||||
const uint8_t* srcBytes, uint32_t srcStride, uint8_t srcBPP,
|
||||
WebGLTexelFormat srcFormat,
|
||||
const webgl::DriverUnpackInfo* dstDUI,
|
||||
const void** const out_bytes,
|
||||
const uint8_t** const out_bytes,
|
||||
UniqueBuffer* const out_anchoredBuffer) const;
|
||||
|
||||
public:
|
||||
@ -86,12 +82,13 @@ public:
|
||||
class TexUnpackBytes final : public TexUnpackBlob
|
||||
{
|
||||
public:
|
||||
const void* const mBytes;
|
||||
const bool mIsClientData;
|
||||
const uint8_t* const mPtr;
|
||||
|
||||
TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target, uint32_t width,
|
||||
uint32_t height, uint32_t depth, const void* bytes);
|
||||
uint32_t height, uint32_t depth, bool isClientData, const uint8_t* ptr);
|
||||
|
||||
virtual bool HasData() const override { return bool(mBytes); }
|
||||
virtual bool HasData() const override { return !mIsClientData || bool(mPtr); }
|
||||
|
||||
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
@ -109,6 +106,8 @@ public:
|
||||
uint32_t height, uint32_t depth, layers::Image* image,
|
||||
bool isAlphaPremult);
|
||||
|
||||
~TexUnpackImage(); // Prevent needing to define layers::Image in the header.
|
||||
|
||||
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
const webgl::DriverUnpackInfo* dui, GLint xOffset,
|
||||
@ -126,10 +125,10 @@ public:
|
||||
bool isAlphaPremult);
|
||||
|
||||
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
const webgl::DriverUnpackInfo* dui, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset,
|
||||
GLenum* const out_error) const override;
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
const webgl::DriverUnpackInfo* dui, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset,
|
||||
GLenum* const out_error) const override;
|
||||
};
|
||||
|
||||
} // namespace webgl
|
||||
|
@ -33,7 +33,9 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
private:
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
|
||||
uint32_t* alignment,
|
||||
const char* info) override;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
|
||||
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
|
||||
|
@ -8,7 +8,8 @@
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
WebGL1Context::ValidateAttribPointerType(bool /*integerMode*/, GLenum type, GLsizei* out_alignment, const char* info)
|
||||
WebGL1Context::ValidateAttribPointerType(bool /*integerMode*/, GLenum type,
|
||||
uint32_t* out_alignment, const char* info)
|
||||
{
|
||||
MOZ_ASSERT(out_alignment);
|
||||
if (!out_alignment)
|
||||
|
@ -122,10 +122,10 @@ public:
|
||||
template<class T>
|
||||
inline void
|
||||
TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLenum unpackFormat, GLenum unpackType, T& elem, ErrorResult& out_rv)
|
||||
GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
|
||||
{
|
||||
TexSubImage3D(target, level, xOffset, yOffset, zOffset, unpackFormat, unpackType,
|
||||
&elem, &out_rv);
|
||||
&any, &out_rv);
|
||||
}
|
||||
|
||||
void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
|
||||
@ -140,6 +140,64 @@ public:
|
||||
GLsizei depth, GLenum sizedUnpackFormat,
|
||||
const dom::ArrayBufferView& data);
|
||||
|
||||
////////////////
|
||||
// Texture PBOs
|
||||
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
|
||||
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType, WebGLsizeiptr offset, ErrorResult&);
|
||||
|
||||
void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType, WebGLsizeiptr offset);
|
||||
|
||||
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
|
||||
ErrorResult&);
|
||||
|
||||
////////////////
|
||||
// WebGL1 overloads
|
||||
|
||||
void
|
||||
TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels, ErrorResult& out_rv)
|
||||
{
|
||||
WebGLContext::TexImage2D(texImageTarget, level, internalFormat, width, height,
|
||||
border, unpackFormat, unpackType, pixels, out_rv);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
|
||||
{
|
||||
WebGLContext::TexImage2D(texImageTarget, level, internalFormat, unpackFormat,
|
||||
unpackType, any, out_rv);
|
||||
}
|
||||
|
||||
void
|
||||
TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels, ErrorResult& out_rv)
|
||||
{
|
||||
WebGLContext::TexSubImage2D(texImageTarget, level, xOffset, yOffset, width,
|
||||
height, unpackFormat, unpackType, pixels, out_rv);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void
|
||||
TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLenum unpackFormat, GLenum unpackType, T& any, ErrorResult& out_rv)
|
||||
{
|
||||
WebGLContext::TexSubImage2D(texImageTarget, level, xOffset, yOffset, unpackFormat,
|
||||
unpackType, any, out_rv);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Programs and shaders - WebGL2ContextPrograms.cpp
|
||||
@ -364,7 +422,9 @@ private:
|
||||
|
||||
// CreateVertexArrayImpl is assumed to be infallible.
|
||||
virtual WebGLVertexArray* CreateVertexArrayImpl() override;
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
|
||||
uint32_t* alignment,
|
||||
const char* info) override;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
|
||||
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
|
||||
|
@ -20,16 +20,11 @@ WebGL2Context::ValidateBufferTarget(GLenum target, const char* funcName)
|
||||
case LOCAL_GL_COPY_WRITE_BUFFER:
|
||||
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
|
||||
case LOCAL_GL_PIXEL_PACK_BUFFER:
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
case LOCAL_GL_UNIFORM_BUFFER:
|
||||
return true;
|
||||
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
|
||||
ErrorInvalidOperation("%s: PBOs are still under development, and are currently"
|
||||
" disabled.",
|
||||
funcName);
|
||||
return false;
|
||||
|
||||
default:
|
||||
ErrorInvalidEnumInfo(funcName, target);
|
||||
return false;
|
||||
|
@ -4,7 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL2Context.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -202,6 +202,116 @@ WebGL2Context::CopyTexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xO
|
||||
height);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
void
|
||||
WebGL2Context::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
|
||||
ErrorResult&)
|
||||
{
|
||||
const char funcName[] = "texImage2D";
|
||||
const uint8_t funcDims = 2;
|
||||
|
||||
TexImageTarget target;
|
||||
WebGLTexture* tex;
|
||||
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
|
||||
&tex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isSubImage = false;
|
||||
const GLint xOffset = 0;
|
||||
const GLint yOffset = 0;
|
||||
const GLint zOffset = 0;
|
||||
const GLsizei depth = 1;
|
||||
tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, width, height, depth, border, unpackFormat,
|
||||
unpackType, offset);
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset,
|
||||
ErrorResult&)
|
||||
{
|
||||
const char funcName[] = "texSubImage2D";
|
||||
const uint8_t funcDims = 2;
|
||||
|
||||
TexImageTarget target;
|
||||
WebGLTexture* tex;
|
||||
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
|
||||
&tex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isSubImage = true;
|
||||
const GLenum internalFormat = 0;
|
||||
const GLint zOffset = 0;
|
||||
const GLsizei depth = 1;
|
||||
const GLint border = 0;
|
||||
tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, width, height, depth, border, unpackFormat,
|
||||
unpackType, offset);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
void
|
||||
WebGL2Context::TexImage3D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLint border,
|
||||
GLenum unpackFormat, GLenum unpackType, WebGLsizeiptr offset)
|
||||
{
|
||||
const char funcName[] = "texImage3D";
|
||||
const uint8_t funcDims = 3;
|
||||
|
||||
TexImageTarget target;
|
||||
WebGLTexture* tex;
|
||||
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
|
||||
&tex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isSubImage = false;
|
||||
const GLint xOffset = 0;
|
||||
const GLint yOffset = 0;
|
||||
const GLint zOffset = 0;
|
||||
tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, width, height, depth, border, unpackFormat,
|
||||
unpackType, offset);
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
|
||||
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
|
||||
WebGLsizeiptr offset, ErrorResult&)
|
||||
{
|
||||
const char funcName[] = "texSubImage3D";
|
||||
const uint8_t funcDims = 3;
|
||||
|
||||
TexImageTarget target;
|
||||
WebGLTexture* tex;
|
||||
if (!ValidateTexImageTarget(this, funcName, funcDims, rawTexImageTarget, &target,
|
||||
&tex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isSubImage = true;
|
||||
const GLenum internalFormat = 0;
|
||||
const GLint border = 0;
|
||||
tex->TexOrSubImage(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, width, height, depth, border, unpackFormat,
|
||||
unpackType, offset);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
/*virtual*/ bool
|
||||
WebGL2Context::IsTexParamValid(GLenum pname) const
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ namespace mozilla {
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type,
|
||||
GLsizei* out_alignment, const char* info)
|
||||
uint32_t* out_alignment, const char* info)
|
||||
{
|
||||
MOZ_ASSERT(out_alignment);
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
OtherData
|
||||
};
|
||||
|
||||
explicit WebGLBuffer(WebGLContext* webgl, GLuint buf);
|
||||
WebGLBuffer(WebGLContext* webgl, GLuint buf);
|
||||
|
||||
void BindTo(GLenum target);
|
||||
Kind Content() const { return mContent; }
|
||||
|
@ -896,7 +896,7 @@ public:
|
||||
// WebGLTextureUpload.cpp
|
||||
public:
|
||||
bool ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
|
||||
uint32_t tailPixels, const webgl::TexUnpackBlob* blob);
|
||||
uint32_t tailPixels, webgl::TexUnpackBlob* blob);
|
||||
|
||||
protected:
|
||||
bool ValidateTexImageSpecification(const char* funcName, uint8_t funcDims,
|
||||
@ -914,8 +914,8 @@ protected:
|
||||
WebGLTexture** const out_texture,
|
||||
WebGLTexture::ImageInfo** const out_imageInfo);
|
||||
|
||||
bool ValidateUnpackInfo(const char* funcName, GLenum format, GLenum type,
|
||||
webgl::PackingInfo* const out);
|
||||
bool ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
|
||||
GLenum type, webgl::PackingInfo* const out);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Vertices Feature (WebGLContextVertices.cpp)
|
||||
@ -1311,7 +1311,7 @@ private:
|
||||
// Context customization points
|
||||
virtual WebGLVertexArray* CreateVertexArrayImpl();
|
||||
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0;
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, uint32_t* alignment, const char* info) = 0;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0;
|
||||
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsString.h"
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef WEBGLCONTEXTUNCHECKED_H
|
||||
#define WEBGLCONTEXTUNCHECKED_H
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
@ -15,9 +14,6 @@ namespace mozilla {
|
||||
|
||||
class WebGLBuffer;
|
||||
class WebGLSampler;
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
} // namespace gl
|
||||
|
||||
class WebGLContextUnchecked
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
@ -571,7 +572,7 @@ WebGLContext::ValidateAttribPointer(bool integerMode, GLuint index, GLint size,
|
||||
return false;
|
||||
}
|
||||
|
||||
GLsizei requiredAlignment = 0;
|
||||
uint32_t requiredAlignment = 0;
|
||||
if (!ValidateAttribPointerType(integerMode, type, &requiredAlignment, info))
|
||||
return false;
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -6,13 +6,13 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "GLContext.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLTimerQuery.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLFormats.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLFormats.h"
|
||||
|
@ -7,9 +7,7 @@
|
||||
#define WEBGL_EXTENSIONS_H_
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
|
@ -6,7 +6,9 @@
|
||||
#include "WebGLFormats.h"
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
#ifdef FOO
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "GLTypes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace webgl {
|
||||
|
@ -6,14 +6,17 @@
|
||||
#ifndef WEBGL_FRAMEBUFFER_H_
|
||||
#define WEBGL_FRAMEBUFFER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -24,10 +27,6 @@ class WebGLTexture;
|
||||
template<typename T>
|
||||
class PlacementArray;
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
} // namespace gl
|
||||
|
||||
class WebGLFBAttachPoint
|
||||
{
|
||||
public:
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include "nsString.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
class WebGLActiveInfo;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -22,7 +23,7 @@ class WebGLSampler final
|
||||
friend class WebGLTexture;
|
||||
|
||||
public:
|
||||
explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
|
||||
WebGLSampler(WebGLContext* webgl, GLuint sampler);
|
||||
|
||||
const GLuint mGLName;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef WEBGL_SHADER_H_
|
||||
#define WEBGL_SHADER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -43,6 +43,12 @@ ChooseValidatorCompileOptions(const ShBuiltInResources& resources,
|
||||
options |= SH_LIMIT_EXPRESSION_COMPLEXITY;
|
||||
}
|
||||
|
||||
// Sampler arrays indexed with non-constant expressions are forbidden in
|
||||
// GLSL 1.30 and later.
|
||||
// ESSL 3 requires constant-integral-expressions for this as well.
|
||||
// Just do it universally.
|
||||
options |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
|
||||
|
||||
if (gfxPrefs::WebGLAllANGLEOptions()) {
|
||||
return options |
|
||||
SH_VALIDATE_LOOP_INDEXING |
|
||||
@ -78,11 +84,6 @@ ChooseValidatorCompileOptions(const ShBuiltInResources& resources,
|
||||
options |= SH_EMULATE_BUILT_IN_FUNCTIONS;
|
||||
}
|
||||
|
||||
// Work around bug 636926
|
||||
if (gl->Vendor() == gl::GLVendor::NVIDIA) {
|
||||
options |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
|
||||
}
|
||||
|
||||
// Work around that Mac drivers handle struct scopes incorrectly.
|
||||
options |= SH_REGENERATE_STRUCT_NAMES;
|
||||
}
|
||||
@ -129,13 +130,8 @@ WebGLContext::CreateShaderValidator(GLenum shaderType) const
|
||||
if (mBypassShaderValidation)
|
||||
return nullptr;
|
||||
|
||||
ShShaderSpec spec = IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
|
||||
ShShaderOutput outputLanguage = gl->IsGLES() ? SH_ESSL_OUTPUT
|
||||
: SH_GLSL_COMPATIBILITY_OUTPUT;
|
||||
|
||||
// If we're using WebGL2 we want a more specific version of GLSL
|
||||
if (IsWebGL2())
|
||||
outputLanguage = ShaderOutput(gl);
|
||||
const auto spec = (IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC);
|
||||
const auto outputLanguage = ShaderOutput(gl);
|
||||
|
||||
ShBuiltInResources resources;
|
||||
memset(&resources, 0, sizeof(resources));
|
||||
@ -253,7 +249,8 @@ ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ShGetShaderVersion(prev->mHandle) != ShGetShaderVersion(mHandle)) {
|
||||
const auto shaderVersion = ShGetShaderVersion(mHandle);
|
||||
if (ShGetShaderVersion(prev->mHandle) != shaderVersion) {
|
||||
nsPrintfCString error("Vertex shader version %d does not match"
|
||||
" fragment shader version %d.",
|
||||
ShGetShaderVersion(prev->mHandle),
|
||||
@ -319,7 +316,7 @@ ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log
|
||||
if (vertVarying.name != fragVarying.name)
|
||||
continue;
|
||||
|
||||
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying)) {
|
||||
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, shaderVersion)) {
|
||||
nsPrintfCString error("Varying `%s`is not linkable between"
|
||||
" attached shaders.",
|
||||
fragVarying.name.c_str());
|
||||
@ -355,7 +352,8 @@ ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (shaderVersion == 100) {
|
||||
// Enforce ESSL1 invariant linking rules.
|
||||
bool isInvariant_Position = false;
|
||||
bool isInvariant_PointSize = false;
|
||||
bool isInvariant_FragCoord = false;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLSampler.h"
|
||||
#include "WebGLTexelConversions.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
@ -18,6 +20,7 @@
|
||||
#include "WebGLFramebufferAttachable.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
@ -25,11 +28,19 @@ class WebGLContext;
|
||||
|
||||
namespace dom {
|
||||
class Element;
|
||||
class HTMLVideoElement;
|
||||
class ImageData;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
} // namespace dom
|
||||
|
||||
namespace layers {
|
||||
class Image;
|
||||
} // namespace layers
|
||||
|
||||
namespace webgl {
|
||||
struct DriverUnpackInfo;
|
||||
struct FormatUsageInfo;
|
||||
struct PackingInfo;
|
||||
class TexUnpackBlob;
|
||||
} // namespace webgl
|
||||
|
||||
@ -190,7 +201,7 @@ public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
|
||||
|
||||
explicit WebGLTexture(WebGLContext* webgl, GLuint tex);
|
||||
WebGLTexture(WebGLContext* webgl, GLuint tex);
|
||||
|
||||
void Delete();
|
||||
|
||||
@ -237,6 +248,12 @@ public:
|
||||
GLint zOffset, GLenum unpackFormat, GLenum unpackType,
|
||||
dom::Element* elem, ErrorResult* const out_error);
|
||||
|
||||
void TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
|
||||
GLint level, GLenum internalFormat, GLint xOffset, GLint yOffset,
|
||||
GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
WebGLsizeiptr offset);
|
||||
|
||||
protected:
|
||||
void TexOrSubImageBlob(bool isSubImage, const char* funcName, TexImageTarget target,
|
||||
GLint level, GLenum internalFormat, GLint xOffset,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "CanvasUtils.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
@ -127,36 +128,35 @@ DoesJSTypeMatchUnpackType(GLenum unpackType, js::Scalar::Type jsType)
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
|
||||
uint32_t tailPixels, const webgl::TexUnpackBlob* blob)
|
||||
uint32_t tailPixels, webgl::TexUnpackBlob* blob)
|
||||
{
|
||||
auto skipPixels = CheckedUint32(blob->mSkipPixels);
|
||||
skipPixels += CheckedUint32(blob->mSkipRows);
|
||||
|
||||
const auto usedPixelsPerRow = CheckedUint32(blob->mSkipPixels) + blob->mWidth;
|
||||
const auto usedRowsPerImage = CheckedUint32(blob->mSkipRows) + blob->mHeight;
|
||||
const auto usedImages = CheckedUint32(blob->mSkipImages) + blob->mDepth;
|
||||
|
||||
if (!usedPixelsPerRow.isValid() ||
|
||||
!usedRowsPerImage.isValid() ||
|
||||
!usedImages.isValid())
|
||||
{
|
||||
ErrorOutOfMemory("%s: Invalid calculation for e.g. UNPACK_SKIP_PIXELS + width.",
|
||||
funcName);
|
||||
return false;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
if (usedPixelsPerRow.value() > blob->mRowLength ||
|
||||
usedRowsPerImage.value() > blob->mImageHeight)
|
||||
{
|
||||
ErrorInvalidOperation("%s: UNPACK_ROW_LENGTH or UNPACK_IMAGE_HEIGHT too small.",
|
||||
if (!usedPixelsPerRow.isValid() || usedPixelsPerRow.value() > blob->mRowLength) {
|
||||
ErrorInvalidOperation("%s: UNPACK_SKIP_PIXELS + height > UNPACK_ROW_LENGTH.",
|
||||
funcName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blob->mHeight > blob->mImageHeight) {
|
||||
ErrorInvalidOperation("%s: height > UNPACK_IMAGE_HEIGHT.", funcName);
|
||||
return false;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
auto fullRowsNeeded = (usedImages - 1) * blob->mImageHeight;
|
||||
fullRowsNeeded += usedRowsPerImage - 1;
|
||||
// The spec doesn't bound SKIP_ROWS + height <= IMAGE_HEIGHT, unfortunately.
|
||||
auto skipFullRows = CheckedUint32(blob->mSkipImages) * blob->mImageHeight;
|
||||
skipFullRows += blob->mSkipRows;
|
||||
|
||||
MOZ_ASSERT(blob->mDepth >= 1);
|
||||
MOZ_ASSERT(blob->mHeight >= 1);
|
||||
auto usedFullRows = CheckedUint32(blob->mDepth - 1) * blob->mImageHeight;
|
||||
usedFullRows += blob->mHeight - 1; // Full rows in the final image, excluding the tail.
|
||||
|
||||
const auto fullRowsNeeded = skipFullRows + usedFullRows;
|
||||
if (!fullRowsNeeded.isValid()) {
|
||||
ErrorOutOfMemory("%s: Invalid calculation for required row count.",
|
||||
funcName);
|
||||
@ -166,8 +166,10 @@ WebGLContext::ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
|
||||
if (fullRows > fullRowsNeeded.value())
|
||||
return true;
|
||||
|
||||
if (fullRows == fullRowsNeeded.value() && tailPixels >= usedPixelsPerRow.value())
|
||||
if (fullRows == fullRowsNeeded.value() && tailPixels >= usedPixelsPerRow.value()) {
|
||||
blob->mNeedsExactUpload = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorInvalidOperation("%s: Desired upload requires more data than is available: (%u"
|
||||
" rows plus %u pixels needed, %u rows plus %u pixels"
|
||||
@ -177,68 +179,37 @@ WebGLContext::ValidateUnpackPixels(const char* funcName, uint32_t fullRows,
|
||||
return false;
|
||||
}
|
||||
|
||||
static UniquePtr<webgl::TexUnpackBlob>
|
||||
BlobFromView(WebGLContext* webgl, const char* funcName, TexImageTarget target,
|
||||
uint32_t width, uint32_t height, uint32_t depth,
|
||||
const webgl::PackingInfo& pi,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView)
|
||||
static bool
|
||||
ValidateUnpackBytes(WebGLContext* webgl, const char* funcName, uint32_t width,
|
||||
uint32_t height, uint32_t depth, const webgl::PackingInfo& pi,
|
||||
uint32_t byteCount, webgl::TexUnpackBlob* blob)
|
||||
{
|
||||
const uint8_t* bytes = nullptr;
|
||||
uint32_t byteCount = 0;
|
||||
const auto bytesPerPixel = webgl::BytesPerPixel(pi);
|
||||
const auto bytesPerRow = CheckedUint32(blob->mRowLength) * bytesPerPixel;
|
||||
const auto rowStride = RoundUpToMultipleOf(bytesPerRow, blob->mAlignment);
|
||||
|
||||
if (!maybeView.IsNull()) {
|
||||
const auto& view = maybeView.Value();
|
||||
|
||||
const auto jsType = JS_GetArrayBufferViewType(view.Obj());
|
||||
if (!DoesJSTypeMatchUnpackType(pi.type, jsType)) {
|
||||
webgl->ErrorInvalidOperation("%s: `pixels` must be compatible with `type`.",
|
||||
funcName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (width && height && depth) {
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
bytes = view.DataAllowShared();
|
||||
byteCount = view.LengthAllowShared();
|
||||
}
|
||||
const auto fullRows = byteCount / rowStride;
|
||||
if (!fullRows.isValid()) {
|
||||
webgl->ErrorOutOfMemory("%s: Unacceptable upload size calculated.");
|
||||
return false;
|
||||
}
|
||||
|
||||
UniquePtr<webgl::TexUnpackBlob> blob(new webgl::TexUnpackBytes(webgl, target, width,
|
||||
height, depth, bytes));
|
||||
const auto bodyBytes = fullRows.value() * rowStride.value();
|
||||
const auto tailPixels = (byteCount - bodyBytes) / bytesPerPixel;
|
||||
|
||||
//////
|
||||
|
||||
if (bytes) {
|
||||
const auto bytesPerPixel = webgl::BytesPerPixel(pi);
|
||||
const auto bytesPerRow = CheckedUint32(blob->mRowLength) * bytesPerPixel;
|
||||
const auto rowStride = RoundUpToMultipleOf(bytesPerRow, blob->mAlignment);
|
||||
|
||||
const auto fullRows = byteCount / rowStride;
|
||||
if (!fullRows.isValid()) {
|
||||
webgl->ErrorOutOfMemory("%s: Unacceptable upload size calculated.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto bodyBytes = fullRows.value() * rowStride.value();
|
||||
const auto tailPixels = (byteCount - bodyBytes) / bytesPerPixel;
|
||||
|
||||
if (!webgl->ValidateUnpackPixels(funcName, fullRows.value(), tailPixels,
|
||||
blob.get()))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
return Move(blob);
|
||||
return webgl->ValidateUnpackPixels(funcName, fullRows.value(), tailPixels, blob);
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateUnpackInfo(const char* funcName, GLenum format, GLenum type,
|
||||
webgl::PackingInfo* const out)
|
||||
WebGLContext::ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
|
||||
GLenum type, webgl::PackingInfo* const out)
|
||||
{
|
||||
if (usePBOs != bool(mBoundPixelUnpackBuffer)) {
|
||||
ErrorInvalidOperation("%s: PACK_BUFFER must be %s.", funcName,
|
||||
(usePBOs ? "non-null" : "null"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mFormatUsage->AreUnpackEnumsValid(format, type)) {
|
||||
ErrorInvalidEnum("%s: Invalid unpack format/type: 0x%04x/0x%04x", funcName,
|
||||
format, type);
|
||||
@ -265,17 +236,96 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
return;
|
||||
}
|
||||
|
||||
const bool usePBOs = false;
|
||||
webgl::PackingInfo pi;
|
||||
if (!mContext->ValidateUnpackInfo(funcName, unpackFormat, unpackType, &pi))
|
||||
if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
|
||||
return;
|
||||
|
||||
const auto blob = BlobFromView(mContext, funcName, target, width, height, depth, pi,
|
||||
maybeView);
|
||||
if (!blob)
|
||||
////
|
||||
|
||||
const uint8_t* bytes = nullptr;
|
||||
uint32_t byteCount = 0;
|
||||
|
||||
if (!maybeView.IsNull()) {
|
||||
const auto& view = maybeView.Value();
|
||||
|
||||
const auto jsType = JS_GetArrayBufferViewType(view.Obj());
|
||||
if (!DoesJSTypeMatchUnpackType(pi.type, jsType)) {
|
||||
mContext->ErrorInvalidOperation("%s: `pixels` not compatible with `type`.",
|
||||
funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (width && height && depth) {
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
bytes = view.DataAllowShared();
|
||||
byteCount = view.LengthAllowShared();
|
||||
}
|
||||
}
|
||||
|
||||
const bool isClientData = true;
|
||||
webgl::TexUnpackBytes blob(mContext, target, width, height, depth, isClientData,
|
||||
bytes);
|
||||
|
||||
if (bytes &&
|
||||
!ValidateUnpackBytes(mContext, funcName, width, height, depth, pi, byteCount,
|
||||
&blob))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, pi, blob.get());
|
||||
yOffset, zOffset, pi, &blob);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarget target,
|
||||
GLint level, GLenum internalFormat, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLsizei rawWidth,
|
||||
GLsizei rawHeight, GLsizei rawDepth, GLint border,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
WebGLsizeiptr offset)
|
||||
{
|
||||
uint32_t width, height, depth;
|
||||
if (!ValidateExtents(mContext, funcName, rawWidth, rawHeight, rawDepth, border,
|
||||
&width, &height, &depth))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool usePBOs = true;
|
||||
webgl::PackingInfo pi;
|
||||
if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
|
||||
return;
|
||||
|
||||
////
|
||||
|
||||
if (offset < 0) {
|
||||
mContext->ErrorInvalidValue("%s: offset cannot be negative.", funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isClientData = false;
|
||||
const auto ptr = (const uint8_t*)offset;
|
||||
webgl::TexUnpackBytes blob(mContext, target, width, height, depth, isClientData, ptr);
|
||||
|
||||
const auto& packBuffer = mContext->mBoundPixelUnpackBuffer;
|
||||
const auto bufferByteCount = packBuffer->ByteLength();
|
||||
|
||||
uint32_t byteCount = 0;
|
||||
if (bufferByteCount >= offset) {
|
||||
byteCount = bufferByteCount - offset;
|
||||
}
|
||||
|
||||
if (!ValidateUnpackBytes(mContext, funcName, width, height, depth, pi, byteCount,
|
||||
&blob))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, pi, &blob);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
@ -319,8 +369,9 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
GLint yOffset, GLint zOffset, GLenum unpackFormat,
|
||||
GLenum unpackType, dom::ImageData* imageData)
|
||||
{
|
||||
const bool usePBOs = false;
|
||||
webgl::PackingInfo pi;
|
||||
if (!mContext->ValidateUnpackInfo(funcName, unpackFormat, unpackType, &pi))
|
||||
if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
|
||||
return;
|
||||
|
||||
if (!imageData) {
|
||||
@ -346,8 +397,8 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
// non-premultiplied alpha values."
|
||||
const bool isAlphaPremult = false;
|
||||
|
||||
const webgl::TexUnpackSurface blob(mContext, target, width, height, depth, surf,
|
||||
isAlphaPremult);
|
||||
webgl::TexUnpackSurface blob(mContext, target, width, height, depth, surf,
|
||||
isAlphaPremult);
|
||||
|
||||
const uint32_t fullRows = imageData->Height();
|
||||
const uint32_t tailPixels = 0;
|
||||
@ -368,8 +419,9 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
GLenum unpackType, dom::Element* elem,
|
||||
ErrorResult* const out_error)
|
||||
{
|
||||
const bool usePBOs = false;
|
||||
webgl::PackingInfo pi;
|
||||
if (!mContext->ValidateUnpackInfo(funcName, unpackFormat, unpackType, &pi))
|
||||
if (!mContext->ValidateUnpackInfo(funcName, usePBOs, unpackFormat, unpackType, &pi))
|
||||
return;
|
||||
|
||||
//////
|
||||
@ -415,7 +467,9 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
const uint32_t depth = 1;
|
||||
|
||||
if (!layersImage && !dataSurf) {
|
||||
const webgl::TexUnpackBytes blob(mContext, target, width, height, depth, nullptr);
|
||||
const bool isClientData = true;
|
||||
const webgl::TexUnpackBytes blob(mContext, target, width, height, depth,
|
||||
isClientData, nullptr);
|
||||
TexOrSubImageBlob(isSubImage, funcName, target, level, internalFormat, xOffset,
|
||||
yOffset, zOffset, pi, &blob);
|
||||
return;
|
||||
@ -453,7 +507,7 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
|
||||
//////
|
||||
// Ok, we're good!
|
||||
|
||||
UniquePtr<const webgl::TexUnpackBlob> blob;
|
||||
UniquePtr<webgl::TexUnpackBlob> blob;
|
||||
const bool isAlphaPremult = sfer.mIsPremultiplied;
|
||||
|
||||
if (layersImage) {
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
|
||||
|
||||
private:
|
||||
explicit WebGLTimerQuery(WebGLContext* webgl, GLuint name);
|
||||
WebGLTimerQuery(WebGLContext* webgl, GLuint name);
|
||||
~WebGLTimerQuery();
|
||||
|
||||
GLenum mTarget;
|
||||
|
@ -22,7 +22,7 @@ class WebGLTransformFeedback final
|
||||
friend class WebGL2Context;
|
||||
|
||||
public:
|
||||
explicit WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
|
||||
WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
|
||||
|
||||
void Delete();
|
||||
WebGLContext* GetParentObject() const;
|
||||
|
@ -16,6 +16,9 @@ typedef int64_t WebGLintptr;
|
||||
typedef bool WebGLboolean;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext; // This is going to be needed a lot.
|
||||
} // namespace gl
|
||||
|
||||
/*
|
||||
* WebGLTextureFakeBlackStatus is an enum to track what needs to use a dummy 1x1 black
|
||||
|
@ -23,6 +23,7 @@ class WebGLProgram;
|
||||
|
||||
namespace webgl {
|
||||
struct LinkedProgramInfo;
|
||||
struct UniformInfo;
|
||||
} // namespace webgl
|
||||
|
||||
class WebGLUniformLocation final
|
||||
|
@ -4464,15 +4464,12 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
|
||||
[generated/test_2_conformance2__buffers__bound-buffer-size-change-test.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance2__buffers__buffer-copying-contents.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance2__buffers__buffer-copying-restrictions.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance2__buffers__buffer-overflow-test.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance2__buffers__buffer-type-restrictions.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance2__buffers__getBufferSubData.html]
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
@ -5839,7 +5836,6 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
|
||||
fail-if = (os == 'mac')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance__textures__misc__tex-image-with-invalid-data.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1') || (os == 'win' && os_version == '6.2'))
|
||||
[generated/test_2_conformance__textures__misc__tex-sub-image-2d-bad-args.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
|
@ -133,18 +133,12 @@ fail-if = (os == 'mac')
|
||||
skip-if = (os == 'win')
|
||||
[generated/test_2_conformance__extensions__webgl-compressed-texture-s3tc.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance__textures__misc__tex-image-with-invalid-data.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance2__buffers__buffer-type-restrictions.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance2__rendering__draw-buffers.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance__textures__misc__tex-image-with-format-and-type.html]
|
||||
fail-if = (os == 'mac')
|
||||
[generated/test_2_conformance__attribs__gl-vertexattribpointer.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance2__buffers__buffer-copying-restrictions.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance2__glsl3__forbidden-operators.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_conformance__textures__misc__tex-sub-image-2d-bad-args.html]
|
||||
@ -155,8 +149,6 @@ fail-if = (os == 'mac') || (os == 'win')
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_conformance__extensions__oes-texture-half-float.html]
|
||||
fail-if = (os == 'mac') || (os == 'win') || (os == 'android') || (os == 'linux')
|
||||
[generated/test_2_conformance2__buffers__buffer-copying-contents.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_2_conformance2__reading__read-pixels-pack-parameters.html]
|
||||
fail-if = (os == 'mac') || (os == 'win')
|
||||
[generated/test_conformance__attribs__gl-vertexattribpointer.html]
|
||||
|
@ -32,12 +32,11 @@ public:
|
||||
{
|
||||
return static_cast<HTMLTableCaptionElement*>(GetChild(nsGkAtoms::caption));
|
||||
}
|
||||
void SetCaption(HTMLTableCaptionElement* aCaption)
|
||||
void SetCaption(HTMLTableCaptionElement* aCaption, ErrorResult& aError)
|
||||
{
|
||||
DeleteCaption();
|
||||
if (aCaption) {
|
||||
mozilla::ErrorResult rv;
|
||||
nsINode::AppendChild(*aCaption, rv);
|
||||
nsINode::AppendChild(*aCaption, aError);
|
||||
}
|
||||
}
|
||||
|
||||
|
17
dom/html/crashtests/1282894.html
Normal file
17
dom/html/crashtests/1282894.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
|
||||
function boom() {
|
||||
var table = document.createElement("table");
|
||||
var cap = document.createElement("caption");
|
||||
cap.appendChild(table)
|
||||
table.caption = cap;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -76,3 +76,4 @@ load 1228876.html
|
||||
load 1230110.html
|
||||
load 1237633.html
|
||||
load 1281972-1.html
|
||||
load 1282894.html
|
@ -1400,6 +1400,11 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
readonly attribute jsval supportsHardwareH264Decoding;
|
||||
|
||||
/**
|
||||
* Returns the current audio backend as a free-form string.
|
||||
*/
|
||||
readonly attribute AString currentAudioBackend;
|
||||
|
||||
/**
|
||||
* Record (and return) frame-intervals for frames which were presented
|
||||
* between calling StartFrameTimeRecording and StopFrameTimeRecording.
|
||||
|
@ -2010,11 +2010,11 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
mPuppetWidget->GetDefaultScale());
|
||||
|
||||
if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
|
||||
nsCOMPtr<nsIDocument> document = GetDocument();
|
||||
if (gfxPrefs::TouchActionEnabled()) {
|
||||
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mPuppetWidget,
|
||||
localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
|
||||
document, localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
|
||||
}
|
||||
nsCOMPtr<nsIDocument> document = GetDocument();
|
||||
APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
|
||||
localEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
@ -2118,6 +2118,9 @@ TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& event)
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
NS_ENSURE_TRUE(presContext, true);
|
||||
|
||||
AutoHandlingUserInputStatePusher userInpStatePusher(localEvent.IsTrusted(),
|
||||
&localEvent, doc);
|
||||
|
||||
EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
|
||||
return true;
|
||||
}
|
||||
|
@ -296,5 +296,15 @@ cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel)
|
||||
}
|
||||
#endif
|
||||
|
||||
void GetCurrentBackend(nsAString& aBackend)
|
||||
{
|
||||
const char* backend = cubeb_get_backend_id(GetCubebContext());
|
||||
if (!backend) {
|
||||
aBackend.AssignLiteral("unknown");
|
||||
return;
|
||||
}
|
||||
aBackend.AssignASCII(backend);
|
||||
}
|
||||
|
||||
} // namespace CubebUtils
|
||||
} // namespace mozilla
|
||||
|
@ -46,6 +46,7 @@ bool CubebLatencyPrefSet();
|
||||
#if defined(__ANDROID__) && defined(MOZ_B2G)
|
||||
cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel);
|
||||
#endif
|
||||
void GetCurrentBackend(nsAString& aBackend);
|
||||
|
||||
} // namespace CubebUtils
|
||||
} // namespace mozilla
|
||||
|
@ -191,6 +191,13 @@ static const GUID DXVA2_Intel_ModeH264_E = {
|
||||
bool
|
||||
D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType, float aFramerate)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gfx::D3D9VideoCrashGuard crashGuard;
|
||||
if (crashGuard.Crashed()) {
|
||||
NS_WARNING("DXVA2D3D9 crash detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
DXVA2_VideoDesc desc;
|
||||
HRESULT hr = ConvertMFTypeToDXVAType(aType, &desc);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
@ -542,6 +549,13 @@ private:
|
||||
bool
|
||||
D3D11DXVA2Manager::SupportsConfig(IMFMediaType* aType, float aFramerate)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gfx::D3D11VideoCrashGuard crashGuard;
|
||||
if (crashGuard.Crashed()) {
|
||||
NS_WARNING("DXVA2D3D9 crash detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11VideoDevice> videoDevice;
|
||||
HRESULT hr = mDevice->QueryInterface(static_cast<ID3D11VideoDevice**>(getter_AddRefs(videoDevice)));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
@ -499,6 +499,26 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
|
||||
return mDecoder->Input(mLastInput);
|
||||
}
|
||||
|
||||
class SupportsConfigEvent : public Runnable {
|
||||
public:
|
||||
SupportsConfigEvent(DXVA2Manager* aDXVA2Manager, IMFMediaType* aMediaType, float aFramerate)
|
||||
: mDXVA2Manager(aDXVA2Manager)
|
||||
, mMediaType(aMediaType)
|
||||
, mFramerate(aFramerate)
|
||||
, mSupportsConfig(false)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
|
||||
mSupportsConfig = mDXVA2Manager->SupportsConfig(mMediaType, mFramerate);
|
||||
return NS_OK;
|
||||
}
|
||||
DXVA2Manager* mDXVA2Manager;
|
||||
IMFMediaType* mMediaType;
|
||||
float mFramerate;
|
||||
bool mSupportsConfig;
|
||||
};
|
||||
|
||||
// The MFTransform we use for decoding h264 video will silently fall
|
||||
// back to software decoding (even if we've negotiated DXVA) if the GPU
|
||||
// doesn't support decoding the given resolution. It will then upload
|
||||
@ -510,6 +530,10 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
|
||||
//
|
||||
// This code tests if the given resolution can be supported directly on the GPU,
|
||||
// and makes sure we only ask the MFT for DXVA if it can be supported properly.
|
||||
//
|
||||
// Ideally we'd know the framerate during initialization and would also ensure
|
||||
// that new decoders are created if the resolution changes. Then we could move
|
||||
// this check into Init and consolidate the main thread blocking code.
|
||||
bool
|
||||
WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType)
|
||||
{
|
||||
@ -523,7 +547,18 @@ WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType)
|
||||
// entire video.
|
||||
float framerate = 1000000.0 / mLastDuration;
|
||||
|
||||
return mDXVA2Manager->SupportsConfig(aType, framerate);
|
||||
// The supports config check must be done on the main thread since we have
|
||||
// a crash guard protecting it.
|
||||
RefPtr<SupportsConfigEvent> event =
|
||||
new SupportsConfigEvent(mDXVA2Manager, aType, framerate);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
event->Run();
|
||||
} else {
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
return event->mSupportsConfig;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
@ -47,7 +47,7 @@ ContentVerifier::Init(const nsACString& aContentSignatureHeader,
|
||||
|
||||
rv = mVerifier->CreateContextWithoutCertChain(
|
||||
this, aContentSignatureHeader,
|
||||
NS_LITERAL_CSTRING("remote-newtab-signer.mozilla.org"));
|
||||
NS_LITERAL_CSTRING("remotenewtab.content-signature.mozilla.org"));
|
||||
if (NS_FAILED(rv)){
|
||||
mVerifier = nullptr;
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICSTCCATOgAwIBAgIUWQzTTfKLNZgX5ngi/ENiI2DO2kowCwYJKoZIhvcNAQEL
|
||||
MIICUzCCAT2gAwIBAgIUNy0IWlDRDL53zwvj1lq0GCpIe2EwCwYJKoZIhvcNAQEL
|
||||
MBExDzANBgNVBAMMBmludC1DQTAiGA8yMDE0MTEyNzAwMDAwMFoYDzIwMTcwMjA0
|
||||
MDAwMDAwWjAUMRIwEAYDVQQDDAllZS1pbnQtQ0EwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05q
|
||||
nAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyD
|
||||
dKpuqc6jRDBCMBMGA1UdJQQMMAoGCCsGAQUFBwMDMCsGA1UdEQQkMCKCIHJlbW90
|
||||
ZS1uZXd0YWItc2lnbmVyLm1vemlsbGEub3JnMAsGCSqGSIb3DQEBCwOCAQEAc2nE
|
||||
feYpA8WFyiPfZi56NgVgc8kXSKRNgplDtBHXK7gT7ICNQTSKkt+zHxnS9tAoXoix
|
||||
OGKsyp/8LNIYGMr4vHVNyOGnxuiLzAYjmDxXhp3t36xOFlU5Y7UaKf9G4feMXrNH
|
||||
+q1SPYlP84keo1MaC5yhTZTTmJMKkRBsCbIVhfDnL3BUczxVZmk9F+7qK/trL222
|
||||
RoAaTZW5hdXUZrX630CYs1sQHWgL0B5rg2y9bwFk7toQ34JbjS0Z25e/MZUtFz19
|
||||
5tSjAZQHlLE6fAYZ3knrxF9xVMJCZf7gQqVphJzBtgy9yvTAtlMsrf6XS6sRRngz
|
||||
27HBxIpd4tYniYrtfg==
|
||||
dKpuqc6jTjBMMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDUGA1UdEQQuMCyCKnJlbW90
|
||||
ZW5ld3RhYi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzALBgkqhkiG9w0B
|
||||
AQsDggEBAIeB4WKghknsrow+lj3qzDiHrPBc9AMlb4aZvS6yzazmXr80rXxnsKkb
|
||||
ZV1PW/cU6xXH5srWHpfJwypvvYS74btNtuacjKVH2AJdua4482WQIi9gCkXIufRx
|
||||
2nSS6pYgYZ4vD+yG8v+3SCChOCXnLjRaN9WxMi8tldbOW9pH44O3vrSSL70pQ2Ph
|
||||
8ncUbUbCNNtYhtOe2Z4XT9Cswmfkf4OIQ3gy9eYK2ySEUWP+lHs9KnnNXrLcA/ae
|
||||
cSUdI00i3C3OS9yldeyNHzVb8mSsZ5d1WkJrkf/hnXWGrMHRTtlJlG7t7cN8S0Oi
|
||||
tQoinJyxrZ+zabFIyl/euDc+Y/dijOU=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC0TCCAbugAwIBAgIULYyr3v/0zZ+XiR22NH7hOcnj2FcwCwYJKoZIhvcNAQEL
|
||||
|
@ -378,6 +378,8 @@ var interfaceNamesInGlobalScope =
|
||||
"CSSValue",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CSSValueList",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CustomElementsRegistry",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CustomEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -105,6 +105,10 @@ public:
|
||||
RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static bool
|
||||
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
|
||||
: URL(aParent)
|
||||
, mURI(aURI)
|
||||
@ -294,12 +298,20 @@ URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
|
||||
nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
|
||||
|
||||
if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
global->UnregisterHostObjectURI(asciiurl);
|
||||
nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
URLMainThread::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_LossyConvertUTF16toASCII asciiurl(aURL);
|
||||
return nsHostObjectProtocolHandler::HasDataEntry(asciiurl);
|
||||
}
|
||||
|
||||
void
|
||||
URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
|
||||
{
|
||||
@ -668,6 +680,10 @@ public:
|
||||
RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static bool
|
||||
IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
ErrorResult& aRv);
|
||||
|
||||
URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
|
||||
|
||||
virtual void
|
||||
@ -897,6 +913,40 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// This class checks if an URL is valid on the main thread.
|
||||
class IsValidURLRunnable : public WorkerMainThreadRunnable
|
||||
{
|
||||
private:
|
||||
const nsString mURL;
|
||||
bool mValid;
|
||||
|
||||
public:
|
||||
IsValidURLRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aURL)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("URL :: IsValidURL"))
|
||||
, mURL(aURL)
|
||||
, mValid(false)
|
||||
{}
|
||||
|
||||
bool
|
||||
MainThreadRun()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
NS_ConvertUTF16toUTF8 url(mURL);
|
||||
mValid = nsHostObjectProtocolHandler::HasDataEntry(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IsValidURL() const
|
||||
{
|
||||
return mValid;
|
||||
}
|
||||
};
|
||||
|
||||
// This class creates a URL object on the main thread.
|
||||
class ConstructorRunnable : public WorkerMainThreadRunnable
|
||||
{
|
||||
@ -1307,6 +1357,24 @@ URLWorker::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
URLWorker::IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
|
||||
RefPtr<IsValidURLRunnable> runnable =
|
||||
new IsValidURLRunnable(workerPrivate, aUrl);
|
||||
|
||||
runnable->Dispatch(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return runnable->IsValidURL();
|
||||
}
|
||||
|
||||
URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
|
||||
: URL(nullptr)
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
@ -1699,6 +1767,16 @@ URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
return URLMainThread::IsValidURL(aGlobal, aURL, aRv);
|
||||
}
|
||||
return URLWorker::IsValidURL(aGlobal, aURL, aRv);
|
||||
}
|
||||
|
||||
URLSearchParams*
|
||||
URL::SearchParams()
|
||||
{
|
||||
|
@ -81,6 +81,10 @@ public:
|
||||
RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static bool
|
||||
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual void
|
||||
GetHref(nsAString& aHref, ErrorResult& aRv) const = 0;
|
||||
|
||||
|
20
dom/webidl/CustomElementsRegistry.webidl
Normal file
20
dom/webidl/CustomElementsRegistry.webidl
Normal file
@ -0,0 +1,20 @@
|
||||
/* 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/. */
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-window-customelements
|
||||
[Func="CustomElementsRegistry::IsCustomElementsEnabled"]
|
||||
interface CustomElementsRegistry {
|
||||
[Throws]
|
||||
void define(DOMString name, Function functionConstructor,
|
||||
optional ElementDefinitionOptions options);
|
||||
[Throws]
|
||||
any get(DOMString name);
|
||||
[Throws]
|
||||
Promise<void> whenDefined(DOMString name);
|
||||
};
|
||||
|
||||
dictionary ElementDefinitionOptions {
|
||||
DOMString extends;
|
||||
};
|
||||
|
@ -261,7 +261,8 @@ partial interface Document {
|
||||
|
||||
//http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
|
||||
partial interface Document {
|
||||
[Throws, Func="nsDocument::IsWebComponentsEnabled"]
|
||||
// this is deprecated from CustomElements v0
|
||||
[Throws, Func="CustomElementsRegistry::IsCustomElementsEnabled"]
|
||||
object registerElement(DOMString name, optional ElementRegistrationOptions options);
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
interface HTMLTableElement : HTMLElement {
|
||||
[SetterThrows]
|
||||
attribute HTMLTableCaptionElement? caption;
|
||||
HTMLElement createCaption();
|
||||
void deleteCaption();
|
||||
|
@ -56,6 +56,8 @@ partial interface URL {
|
||||
static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
|
||||
[Throws]
|
||||
static void revokeObjectURL(DOMString url);
|
||||
[ChromeOnly, Throws]
|
||||
static boolean isValidURL(DOMString url);
|
||||
};
|
||||
|
||||
dictionary objectURLOptions
|
||||
|
@ -348,19 +348,25 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
||||
any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
|
||||
void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
/* Texture objects */
|
||||
void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
|
||||
GLsizei depth);
|
||||
|
||||
//////
|
||||
|
||||
void texImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLint border, GLenum format,
|
||||
GLenum type, ArrayBufferView? pixels);
|
||||
|
||||
//////
|
||||
|
||||
[Throws] // Can't actually throw.
|
||||
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type,
|
||||
ArrayBufferView? pixels);
|
||||
GLenum format, GLenum type, ArrayBufferView? pixels);
|
||||
[Throws] // Can't actually throw.
|
||||
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLint zoffset, GLenum format, GLenum type, ImageData? data);
|
||||
@ -375,6 +381,8 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
||||
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLint zoffset, GLenum format, GLenum type, HTMLVideoElement video);
|
||||
|
||||
//////
|
||||
|
||||
void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLint zoffset, GLint x, GLint y, GLsizei width,
|
||||
GLsizei height);
|
||||
@ -387,6 +395,70 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
||||
GLsizei depth, GLenum format,
|
||||
ArrayBufferView data);
|
||||
|
||||
////////////////
|
||||
// Texture from PBO
|
||||
|
||||
[Throws] // Can't actually throw.
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum format, GLenum type,
|
||||
GLintptr offset);
|
||||
|
||||
[Throws] // Can't actually throw.
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
GLintptr offset);
|
||||
|
||||
void texImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLint border, GLenum format,
|
||||
GLenum type, GLintptr offset);
|
||||
|
||||
[Throws] // Can't actually throw.
|
||||
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type, GLintptr offset);
|
||||
|
||||
////////////////
|
||||
// WebGL 1 overloads
|
||||
|
||||
// Overloads must share [Throws].
|
||||
[Throws] // Can't throw.
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum format, GLenum type,
|
||||
ArrayBufferView? pixels);
|
||||
[Throws] // Can't throw.
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format,
|
||||
GLenum type, ImageData? pixels);
|
||||
[Throws] // May throw DOMException
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format,
|
||||
GLenum type, HTMLImageElement image);
|
||||
[Throws] // May throw DOMException
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format,
|
||||
GLenum type, HTMLCanvasElement canvas);
|
||||
[Throws] // May throw DOMException
|
||||
void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format,
|
||||
GLenum type, HTMLVideoElement video);
|
||||
|
||||
//////
|
||||
|
||||
[Throws] // Can't throw.
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
ArrayBufferView? pixels);
|
||||
[Throws] // Can't throw.
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLenum format, GLenum type, ImageData? pixels);
|
||||
[Throws] // May throw DOMException
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLenum format, GLenum type, HTMLImageElement image);
|
||||
[Throws] // May throw DOMException
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLenum format, GLenum type, HTMLCanvasElement canvas);
|
||||
[Throws] // May throw DOMException
|
||||
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLenum format, GLenum type, HTMLVideoElement video);
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
/* Programs and shaders */
|
||||
[WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram? program, DOMString name);
|
||||
|
||||
|
@ -36,6 +36,8 @@ typedef any Transferable;
|
||||
[PutForwards=href, Unforgeable, Throws,
|
||||
CrossOriginReadable, CrossOriginWritable] readonly attribute Location? location;
|
||||
[Throws] readonly attribute History history;
|
||||
[Func="CustomElementsRegistry::IsCustomElementsEnabled"]
|
||||
readonly attribute CustomElementsRegistry customElements;
|
||||
[Replaceable, Throws] readonly attribute BarProp locationbar;
|
||||
[Replaceable, Throws] readonly attribute BarProp menubar;
|
||||
[Replaceable, Throws] readonly attribute BarProp personalbar;
|
||||
|
@ -107,6 +107,7 @@ WEBIDL_FILES = [
|
||||
'CSSTransition.webidl',
|
||||
'CSSValue.webidl',
|
||||
'CSSValueList.webidl',
|
||||
'CustomElementsRegistry.webidl',
|
||||
'DataContainerEvent.webidl',
|
||||
'DataTransfer.webidl',
|
||||
'DataTransferItem.webidl',
|
||||
|
@ -102,6 +102,73 @@ ReleaseTemporarySurface(void* aPixels, void* aContext)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool
|
||||
VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
if (aFormat != SurfaceFormat::B8G8R8X8 || aSize.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
// We should've initialized the data to be opaque already
|
||||
// On debug builds, verify that this is actually true.
|
||||
int height = aSize.height;
|
||||
int width = aSize.width;
|
||||
|
||||
for (int row = 0; row < height; ++row) {
|
||||
for (int column = 0; column < width; column += 4) {
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
MOZ_ASSERT(aData[column] == 0xFF);
|
||||
#else
|
||||
MOZ_ASSERT(aData[column + 3] == 0xFF);
|
||||
#endif
|
||||
}
|
||||
aData += aStride;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Since checking every pixel is expensive, this only checks the four corners and center
|
||||
// of a surface that their alpha value is 0xFF.
|
||||
static bool
|
||||
VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
if (aFormat != SurfaceFormat::B8G8R8X8 || aSize.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int height = aSize.height;
|
||||
int width = aSize.width;
|
||||
const int pixelSize = 4;
|
||||
const int strideDiff = aStride - (width * pixelSize);
|
||||
MOZ_ASSERT(width * pixelSize <= aStride);
|
||||
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
const int alphaOffset = 0;
|
||||
#else
|
||||
const int alphaOffset = 3;
|
||||
#endif
|
||||
|
||||
const int topLeft = alphaOffset;
|
||||
const int topRight = width * pixelSize + alphaOffset - pixelSize;
|
||||
const int bottomRight = aStride * height - strideDiff + alphaOffset - pixelSize;
|
||||
const int bottomLeft = aStride * height - aStride + alphaOffset;
|
||||
|
||||
// Lastly the center pixel
|
||||
int middleRowHeight = height / 2;
|
||||
int middleRowWidth = (width / 2) * pixelSize;
|
||||
const int middle = aStride * middleRowHeight + middleRowWidth + alphaOffset;
|
||||
|
||||
MOZ_ASSERT(aData[topLeft] == 0xFF);
|
||||
MOZ_ASSERT(aData[topRight] == 0xFF);
|
||||
MOZ_ASSERT(aData[bottomRight] == 0xFF);
|
||||
MOZ_ASSERT(aData[bottomLeft] == 0xFF);
|
||||
MOZ_ASSERT(aData[middle] == 0xFF);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SkBitmap
|
||||
GetBitmapForSurface(SourceSurface* aSurface)
|
||||
{
|
||||
@ -129,6 +196,9 @@ GetBitmapForSurface(SourceSurface* aSurface)
|
||||
gfxDebug() << "Failed installing pixels on Skia bitmap for temporary surface";
|
||||
}
|
||||
|
||||
// Skia doesn't support RGBX surfaces so ensure that the alpha value is opaque white.
|
||||
MOZ_ASSERT(VerifyRGBXCorners(surf->GetData(), surf->GetSize(),
|
||||
surf->Stride(), surf->GetFormat()));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@ -1334,7 +1404,10 @@ DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const
|
||||
// uploading, so any data surface is fine. Call GetDataSurface
|
||||
// to trigger any required readback so that it only happens
|
||||
// once.
|
||||
return aSurface->GetDataSurface();
|
||||
RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
|
||||
MOZ_ASSERT(VerifyRGBXFormat(dataSurface->GetData(), dataSurface->GetSize(),
|
||||
dataSurface->Stride(), dataSurface->GetFormat()));
|
||||
return dataSurface.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
@ -1415,7 +1488,8 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
||||
return false;
|
||||
}
|
||||
|
||||
bitmap.eraseColor(SK_ColorTRANSPARENT);
|
||||
SkColor clearColor = (aFormat == SurfaceFormat::B8G8R8X8) ? SK_ColorBLACK : SK_ColorTRANSPARENT;
|
||||
bitmap.eraseColor(clearColor);
|
||||
|
||||
mCanvas.adopt(new SkCanvas(bitmap));
|
||||
mSize = aSize;
|
||||
@ -1477,30 +1551,6 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
// We should've initialized the data to be opaque already
|
||||
// On debug builds, verify that this is actually true.
|
||||
int height = aSize.height;
|
||||
int width = aSize.width;
|
||||
|
||||
for (int row = 0; row < height; ++row) {
|
||||
for (int column = 0; column < width; column += 4) {
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
MOZ_ASSERT(aData[column] == 0xFF);
|
||||
#else
|
||||
MOZ_ASSERT(aData[column + 3] == 0xFF);
|
||||
#endif
|
||||
}
|
||||
aData += aStride;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized)
|
||||
{
|
||||
@ -1558,7 +1608,8 @@ DrawTargetSkia::ClearRect(const Rect &aRect)
|
||||
MarkChanged();
|
||||
mCanvas->save();
|
||||
mCanvas->clipRect(RectToSkRect(aRect), SkRegion::kIntersect_Op, true);
|
||||
mCanvas->clear(SK_ColorTRANSPARENT);
|
||||
SkColor clearColor = (mFormat == SurfaceFormat::B8G8R8X8) ? SK_ColorBLACK : SK_ColorTRANSPARENT;
|
||||
mCanvas->clear(clearColor);
|
||||
mCanvas->restore();
|
||||
}
|
||||
|
||||
|
@ -827,8 +827,12 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Skia doesn't support RGBX, so memset RGBX to 0xFF
|
||||
bool clearSurface = aZero || aFormat == SurfaceFormat::B8G8R8X8;
|
||||
uint8_t clearValue = aFormat == SurfaceFormat::B8G8R8X8 ? 0xFF : 0;
|
||||
|
||||
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
|
||||
if (newSurf->Init(aSize, aFormat, aZero)) {
|
||||
if (newSurf->Init(aSize, aFormat, clearSurface, clearValue)) {
|
||||
return newSurf.forget();
|
||||
}
|
||||
|
||||
@ -847,8 +851,12 @@ Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Skia doesn't support RGBX, so memset RGBX to 0xFF
|
||||
bool clearSurface = aZero || aFormat == SurfaceFormat::B8G8R8X8;
|
||||
uint8_t clearValue = aFormat == SurfaceFormat::B8G8R8X8 ? 0xFF : 0;
|
||||
|
||||
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
|
||||
if (newSurf->InitWithStride(aSize, aFormat, aStride, aZero)) {
|
||||
if (newSurf->Init(aSize, aFormat, clearSurface, clearValue, aStride)) {
|
||||
return newSurf.forget();
|
||||
}
|
||||
|
||||
|
@ -49,40 +49,26 @@ SourceSurfaceRawData::GuaranteePersistance()
|
||||
bool
|
||||
SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
|
||||
SurfaceFormat aFormat,
|
||||
bool aZero)
|
||||
bool aClearMem,
|
||||
uint8_t aClearValue,
|
||||
int32_t aStride)
|
||||
{
|
||||
mFormat = aFormat;
|
||||
mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
|
||||
mStride = aStride ? aStride : GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
|
||||
if (bufLen > 0) {
|
||||
bool zeroMem = aClearMem && !aClearValue;
|
||||
static_assert(sizeof(decltype(mArray[0])) == 1,
|
||||
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
|
||||
mArray.Realloc(/* actually an object count */ bufLen, aZero);
|
||||
|
||||
// AlignedArray uses cmalloc to zero mem for a fast path.
|
||||
mArray.Realloc(/* actually an object count */ bufLen, zeroMem);
|
||||
mSize = aSize;
|
||||
} else {
|
||||
mArray.Dealloc();
|
||||
mSize.SizeTo(0, 0);
|
||||
}
|
||||
|
||||
return mArray != nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
SourceSurfaceAlignedRawData::InitWithStride(const IntSize &aSize,
|
||||
SurfaceFormat aFormat,
|
||||
int32_t aStride,
|
||||
bool aZero)
|
||||
{
|
||||
mFormat = aFormat;
|
||||
mStride = aStride;
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
|
||||
if (bufLen > 0) {
|
||||
static_assert(sizeof(decltype(mArray[0])) == 1,
|
||||
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
|
||||
mArray.Realloc(/* actually an object count */ bufLen, aZero);
|
||||
mSize = aSize;
|
||||
if (mArray && aClearMem && aClearValue) {
|
||||
memset(mArray, aClearValue, mStride * aSize.height);
|
||||
}
|
||||
} else {
|
||||
mArray.Dealloc();
|
||||
mSize.SizeTo(0, 0);
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
MOZ_ASSERT(mMapCount == 0);
|
||||
}
|
||||
|
||||
virtual uint8_t *GetData() override { return mArray; }
|
||||
virtual uint8_t* GetData() override { return mArray; }
|
||||
virtual int32_t Stride() override { return mStride; }
|
||||
|
||||
virtual SurfaceType GetType() const override { return SurfaceType::DATA; }
|
||||
@ -142,11 +142,9 @@ private:
|
||||
|
||||
bool Init(const IntSize &aSize,
|
||||
SurfaceFormat aFormat,
|
||||
bool aZero);
|
||||
bool InitWithStride(const IntSize &aSize,
|
||||
SurfaceFormat aFormat,
|
||||
int32_t aStride,
|
||||
bool aZero);
|
||||
bool aClearMem,
|
||||
uint8_t aClearValue,
|
||||
int32_t aStride = 0);
|
||||
|
||||
AlignedArray<uint8_t> mArray;
|
||||
int32_t mStride;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/gfx/Tools.h" // For BytesPerPixel
|
||||
#include "nsRegion.h"
|
||||
#include "GfxTexturesReporter.h"
|
||||
@ -18,39 +19,6 @@ using namespace gfx;
|
||||
|
||||
namespace gl {
|
||||
|
||||
/* These two techniques are suggested by "Bit Twiddling Hacks"
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns true if |aNumber| is a power of two
|
||||
* 0 is incorreclty considered a power of two
|
||||
*/
|
||||
static bool
|
||||
IsPowerOfTwo(int aNumber)
|
||||
{
|
||||
return (aNumber & (aNumber - 1)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first integer greater than |aNumber| which is a power of two
|
||||
* Undefined for |aNumber| < 0
|
||||
*/
|
||||
static int
|
||||
NextPowerOfTwo(int aNumber)
|
||||
{
|
||||
#if defined(__arm__)
|
||||
return 1 << (32 - __builtin_clz(aNumber - 1));
|
||||
#else
|
||||
--aNumber;
|
||||
aNumber |= aNumber >> 1;
|
||||
aNumber |= aNumber >> 2;
|
||||
aNumber |= aNumber >> 4;
|
||||
aNumber |= aNumber >> 8;
|
||||
aNumber |= aNumber >> 16;
|
||||
return ++aNumber;
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
@ -285,15 +253,16 @@ TexImage2DHelper(GLContext* gl,
|
||||
NS_ASSERTION(format == (GLenum)internalformat,
|
||||
"format and internalformat not the same for glTexImage2D on GLES2");
|
||||
|
||||
MOZ_ASSERT(width >= 0 && height >= 0);
|
||||
if (!CanUploadNonPowerOfTwo(gl)
|
||||
&& (stride != width * pixelsize
|
||||
|| !IsPowerOfTwo(width)
|
||||
|| !IsPowerOfTwo(height))) {
|
||||
|| !IsPowerOfTwo((uint32_t)width)
|
||||
|| !IsPowerOfTwo((uint32_t)height))) {
|
||||
|
||||
// Pad out texture width and height to the next power of two
|
||||
// as we don't support/want non power of two texture uploads
|
||||
GLsizei paddedWidth = NextPowerOfTwo(width);
|
||||
GLsizei paddedHeight = NextPowerOfTwo(height);
|
||||
GLsizei paddedWidth = RoundUpPow2((uint32_t)width);
|
||||
GLsizei paddedHeight = RoundUpPow2((uint32_t)height);
|
||||
|
||||
GLvoid* paddedPixels = new unsigned char[paddedWidth * paddedHeight * pixelsize];
|
||||
|
||||
|
@ -32,7 +32,7 @@ GPUChild::Init()
|
||||
nsTArray<GfxPrefSetting> prefs;
|
||||
for (auto pref : gfxPrefs::all()) {
|
||||
if (pref->HasDefaultValue()) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
GfxPrefValue value;
|
||||
|
@ -84,7 +84,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
context->CopyResource(softTexture, texture);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
|
||||
gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8A8);
|
||||
if (NS_WARN_IF(!surface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9RecycleAllocator* aAllocator,
|
||||
hr = d3d9->CheckDeviceFormatConversion(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
desc.Format,
|
||||
D3DFMT_X8R8G8B8);
|
||||
D3DFMT_A8R8G8B8);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
// DXVA surfaces aren't created sharable, so we need to copy the surface
|
||||
// to a sharable texture to that it's accessible to the layer manager's
|
||||
// device.
|
||||
RefPtr<TextureClient> textureClient =
|
||||
aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8X8, aRegion.Size());
|
||||
aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8A8, aRegion.Size());
|
||||
if (!textureClient) {
|
||||
return E_FAIL;
|
||||
}
|
||||
@ -133,7 +133,7 @@ D3D9SurfaceImage::GetAsSourceSurface()
|
||||
RefPtr<IDirect3DSurface9> systemMemorySurface;
|
||||
hr = device->CreateOffscreenPlainSurface(mSize.width,
|
||||
mSize.height,
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(systemMemorySurface),
|
||||
0);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user