зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-i to m-c
This commit is contained in:
Коммит
992792ad07
|
@ -195,7 +195,6 @@
|
|||
@BINPATH@/components/dom_indexeddb.xpt
|
||||
@BINPATH@/components/dom_offline.xpt
|
||||
@BINPATH@/components/dom_payment.xpt
|
||||
@BINPATH@/components/dom_push.xpt
|
||||
@BINPATH@/components/dom_json.xpt
|
||||
@BINPATH@/components/dom_browserelement.xpt
|
||||
@BINPATH@/components/dom_messages.xpt
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
%tabBrowserDTD;
|
||||
]>
|
||||
|
||||
# MAKE_E10S_WORK surrounds code needed to have the front-end try to be smart
|
||||
# about using non-remote browsers for loading certain URIs when remote tabs
|
||||
# (browser.tabs.remote) are enabled.
|
||||
#define MAKE_E10S_WORK 1
|
||||
|
||||
<bindings id="tabBrowserBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
|
@ -1300,6 +1305,73 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
#ifdef MAKE_E10S_WORK
|
||||
<method name="_updateBrowserRemoteness">
|
||||
<parameter name="aBrowser"/>
|
||||
<parameter name="aRemote"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let isRemote = aBrowser.getAttribute("remote") == "true";
|
||||
if (isRemote == aRemote)
|
||||
return;
|
||||
|
||||
// Unhook our progress listener.
|
||||
let tab = this._getTabForBrowser(aBrowser);
|
||||
let index = tab._tPos;
|
||||
let filter = this.mTabFilters[index];
|
||||
aBrowser.webProgress.removeProgressListener(filter);
|
||||
|
||||
// Change the "remote" attribute.
|
||||
let parent = aBrowser.parentNode;
|
||||
parent.removeChild(aBrowser);
|
||||
aBrowser.setAttribute("remote", aRemote ? "true" : "false");
|
||||
parent.appendChild(aBrowser);
|
||||
|
||||
// Restore the progress listener.
|
||||
aBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
|
||||
if (aRemote)
|
||||
tab.setAttribute("remote", "true");
|
||||
else
|
||||
tab.removeAttribute("remote");
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
Returns true if we want to load the content for this URL in a
|
||||
remote process. Eventually this should just check whether aURL
|
||||
is unprivileged. Right now, though, we would like to load
|
||||
some unprivileged URLs (like about:neterror) in the main
|
||||
process since they interact with chrome code through
|
||||
BrowserOnClick.
|
||||
-->
|
||||
<method name="_shouldBrowserBeRemote">
|
||||
<parameter name="aURL"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!gMultiProcessBrowser)
|
||||
return false;
|
||||
|
||||
// loadURI in browser.xml treats null as about:blank
|
||||
if (!aURL)
|
||||
aURL = "about:blank";
|
||||
|
||||
if (aURL.startsWith("about:") &&
|
||||
aURL.toLowerCase() != "about:home" &&
|
||||
aURL.toLowerCase() != "about:blank") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aURL.startsWith("chrome:"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
#endif
|
||||
|
||||
<method name="addTab">
|
||||
<parameter name="aURI"/>
|
||||
<parameter name="aReferrerURI"/>
|
||||
|
@ -1344,6 +1416,8 @@
|
|||
|
||||
t.setAttribute("crop", "end");
|
||||
t.setAttribute("onerror", "this.removeAttribute('image');");
|
||||
if (remote)
|
||||
t.setAttribute("remote", "true");
|
||||
t.className = "tabbrowser-tab";
|
||||
|
||||
this.tabContainer._unlockTabSizing();
|
||||
|
@ -1379,10 +1453,13 @@
|
|||
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
|
||||
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
|
||||
|
||||
if (Services.prefs.getPrefType("browser.tabs.remote") == Services.prefs.PREF_BOOL &&
|
||||
Services.prefs.getBoolPref("browser.tabs.remote")) {
|
||||
#ifdef MAKE_E10S_WORK
|
||||
let remote = this._shouldBrowserBeRemote(aURI);
|
||||
#else
|
||||
let remote = gMultiProcessBrowser;
|
||||
#endif
|
||||
if (remote)
|
||||
b.setAttribute("remote", "true");
|
||||
}
|
||||
|
||||
if (window.gShowPageResizers && document.getElementById("addon-bar").collapsed &&
|
||||
window.windowState == window.STATE_NORMAL) {
|
||||
|
@ -2554,7 +2631,17 @@
|
|||
<parameter name="aCharset"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
#ifdef MAKE_E10S_WORK
|
||||
this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(aURI));
|
||||
try {
|
||||
#endif
|
||||
return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
|
||||
#ifdef MAKE_E10S_WORK
|
||||
} catch (e) {
|
||||
let url = this.mCurrentBrowser.currentURI.spec;
|
||||
this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(url));
|
||||
}
|
||||
#endif
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -2568,7 +2655,17 @@
|
|||
<parameter name="aPostData"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
#ifdef MAKE_E10S_WORK
|
||||
this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(aURI));
|
||||
try {
|
||||
#endif
|
||||
return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
|
||||
#ifdef MAKE_E10S_WORK
|
||||
} catch (e) {
|
||||
let url = this.mCurrentBrowser.currentURI.spec;
|
||||
this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(url));
|
||||
}
|
||||
#endif
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -2818,6 +2915,7 @@
|
|||
browserStack.removeChild(this.mCurrentBrowser);
|
||||
this.mCurrentBrowser.setAttribute("remote", true);
|
||||
browserStack.appendChild(this.mCurrentBrowser);
|
||||
this.tabContainer.firstChild.setAttribute("remote", "true");
|
||||
}
|
||||
|
||||
this.mCurrentTab = this.tabContainer.firstChild;
|
||||
|
|
|
@ -190,7 +190,6 @@
|
|||
@BINPATH@/components/dom_canvas.xpt
|
||||
@BINPATH@/components/dom_contacts.xpt
|
||||
@BINPATH@/components/dom_alarm.xpt
|
||||
@BINPATH@/components/dom_push.xpt
|
||||
@BINPATH@/components/dom_core.xpt
|
||||
@BINPATH@/components/dom_css.xpt
|
||||
@BINPATH@/components/dom_devicestorage.xpt
|
||||
|
|
|
@ -1662,6 +1662,10 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
color: -moz-dialogtext;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[remote] {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
|
||||
background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, transparent 1px),
|
||||
linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%),
|
||||
|
|
|
@ -2257,6 +2257,10 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
-moz-box-align: stretch;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[remote] {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
%define TABSONTOP_TAB #tabbrowser-tabs[tabsontop="true"] > .tabbrowser-tab
|
||||
%define TABSONBOTTOM_TAB #tabbrowser-tabs[tabsontop="false"] > .tabbrowser-tab
|
||||
%define TABSONTOP_TAB_STACK #tabbrowser-tabs[tabsontop="true"] > .tabbrowser-tab > .tab-stack
|
||||
|
|
|
@ -1971,6 +1971,10 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[remote] {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:hover,
|
||||
.tabs-newtab-button:hover {
|
||||
background-image: @toolbarShadowOnTab@, @bgTabTextureHover@,
|
||||
|
|
|
@ -139,6 +139,10 @@ public class CmdWorkerThread extends Thread
|
|||
SUTAgentAndroid.log(dc, message);
|
||||
|
||||
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
|
||||
if (outputLine == null)
|
||||
{
|
||||
outputLine = "";
|
||||
}
|
||||
if (outputLine.length() > 0)
|
||||
{
|
||||
out.print(outputLine + "\n" + prompt);
|
||||
|
|
|
@ -170,6 +170,10 @@ public class DataWorkerThread extends Thread
|
|||
if ((inputLine += readLine(in)) != null)
|
||||
{
|
||||
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
|
||||
if (outputLine == null)
|
||||
{
|
||||
outputLine = "";
|
||||
}
|
||||
out.print(outputLine + "\n");
|
||||
out.flush();
|
||||
if (outputLine.equals("exit"))
|
||||
|
|
|
@ -107,7 +107,7 @@ public class DoCommand {
|
|||
String ffxProvider = "org.mozilla.ffxcp";
|
||||
String fenProvider = "org.mozilla.fencp";
|
||||
|
||||
private final String prgVersion = "SUTAgentAndroid Version 1.18";
|
||||
private final String prgVersion = "SUTAgentAndroid Version 1.19";
|
||||
|
||||
public enum Command
|
||||
{
|
||||
|
@ -1396,7 +1396,7 @@ private void CancelNotification()
|
|||
}
|
||||
Log.e("SUTAgentAndroid", "ERROR: Cannot access world writeable test root");
|
||||
|
||||
return(null);
|
||||
return sErrorPrefix + " unable to determine test root";
|
||||
}
|
||||
|
||||
public String GetAppRoot(String AppName)
|
||||
|
|
|
@ -0,0 +1,396 @@
|
|||
# vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
# 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/.
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# This script checks various aspects of SpiderMonkey code style. The current checks are as
|
||||
# follows.
|
||||
#
|
||||
# We check the following things in headers.
|
||||
#
|
||||
# - No cyclic dependencies.
|
||||
#
|
||||
# - No normal header should #include a inlines.h/-inl.h file.
|
||||
#
|
||||
# - #ifndef wrappers should have the right form. (XXX: not yet implemented)
|
||||
# - Every header file should have one.
|
||||
# - It should be in the vanilla form and have no tokens before/after it so
|
||||
# that GCC and clang can avoid multiple-inclusion.
|
||||
# - The guard name used should be appropriate for the filename.
|
||||
#
|
||||
# We check the following things in all files.
|
||||
#
|
||||
# - #includes should have full paths, e.g. "ion/Ion.h", not "Ion.h".
|
||||
#
|
||||
# - #includes should use the appropriate form for system headers (<...>) and
|
||||
# local headers ("...").
|
||||
#
|
||||
# - #includes should be ordered correctly. (XXX: not yet implemented; see bug
|
||||
# 888088)
|
||||
# - Each one should be in the correct section.
|
||||
# - Alphabetical order should be used within sections.
|
||||
# - Sections should be in the right order.
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import difflib
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
# We don't bother checking files in these directories, because they're (a) auxiliary or (b)
|
||||
# imported code that doesn't follow our coding style.
|
||||
ignored_js_src_dirs = [
|
||||
'js/src/config/', # auxiliary stuff
|
||||
'js/src/ctypes/libffi/', # imported code
|
||||
'js/src/devtools/', # auxiliary stuff
|
||||
'js/src/editline/', # imported code
|
||||
'js/src/gdb/', # auxiliary stuff
|
||||
'js/src/vtune/' # imported code
|
||||
]
|
||||
|
||||
# We ignore #includes of these files, because they don't follow the usual rules.
|
||||
included_inclnames_to_ignore = set([
|
||||
'ffi.h', # generated in ctypes/libffi/
|
||||
'devtools/sharkctl.h', # we ignore devtools/ in general
|
||||
'devtools/Instruments.h', # we ignore devtools/ in general
|
||||
'double-conversion.h', # strange MFBT case
|
||||
'javascript-trace.h', # generated in $OBJDIR if HAVE_DTRACE is defined
|
||||
'jsautokw.h', # generated in $OBJDIR
|
||||
'jsautooplen.h', # generated in $OBJDIR
|
||||
'jscustomallocator.h', # provided by embedders; allowed to be missing
|
||||
'js-config.h', # generated in $OBJDIR
|
||||
'pratom.h', # NSPR
|
||||
'prcvar.h', # NSPR
|
||||
'prinit.h', # NSPR
|
||||
'prlink.h', # NSPR
|
||||
'prlock.h', # NSPR
|
||||
'prprf.h', # NSPR
|
||||
'prthread.h', # NSPR
|
||||
'prtypes.h', # NSPR
|
||||
'selfhosted.out.h', # generated in $OBJDIR
|
||||
'unicode/locid.h', # ICU
|
||||
'unicode/numsys.h', # ICU
|
||||
'unicode/ucal.h', # ICU
|
||||
'unicode/uclean.h', # ICU
|
||||
'unicode/ucol.h', # ICU
|
||||
'unicode/udat.h', # ICU
|
||||
'unicode/udatpg.h', # ICU
|
||||
'unicode/uenum.h', # ICU
|
||||
'unicode/unum.h', # ICU
|
||||
'unicode/ustring.h', # ICU
|
||||
'unicode/utypes.h', # ICU
|
||||
'vtune/VTuneWrapper.h' # VTune
|
||||
])
|
||||
|
||||
# The files in tests/style/ contain code that fails this checking in various
|
||||
# ways. Here is the output we expect. If the actual output differs from
|
||||
# this, one of the following must have happened.
|
||||
# - New SpiderMonkey code violates one of the checked rules.
|
||||
# - The tests/style/ files have changed without expected_output being changed
|
||||
# accordingly.
|
||||
# - This script has been broken somehow.
|
||||
#
|
||||
expected_output = '''\
|
||||
js/src/tests/style/BadIncludes2.h:1: error:
|
||||
vanilla header includes an inline-header file "tests/style/BadIncludes2-inl.h"
|
||||
|
||||
js/src/tests/style/BadIncludes.h:1: error:
|
||||
the file includes itself
|
||||
|
||||
js/src/tests/style/BadIncludes.h:3: error:
|
||||
"BadIncludes2.h" is included using the wrong path;
|
||||
did you forget a prefix, or is the file not yet committed?
|
||||
|
||||
js/src/tests/style/BadIncludes.h:4: error:
|
||||
<tests/style/BadIncludes2.h> should be included using
|
||||
the #include "..." form
|
||||
|
||||
js/src/tests/style/BadIncludes.h:5: error:
|
||||
"stdio.h" is included using the wrong path;
|
||||
did you forget a prefix, or is the file not yet committed?
|
||||
|
||||
(multiple files): error:
|
||||
header files form one or more cycles
|
||||
|
||||
tests/style/HeaderCycleA1.h
|
||||
-> tests/style/HeaderCycleA2.h
|
||||
-> tests/style/HeaderCycleA3.h
|
||||
-> tests/style/HeaderCycleA1.h
|
||||
|
||||
tests/style/HeaderCycleB1-inl.h
|
||||
-> tests/style/HeaderCycleB2-inl.h
|
||||
-> tests/style/HeaderCycleB3-inl.h
|
||||
-> tests/style/HeaderCycleB4-inl.h
|
||||
-> tests/style/HeaderCycleB1-inl.h
|
||||
-> tests/style/jsheadercycleB5inlines.h
|
||||
-> tests/style/HeaderCycleB1-inl.h
|
||||
-> tests/style/HeaderCycleB4-inl.h
|
||||
|
||||
'''.splitlines(True)
|
||||
|
||||
actual_output = []
|
||||
|
||||
|
||||
def out(*lines):
|
||||
for line in lines:
|
||||
actual_output.append(line + '\n')
|
||||
|
||||
|
||||
def error(filename, linenum, *lines):
|
||||
location = filename
|
||||
if linenum != None:
|
||||
location += ":" + str(linenum)
|
||||
out(location + ': error:')
|
||||
for line in (lines):
|
||||
out(' ' + line)
|
||||
out('')
|
||||
|
||||
|
||||
class FileKind(object):
|
||||
C = 1
|
||||
CPP = 2
|
||||
INL_H = 3
|
||||
H = 4
|
||||
TBL = 5
|
||||
MSG = 6
|
||||
|
||||
@staticmethod
|
||||
def get(filename):
|
||||
if filename.endswith('.c'):
|
||||
return FileKind.C
|
||||
|
||||
if filename.endswith('.cpp'):
|
||||
return FileKind.CPP
|
||||
|
||||
if filename.endswith(('inlines.h', '-inl.h')):
|
||||
return FileKind.INL_H
|
||||
|
||||
if filename.endswith('.h'):
|
||||
return FileKind.H
|
||||
|
||||
if filename.endswith('.tbl'):
|
||||
return FileKind.TBL
|
||||
|
||||
if filename.endswith('.msg'):
|
||||
return FileKind.MSG
|
||||
|
||||
error(filename, None, 'unknown file kind')
|
||||
|
||||
|
||||
def get_all_filenames():
|
||||
"""Get a list of all the files in the (Mercurial or Git) repository."""
|
||||
cmds = [['hg', 'manifest'], ['git', 'ls-files']]
|
||||
for cmd in cmds:
|
||||
try:
|
||||
all_filenames = subprocess.check_output(cmd, universal_newlines=True,
|
||||
stderr=subprocess.PIPE).split('\n')
|
||||
return all_filenames
|
||||
except:
|
||||
continue
|
||||
else:
|
||||
raise Exception('failed to run any of the repo manifest commands', cmds)
|
||||
|
||||
|
||||
def check_style():
|
||||
# We deal with two kinds of name.
|
||||
# - A "filename" is a full path to a file from the repository root.
|
||||
# - An "inclname" is how a file is referred to in a #include statement.
|
||||
#
|
||||
# Examples (filename -> inclname)
|
||||
# - "mfbt/Attributes.h" -> "mozilla/Attributes.h"
|
||||
# - "js/public/Vector.h" -> "js/Vector.h"
|
||||
# - "js/src/vm/String.h" -> "vm/String.h"
|
||||
|
||||
mfbt_inclnames = set() # type: set(inclname)
|
||||
js_names = dict() # type: dict(filename, inclname)
|
||||
|
||||
# Select the appropriate files.
|
||||
for filename in get_all_filenames():
|
||||
if filename.startswith('mfbt/') and filename.endswith('.h'):
|
||||
inclname = 'mozilla/' + filename[len('mfbt/'):]
|
||||
mfbt_inclnames.add(inclname)
|
||||
|
||||
if filename.startswith('js/public/') and filename.endswith('.h'):
|
||||
inclname = 'js/' + filename[len('js/public/'):]
|
||||
js_names[filename] = inclname
|
||||
|
||||
if filename.startswith('js/src/') and \
|
||||
not filename.startswith(tuple(ignored_js_src_dirs)) and \
|
||||
filename.endswith(('.c', '.cpp', '.h', '.tbl', '.msg')):
|
||||
inclname = filename[len('js/src/'):]
|
||||
js_names[filename] = inclname
|
||||
|
||||
all_inclnames = mfbt_inclnames | set(js_names.values())
|
||||
|
||||
edges = dict() # type: dict(inclname, set(inclname))
|
||||
|
||||
# We don't care what's inside the MFBT files, but because they are
|
||||
# #included from JS files we have to add them to the inclusion graph.
|
||||
for inclname in mfbt_inclnames:
|
||||
edges[inclname] = set()
|
||||
|
||||
# Process all the JS files.
|
||||
for filename in js_names.keys():
|
||||
inclname = js_names[filename]
|
||||
file_kind = FileKind.get(filename)
|
||||
if file_kind == FileKind.C or file_kind == FileKind.CPP or \
|
||||
file_kind == FileKind.H or file_kind == FileKind.INL_H:
|
||||
included_h_inclnames = set() # type: set(inclname)
|
||||
|
||||
# This script is run in js/src/, so prepend '../../' to get to the root of the Mozilla
|
||||
# source tree.
|
||||
with open(os.path.join('../..', filename)) as f:
|
||||
do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclnames)
|
||||
|
||||
edges[inclname] = included_h_inclnames
|
||||
|
||||
find_cycles(all_inclnames, edges)
|
||||
|
||||
# Compare expected and actual output.
|
||||
difflines = difflib.unified_diff(expected_output, actual_output,
|
||||
fromfile='check_spider_monkey_style.py expected output',
|
||||
tofile='check_spider_monkey_style.py actual output')
|
||||
ok = True
|
||||
for diffline in difflines:
|
||||
ok = False
|
||||
print(diffline, end='')
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclnames):
|
||||
for linenum, line in enumerate(f, start=1):
|
||||
# Look for a |#include "..."| line.
|
||||
m = re.match(r'\s*#\s*include\s+"([^"]*)"', line)
|
||||
if m is not None:
|
||||
included_inclname = m.group(1)
|
||||
|
||||
if included_inclname not in included_inclnames_to_ignore:
|
||||
included_kind = FileKind.get(included_inclname)
|
||||
|
||||
# Check the #include path has the correct form.
|
||||
if included_inclname not in all_inclnames:
|
||||
error(filename, linenum,
|
||||
'"' + included_inclname + '" is included ' + 'using the wrong path;',
|
||||
'did you forget a prefix, or is the file not yet committed?')
|
||||
|
||||
# Record inclusions of .h files for cycle detection later.
|
||||
# (Exclude .tbl and .msg files.)
|
||||
elif included_kind == FileKind.H or included_kind == FileKind.INL_H:
|
||||
included_h_inclnames.add(included_inclname)
|
||||
|
||||
# Check a H file doesn't #include an INL_H file.
|
||||
if file_kind == FileKind.H and included_kind == FileKind.INL_H:
|
||||
error(filename, linenum,
|
||||
'vanilla header includes an inline-header file "' + included_inclname + '"')
|
||||
|
||||
# Check a file doesn't #include itself. (We do this here because the
|
||||
# cycle detection below doesn't detect this case.)
|
||||
if inclname == included_inclname:
|
||||
error(filename, linenum, 'the file includes itself')
|
||||
|
||||
# Look for a |#include <...>| line.
|
||||
m = re.match(r'\s*#\s*include\s+<([^>]*)>', line)
|
||||
if m is not None:
|
||||
included_inclname = m.group(1)
|
||||
|
||||
# Check it is not a known local file (in which case it's
|
||||
# probably a system header).
|
||||
if included_inclname in included_inclnames_to_ignore or \
|
||||
included_inclname in all_inclnames:
|
||||
error(filename, linenum,
|
||||
'<' + included_inclname + '> should be included using',
|
||||
'the #include "..." form')
|
||||
|
||||
|
||||
def find_cycles(all_inclnames, edges):
|
||||
"""Find and draw any cycles."""
|
||||
|
||||
SCCs = tarjan(all_inclnames, edges)
|
||||
|
||||
# The various sorted() calls below ensure the output is deterministic.
|
||||
|
||||
def draw_SCC(c):
|
||||
cset = set(c)
|
||||
drawn = set()
|
||||
def draw(v, indent):
|
||||
out(' ' * indent + ('-> ' if indent else ' ') + v)
|
||||
if v in drawn:
|
||||
return
|
||||
drawn.add(v)
|
||||
for succ in sorted(edges[v]):
|
||||
if succ in cset:
|
||||
draw(succ, indent + 1)
|
||||
draw(sorted(c)[0], 0)
|
||||
out('')
|
||||
|
||||
have_drawn_an_SCC = False
|
||||
for scc in sorted(SCCs):
|
||||
if len(scc) != 1:
|
||||
if not have_drawn_an_SCC:
|
||||
error('(multiple files)', None, 'header files form one or more cycles')
|
||||
have_drawn_an_SCC = True
|
||||
|
||||
draw_SCC(scc)
|
||||
|
||||
|
||||
# Tarjan's algorithm for finding the strongly connected components (SCCs) of a graph.
|
||||
# https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
|
||||
def tarjan(V, E):
|
||||
vertex_index = {}
|
||||
vertex_lowlink = {}
|
||||
index = 0
|
||||
S = []
|
||||
all_SCCs = []
|
||||
|
||||
def strongconnect(v, index):
|
||||
# Set the depth index for v to the smallest unused index
|
||||
vertex_index[v] = index
|
||||
vertex_lowlink[v] = index
|
||||
index += 1
|
||||
S.append(v)
|
||||
|
||||
# Consider successors of v
|
||||
for w in E[v]:
|
||||
if w not in vertex_index:
|
||||
# Successor w has not yet been visited; recurse on it
|
||||
index = strongconnect(w, index)
|
||||
vertex_lowlink[v] = min(vertex_lowlink[v], vertex_lowlink[w])
|
||||
elif w in S:
|
||||
# Successor w is in stack S and hence in the current SCC
|
||||
vertex_lowlink[v] = min(vertex_lowlink[v], vertex_index[w])
|
||||
|
||||
# If v is a root node, pop the stack and generate an SCC
|
||||
if vertex_lowlink[v] == vertex_index[v]:
|
||||
i = S.index(v)
|
||||
scc = S[i:]
|
||||
del S[i:]
|
||||
all_SCCs.append(scc)
|
||||
|
||||
return index
|
||||
|
||||
for v in V:
|
||||
if v not in vertex_index:
|
||||
index = strongconnect(v, index)
|
||||
|
||||
return all_SCCs
|
||||
|
||||
|
||||
def main():
|
||||
ok = check_style()
|
||||
|
||||
if ok:
|
||||
print('TEST-PASS | check_spidermonkey_style.py | ok')
|
||||
else:
|
||||
print('TEST-UNEXPECTED-FAIL | check_spidermonkey_style.py | actual output does not match expected output; diff is above')
|
||||
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -442,7 +442,7 @@ define SUBMAKE # $(call SUBMAKE,target,directory,static)
|
|||
endef # The extra line is important here! don't delete it
|
||||
|
||||
define TIER_DIR_SUBMAKE
|
||||
@echo "BUILDSTATUS TIERDIR_START $(2)"
|
||||
@echo "BUILDSTATUS TIERDIR_START $(2)"
|
||||
$(call SUBMAKE,$(1),$(2),$(3))
|
||||
@echo "BUILDSTATUS TIERDIR_FINISH $(2)"
|
||||
|
||||
|
|
|
@ -9125,7 +9125,7 @@ if test -n "$MOZ_WEBRTC"; then
|
|||
AC_MSG_RESULT("generating WebRTC Makefiles...")
|
||||
|
||||
if test "${MOZ_WIDGET_TOOLKIT}" = "gonk"; then
|
||||
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D build_with_gonk=1 -D include_internal_audio_device=0"
|
||||
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D build_with_gonk=1"
|
||||
fi
|
||||
|
||||
dnl Any --include files must also appear in -D FORCED_INCLUDE_FILE= entries
|
||||
|
|
|
@ -6704,6 +6704,14 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
|||
int32_t idx = parent->IndexOf(adoptedNode);
|
||||
MOZ_ASSERT(idx >= 0);
|
||||
parent->RemoveChildAt(idx, true);
|
||||
} else {
|
||||
MOZ_ASSERT(!adoptedNode->IsInDoc());
|
||||
|
||||
// If we're adopting a node that's not in a document, it might still
|
||||
// have a binding applied. Remove the binding from the element now
|
||||
// that it's getting adopted into a new document.
|
||||
// TODO Fully tear down the binding.
|
||||
adoptedNode->AsContent()->SetXBLBinding(nullptr);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -3389,6 +3389,19 @@ nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObje
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsObjectLoadingContent::GetOwnPropertyNames(JSContext* aCx,
|
||||
nsTArray<nsString>& /* unused */,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Just like DoNewResolve, just make sure we're instantiated. That will do
|
||||
// the work our Enumerate hook needs to do, and we don't want to return these
|
||||
// property names from Xrays anyway.
|
||||
nsRefPtr<nsNPAPIPluginInstance> pi;
|
||||
aRv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
|
||||
}
|
||||
|
||||
|
||||
// SetupProtoChainRunner implementation
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
|
||||
nsIScriptContext* scriptContext,
|
||||
|
|
|
@ -151,6 +151,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
// Helper for WebIDL enumeration
|
||||
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& /* unused */,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// WebIDL API
|
||||
nsIDocument* GetContentDocument();
|
||||
|
|
|
@ -55,8 +55,7 @@ bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* context)
|
|||
{
|
||||
gl::GLContext * gl = context->GL();
|
||||
|
||||
if (!gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::EXT_draw_buffers
|
||||
: GLContext::ARB_draw_buffers)) {
|
||||
if (!gl->IsExtensionSupported(GLContext::XXX_draw_buffers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,7 @@ bool WebGLExtensionVertexArray::IsSupported(const WebGLContext* context)
|
|||
{
|
||||
gl::GLContext* gl = context->GL();
|
||||
|
||||
if (gl->IsGLES2()) {
|
||||
return gl->IsExtensionSupported(gl::GLContext::OES_vertex_array_object);
|
||||
}
|
||||
|
||||
return gl->IsExtensionSupported(gl::GLContext::ARB_vertex_array_object) ||
|
||||
gl->IsExtensionSupported(gl::GLContext::APPLE_vertex_array_object);
|
||||
return gl->IsExtensionSupported(gl::GLContext::XXX_vertex_array_object);
|
||||
}
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray)
|
||||
|
|
|
@ -21,6 +21,7 @@ include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
|||
|
||||
ifdef MOZ_WEBRTC
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/media/webrtc/trunk \
|
||||
-I$(topsrcdir)/media/webrtc/trunk/webrtc \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/common \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/common/browser_logging \
|
||||
|
|
|
@ -88,7 +88,7 @@ AlarmsManager.prototype = {
|
|||
remove: function remove(aId) {
|
||||
debug("remove()");
|
||||
|
||||
return this._cpmm.sendSyncMessage(
|
||||
this._cpmm.sendAsyncMessage(
|
||||
"AlarmsManager:Remove",
|
||||
{ id: aId, manifestURL: this._manifestURL }
|
||||
);
|
||||
|
@ -156,20 +156,26 @@ AlarmsManager.prototype = {
|
|||
debug("init()");
|
||||
|
||||
// Set navigator.mozAlarms to null.
|
||||
if (!Services.prefs.getBoolPref("dom.mozAlarms.enabled"))
|
||||
if (!Services.prefs.getBoolPref("dom.mozAlarms.enabled")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only pages with perm set can use the alarms.
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
let perm = Services.perms.testExactPermissionFromPrincipal(principal, "alarms");
|
||||
if (perm != Ci.nsIPermissionManager.ALLOW_ACTION)
|
||||
let perm =
|
||||
Services.perms.testExactPermissionFromPrincipal(principal, "alarms");
|
||||
if (perm != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
|
||||
this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
|
||||
// Add the valid messages to be listened.
|
||||
this.initDOMRequestHelper(aWindow, ["AlarmsManager:Add:Return:OK", "AlarmsManager:Add:Return:KO",
|
||||
"AlarmsManager:GetAll:Return:OK", "AlarmsManager:GetAll:Return:KO"]);
|
||||
this.initDOMRequestHelper(aWindow, ["AlarmsManager:Add:Return:OK",
|
||||
"AlarmsManager:Add:Return:KO",
|
||||
"AlarmsManager:GetAll:Return:OK",
|
||||
"AlarmsManager:GetAll:Return:KO"]);
|
||||
|
||||
// Get the manifest URL if this is an installed app
|
||||
let appsService = Cc["@mozilla.org/AppsService;1"]
|
||||
|
|
|
@ -1456,7 +1456,7 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
|||
return true;
|
||||
}
|
||||
|
||||
nsScriptNameSpaceManager *nameSpaceManager =
|
||||
nsScriptNameSpaceManager* nameSpaceManager =
|
||||
nsJSRuntime::GetNameSpaceManager();
|
||||
if (!nameSpaceManager) {
|
||||
return Throw<true>(aCx, NS_ERROR_NOT_INITIALIZED);
|
||||
|
@ -1550,6 +1550,29 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
|||
return true;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
SaveNavigatorName(const nsAString& aName, void* aClosure)
|
||||
{
|
||||
nsTArray<nsString>* arr = static_cast<nsTArray<nsString>*>(aClosure);
|
||||
arr->AppendElement(aName);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsScriptNameSpaceManager *nameSpaceManager =
|
||||
nsJSRuntime::GetNameSpaceManager();
|
||||
if (!nameSpaceManager) {
|
||||
NS_ERROR("Can't get namespace manager.");
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
nameSpaceManager->EnumerateNavigatorNames(SaveNavigatorName, &aNames);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Navigator::WrapObject(JSContext* cx, JS::Handle<JSObject*> scope)
|
||||
{
|
||||
|
|
|
@ -243,6 +243,8 @@ public:
|
|||
#endif // MOZ_MEDIA_NAVIGATOR
|
||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId, JS::MutableHandle<JS::Value> aValue);
|
||||
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// WebIDL helper methods
|
||||
static bool HasBatterySupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||
|
|
|
@ -787,27 +787,34 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
|
|||
}
|
||||
}
|
||||
|
||||
struct GlobalNameClosure
|
||||
struct NameClosure
|
||||
{
|
||||
nsScriptNameSpaceManager::GlobalNameEnumerator enumerator;
|
||||
nsScriptNameSpaceManager::NameEnumerator enumerator;
|
||||
void* closure;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
EnumerateGlobalName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t,
|
||||
void* aClosure)
|
||||
EnumerateName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t, void* aClosure)
|
||||
{
|
||||
GlobalNameMapEntry *entry = static_cast<GlobalNameMapEntry *>(hdr);
|
||||
GlobalNameClosure* closure = static_cast<GlobalNameClosure*>(aClosure);
|
||||
NameClosure* closure = static_cast<NameClosure*>(aClosure);
|
||||
return closure->enumerator(entry->mKey, closure->closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptNameSpaceManager::EnumerateGlobalNames(GlobalNameEnumerator aEnumerator,
|
||||
nsScriptNameSpaceManager::EnumerateGlobalNames(NameEnumerator aEnumerator,
|
||||
void* aClosure)
|
||||
{
|
||||
GlobalNameClosure closure = { aEnumerator, aClosure };
|
||||
PL_DHashTableEnumerate(&mGlobalNames, EnumerateGlobalName, &closure);
|
||||
NameClosure closure = { aEnumerator, aClosure };
|
||||
PL_DHashTableEnumerate(&mGlobalNames, EnumerateName, &closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptNameSpaceManager::EnumerateNavigatorNames(NameEnumerator aEnumerator,
|
||||
void* aClosure)
|
||||
{
|
||||
NameClosure closure = { aEnumerator, aClosure };
|
||||
PL_DHashTableEnumerate(&mNavigatorNames, EnumerateName, &closure);
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
|
|
@ -152,10 +152,12 @@ public:
|
|||
mozilla::dom::ConstructorEnabled* aConstructorEnabled);
|
||||
|
||||
typedef PLDHashOperator
|
||||
(* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure);
|
||||
(* NameEnumerator)(const nsAString& aGlobalName, void* aClosure);
|
||||
|
||||
void EnumerateGlobalNames(GlobalNameEnumerator aEnumerator,
|
||||
void EnumerateGlobalNames(NameEnumerator aEnumerator,
|
||||
void* aClosure);
|
||||
void EnumerateNavigatorNames(NameEnumerator aEnumerator,
|
||||
void* aClosure);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <algorithm>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "JavaScriptParent.h"
|
||||
|
||||
#include "prprf.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
|
@ -1746,6 +1748,17 @@ InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
|
|||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> unwrapped(cx, js::CheckedUnwrap(instance, true));
|
||||
if (unwrapped && jsipc::JavaScriptParent::IsCPOW(unwrapped)) {
|
||||
bool boolp = false;
|
||||
if (!jsipc::JavaScriptParent::DOMInstanceOf(unwrapped, clasp->mPrototypeID,
|
||||
clasp->mDepth, &boolp)) {
|
||||
return false;
|
||||
}
|
||||
*bp = boolp;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> protov(cx);
|
||||
DebugOnly<bool> ok = JS_GetProperty(cx, obj, "prototype", &protov);
|
||||
MOZ_ASSERT(ok, "Someone messed with our prototype property?");
|
||||
|
@ -1787,6 +1800,21 @@ InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::MutableHandle
|
|||
return InterfaceHasInstance(cx, obj, instanceObject, bp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
|
||||
JS::Handle<JSObject*> instance,
|
||||
JSBool* bp)
|
||||
{
|
||||
const DOMClass* domClass = GetDOMClass(js::UncheckedUnwrap(instance));
|
||||
|
||||
MOZ_ASSERT(!domClass || prototypeID != prototypes::id::_ID_Count,
|
||||
"Why do we have a hasInstance hook if we don't have a prototype "
|
||||
"ID?");
|
||||
|
||||
*bp = (domClass && domClass->mInterfaceChain[depth] == prototypeID);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
|
|
|
@ -2074,6 +2074,10 @@ InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
|
|||
JSBool
|
||||
InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JS::Value> vp,
|
||||
JSBool* bp);
|
||||
JSBool
|
||||
InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
|
||||
JS::Handle<JSObject*> instance,
|
||||
JSBool* bp);
|
||||
|
||||
// Helper for lenient getters/setters to report to console. If this
|
||||
// returns false, we couldn't even get a global.
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
# true for workers, false otherwise).
|
||||
# * customFinalize - The native class will use a custom finalize hook
|
||||
# (defaults to true for workers, false otherwise).
|
||||
# * wantsQI - Indicates whether the interface should have a QueryInterface
|
||||
# method available to chrome.
|
||||
# * notflattened - The native type does not have nsIClassInfo, so when
|
||||
# wrapping it the right IID needs to be passed in.
|
||||
# * register - True if this binding should be registered. Defaults to true.
|
||||
|
@ -605,9 +607,11 @@ DOMInterfaces = {
|
|||
'workers': True,
|
||||
}],
|
||||
|
||||
'ImageData': {
|
||||
'wrapperCache': False
|
||||
},
|
||||
'ImageData': [
|
||||
{
|
||||
'wrapperCache': False,
|
||||
'wantsQI': False,
|
||||
}],
|
||||
|
||||
'InputStream': [
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ CONSTRUCT_HOOK_NAME = '_constructor'
|
|||
LEGACYCALLER_HOOK_NAME = '_legacycaller'
|
||||
HASINSTANCE_HOOK_NAME = '_hasInstance'
|
||||
NEWRESOLVE_HOOK_NAME = '_newResolve'
|
||||
ENUMERATE_HOOK_NAME= '_enumerate'
|
||||
ENUM_ENTRY_VARIABLE_NAME = 'strings'
|
||||
|
||||
def replaceFileIfChanged(filename, newContents):
|
||||
|
@ -88,7 +89,7 @@ class CGNativePropertyHooks(CGThing):
|
|||
enumerateOwnProperties = "EnumerateOwnProperties"
|
||||
elif self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
resolveOwnProperty = "ResolveOwnPropertyViaNewresolve"
|
||||
enumerateOwnProperties = "nullptr"
|
||||
enumerateOwnProperties = "EnumerateOwnPropertiesViaGetOwnPropertyNames"
|
||||
else:
|
||||
resolveOwnProperty = "nullptr"
|
||||
enumerateOwnProperties = "nullptr"
|
||||
|
@ -173,8 +174,10 @@ class CGDOMJSClass(CGThing):
|
|||
if self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
newResolveHook = "(JSResolveOp)" + NEWRESOLVE_HOOK_NAME
|
||||
classFlags += " | JSCLASS_NEW_RESOLVE"
|
||||
enumerateHook = ENUMERATE_HOOK_NAME
|
||||
else:
|
||||
newResolveHook = "JS_ResolveStub"
|
||||
enumerateHook = "JS_EnumerateStub"
|
||||
return """
|
||||
DOMJSClass Class = {
|
||||
{ "%s",
|
||||
|
@ -183,8 +186,8 @@ DOMJSClass Class = {
|
|||
JS_DeletePropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
%s,
|
||||
%s, /* enumerate */
|
||||
%s, /* resolve */
|
||||
JS_ConvertStub,
|
||||
%s, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
|
@ -199,7 +202,7 @@ DOMJSClass Class = {
|
|||
""" % (self.descriptor.interface.identifier.name,
|
||||
classFlags,
|
||||
ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'JS_PropertyStub',
|
||||
newResolveHook, FINALIZE_HOOK_NAME, callHook, traceHook,
|
||||
enumerateHook, newResolveHook, FINALIZE_HOOK_NAME, callHook, traceHook,
|
||||
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
|
||||
|
||||
def PrototypeIDAndDepth(descriptor):
|
||||
|
@ -647,13 +650,15 @@ class CGHeaders(CGWrapper):
|
|||
for desc in descriptors:
|
||||
if desc.interface.isExternal():
|
||||
continue
|
||||
for m in desc.interface.members:
|
||||
func = PropertyDefiner.getStringAttr(m, "Func")
|
||||
def addHeaderForFunc(func):
|
||||
# Include the right class header, which we can only do
|
||||
# if this is a class member function.
|
||||
if func is not None and "::" in func:
|
||||
# Strip out the function name and convert "::" to "/"
|
||||
bindingHeaders.add("/".join(func.split("::")[:-1]) + ".h")
|
||||
for m in desc.interface.members:
|
||||
addHeaderForFunc(PropertyDefiner.getStringAttr(m, "Func"))
|
||||
addHeaderForFunc(desc.interface.getExtendedAttribute("Func"))
|
||||
|
||||
for d in dictionaries:
|
||||
if d.parent:
|
||||
|
@ -1369,21 +1374,6 @@ def overloadLength(arguments):
|
|||
def methodLength(method):
|
||||
signatures = method.signatures()
|
||||
return min(overloadLength(arguments) for (retType, arguments) in signatures)
|
||||
def requiresQueryInterfaceMethod(descriptor):
|
||||
# Make sure to not stick QueryInterface on abstract interfaces that
|
||||
# have hasXPConnectImpls (like EventTarget). So only put it on
|
||||
# interfaces that are concrete and all of whose ancestors are abstract.
|
||||
def allAncestorsAbstract(iface):
|
||||
if not iface.parent:
|
||||
return True
|
||||
desc = descriptor.getDescriptor(iface.parent.identifier.name)
|
||||
if desc.concrete:
|
||||
return False
|
||||
return allAncestorsAbstract(iface.parent)
|
||||
return (not descriptor.workers and
|
||||
descriptor.interface.hasInterfacePrototypeObject() and
|
||||
descriptor.concrete and
|
||||
allAncestorsAbstract(descriptor.interface))
|
||||
|
||||
class MethodDefiner(PropertyDefiner):
|
||||
"""
|
||||
|
@ -1425,7 +1415,7 @@ class MethodDefiner(PropertyDefiner):
|
|||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": MemberCondition(None, None) })
|
||||
|
||||
if not static and requiresQueryInterfaceMethod(descriptor):
|
||||
if not static and descriptor.wantsQI():
|
||||
condition = "WantsQueryInterface<%s>::Enabled" % descriptor.nativeType
|
||||
self.regular.append({"name": 'QueryInterface',
|
||||
"methodInfo": False,
|
||||
|
@ -1720,7 +1710,9 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
if len(idsToInit) > 1:
|
||||
initIds = CGWrapper(initIds, pre="(", post=")", reindent=True)
|
||||
initIds = CGList(
|
||||
[CGGeneric("%s_ids[0] == JSID_VOID &&" % idsToInit[0]), initIds],
|
||||
[CGGeneric("%s_ids[0] == JSID_VOID &&" % idsToInit[0]),
|
||||
CGGeneric("NS_IsMainThread() &&"),
|
||||
initIds],
|
||||
"\n")
|
||||
initIds = CGWrapper(initIds, pre="if (", post=") {", reindent=True)
|
||||
initIds = CGList(
|
||||
|
@ -1950,7 +1942,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
|||
|
||||
""" + getConstructor)
|
||||
|
||||
class CGPrefEnabledNative(CGAbstractMethod):
|
||||
class CGConstructorEnabledViaPrefEnabled(CGAbstractMethod):
|
||||
"""
|
||||
A method for testing whether the preference controlling this
|
||||
interface is enabled. This delegates to PrefEnabled() on the
|
||||
|
@ -1967,7 +1959,7 @@ class CGPrefEnabledNative(CGAbstractMethod):
|
|||
def definition_body(self):
|
||||
return " return %s::PrefEnabled();" % self.descriptor.nativeType
|
||||
|
||||
class CGPrefEnabled(CGAbstractMethod):
|
||||
class CGConstructorEnabledViaPref(CGAbstractMethod):
|
||||
"""
|
||||
A method for testing whether the preference controlling this
|
||||
interface is enabled. This generates code in the binding to
|
||||
|
@ -2002,6 +1994,22 @@ class CGConstructorEnabledChromeOnly(CGAbstractMethod):
|
|||
def definition_body(self):
|
||||
return " return %s;" % GetAccessCheck(self.descriptor, "aObj")
|
||||
|
||||
class CGConstructorEnabledViaFunc(CGAbstractMethod):
|
||||
"""
|
||||
A method for testing whether the interface object should be exposed on a
|
||||
given global based on whatever the callee wants to consider.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
CGAbstractMethod.__init__(self, descriptor,
|
||||
'ConstructorEnabled', 'bool',
|
||||
[Argument("JSContext*", "cx"),
|
||||
Argument("JS::Handle<JSObject*>", "obj")])
|
||||
|
||||
def definition_body(self):
|
||||
func = self.descriptor.interface.getExtendedAttribute("Func")
|
||||
assert isinstance(func, list) and len(func) == 1
|
||||
return " return %s(cx, obj);" % func[0]
|
||||
|
||||
class CGIsMethod(CGAbstractMethod):
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSObject*', 'obj')]
|
||||
|
@ -2148,7 +2156,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
|||
self.properties = properties
|
||||
|
||||
def definition_body(self):
|
||||
if self.descriptor.workers:
|
||||
if self.descriptor.nativeOwnership == 'worker':
|
||||
return """ return aObject->GetJSObject();"""
|
||||
|
||||
assertISupportsInheritance = (
|
||||
|
@ -5336,20 +5344,15 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
|||
NewResolve hook for our object
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
self._needNewResolve = descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||
assert descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||
args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'obj'),
|
||||
Argument('JS::Handle<jsid>', 'id'), Argument('unsigned', 'flags'),
|
||||
Argument('JS::MutableHandle<JSObject*>', 'objp')]
|
||||
# Our "self" is actually the callee in this case, not the thisval.
|
||||
# Our "self" is actually the "obj" argument in this case, not the thisval.
|
||||
CGAbstractBindingMethod.__init__(
|
||||
self, descriptor, NEWRESOLVE_HOOK_NAME,
|
||||
args, getThisObj="", callArgs="")
|
||||
|
||||
def define(self):
|
||||
if not self._needNewResolve:
|
||||
return ""
|
||||
return CGAbstractBindingMethod.define(self)
|
||||
|
||||
def generate_code(self):
|
||||
return CGIndenter(CGGeneric(
|
||||
"JS::Rooted<JS::Value> value(cx);\n"
|
||||
|
@ -5365,6 +5368,36 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
|||
"objp.set(obj);\n"
|
||||
"return true;"))
|
||||
|
||||
class CGEnumerateHook(CGAbstractBindingMethod):
|
||||
"""
|
||||
Enumerate hook for our object
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
assert descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'obj')]
|
||||
# Our "self" is actually the "obj" argument in this case, not the thisval.
|
||||
CGAbstractBindingMethod.__init__(
|
||||
self, descriptor, ENUMERATE_HOOK_NAME,
|
||||
args, getThisObj="", callArgs="")
|
||||
|
||||
def generate_code(self):
|
||||
return CGIndenter(CGGeneric(
|
||||
"nsAutoTArray<nsString, 8> names;\n"
|
||||
"ErrorResult rv;\n"
|
||||
"self->GetOwnPropertyNames(cx, names, rv);\n"
|
||||
"rv.WouldReportJSException();\n"
|
||||
"if (rv.Failed()) {\n"
|
||||
' return ThrowMethodFailedWithDetails<true>(cx, rv, "%s", "enumerate");\n'
|
||||
"}\n"
|
||||
"JS::Rooted<JS::Value> dummy(cx);\n"
|
||||
"for (uint32_t i = 0; i < names.Length(); ++i) {\n"
|
||||
" if (!JS_LookupUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"return true;"))
|
||||
|
||||
class CppKeywords():
|
||||
"""
|
||||
A class for checking if method names declared in webidl
|
||||
|
@ -6920,6 +6953,33 @@ class CGEnumerateOwnProperties(CGAbstractStaticMethod):
|
|||
return """ return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
|
||||
"""
|
||||
|
||||
class CGEnumerateOwnPropertiesViaGetOwnPropertyNames(CGAbstractBindingMethod):
|
||||
"""
|
||||
An implementation of Xray EnumerateOwnProperties stuff for things
|
||||
that have a newresolve hook.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
||||
Argument('JS::Handle<JSObject*>', 'obj'),
|
||||
Argument('JS::AutoIdVector&', 'props')]
|
||||
CGAbstractBindingMethod.__init__(self, descriptor,
|
||||
"EnumerateOwnPropertiesViaGetOwnPropertyNames",
|
||||
args, getThisObj="",
|
||||
callArgs="", returnType="bool")
|
||||
def generate_code(self):
|
||||
return CGIndenter(CGGeneric(
|
||||
"nsAutoTArray<nsString, 8> names;\n"
|
||||
"ErrorResult rv;\n"
|
||||
"self->GetOwnPropertyNames(cx, names, rv);\n"
|
||||
"rv.WouldReportJSException();\n"
|
||||
"if (rv.Failed()) {\n"
|
||||
' return ThrowMethodFailedWithDetails<true>(cx, rv, "%s", "enumerate");\n'
|
||||
"}\n"
|
||||
'// OK to pass null as "proxy" because it\'s ignored if\n'
|
||||
"// shadowPrototypeProperties is true\n"
|
||||
"return DOMProxyHandler::AppendNamedPropertyIds(cx, JS::NullPtr(), names, true, nullptr, props);"))
|
||||
|
||||
class CGPrototypeTraitsClass(CGClass):
|
||||
def __init__(self, descriptor, indent=''):
|
||||
templateArgs = [Argument('prototypes::ID', 'PrototypeID')]
|
||||
|
@ -7488,7 +7548,7 @@ for (int32_t i = 0; i < int32_t(length); ++i) {
|
|||
addNames = """
|
||||
nsTArray<nsString> names;
|
||||
UnwrapProxy(proxy)->GetSupportedNames(names);
|
||||
if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
|
||||
if (!AppendNamedPropertyIds(cx, proxy, names, %s, this, props)) {
|
||||
return false;
|
||||
}
|
||||
""" % shadow
|
||||
|
@ -7882,6 +7942,7 @@ class CGDescriptor(CGThing):
|
|||
cgThings.append(CGEnumerateOwnProperties(descriptor))
|
||||
elif descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
cgThings.append(CGResolveOwnPropertyViaNewresolve(descriptor))
|
||||
cgThings.append(CGEnumerateOwnPropertiesViaGetOwnPropertyNames(descriptor))
|
||||
|
||||
# Now that we have our ResolveOwnProperty/EnumerateOwnProperties stuff
|
||||
# done, set up our NativePropertyHooks.
|
||||
|
@ -7897,7 +7958,9 @@ class CGDescriptor(CGThing):
|
|||
cgThings.append(CGNamedConstructors(descriptor))
|
||||
|
||||
cgThings.append(CGLegacyCallHook(descriptor))
|
||||
cgThings.append(CGNewResolveHook(descriptor))
|
||||
if descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
cgThings.append(CGNewResolveHook(descriptor))
|
||||
cgThings.append(CGEnumerateHook(descriptor))
|
||||
|
||||
if descriptor.interface.hasInterfacePrototypeObject():
|
||||
cgThings.append(CGPrototypeJSClass(descriptor, properties))
|
||||
|
@ -7918,17 +7981,21 @@ class CGDescriptor(CGThing):
|
|||
prefControlled = descriptor.interface.getExtendedAttribute("PrefControlled")
|
||||
havePref = descriptor.interface.getExtendedAttribute("Pref")
|
||||
haveChromeOnly = descriptor.interface.getExtendedAttribute("ChromeOnly")
|
||||
haveFunc = descriptor.interface.getExtendedAttribute("Func")
|
||||
# Make sure at most one of those is set
|
||||
if bool(prefControlled) + bool(havePref) + bool(haveChromeOnly) > 1:
|
||||
if (bool(prefControlled) + bool(havePref) +
|
||||
bool(haveChromeOnly) + bool(haveFunc) > 1):
|
||||
raise TypeError("Interface %s has more than one of "
|
||||
"'PrefControlled', 'Pref', and 'ChomeOnly' "
|
||||
"specified", descriptor.name)
|
||||
"'PrefControlled', 'Pref', 'Func', and "
|
||||
"'ChomeOnly' specified", descriptor.name)
|
||||
if prefControlled is not None:
|
||||
cgThings.append(CGPrefEnabledNative(descriptor))
|
||||
cgThings.append(CGConstructorEnabledViaPrefEnabled(descriptor))
|
||||
elif havePref is not None:
|
||||
cgThings.append(CGPrefEnabled(descriptor))
|
||||
cgThings.append(CGConstructorEnabledViaPref(descriptor))
|
||||
elif haveChromeOnly is not None:
|
||||
cgThings.append(CGConstructorEnabledChromeOnly(descriptor))
|
||||
elif haveFunc is not None:
|
||||
cgThings.append(CGConstructorEnabledViaFunc(descriptor))
|
||||
|
||||
if descriptor.concrete:
|
||||
if descriptor.proxy:
|
||||
|
@ -8454,7 +8521,8 @@ class CGRegisterProtos(CGAbstractMethod):
|
|||
def getCheck(desc):
|
||||
if (desc.interface.getExtendedAttribute("PrefControlled") is None and
|
||||
desc.interface.getExtendedAttribute("Pref") is None and
|
||||
desc.interface.getExtendedAttribute("ChromeOnly") is None):
|
||||
desc.interface.getExtendedAttribute("ChromeOnly") is None and
|
||||
desc.interface.getExtendedAttribute("Func") is None):
|
||||
return "nullptr"
|
||||
return "%sBinding::ConstructorEnabled" % desc.name
|
||||
lines = []
|
||||
|
|
|
@ -358,11 +358,7 @@ class Descriptor(DescriptorProvider):
|
|||
iface = iface.parent
|
||||
self.operations = operations
|
||||
|
||||
if self.workers:
|
||||
if desc.get('nativeOwnership', 'worker') != 'worker':
|
||||
raise TypeError("Worker descriptor for %s should have 'worker' "
|
||||
"as value for nativeOwnership" %
|
||||
self.interface.identifier.name)
|
||||
if self.workers and desc.get('nativeOwnership', 'worker') == 'worker':
|
||||
self.nativeOwnership = "worker"
|
||||
else:
|
||||
self.nativeOwnership = desc.get('nativeOwnership', 'refcounted')
|
||||
|
@ -372,8 +368,10 @@ class Descriptor(DescriptorProvider):
|
|||
(self.interface.identifier.name, self.nativeOwnership))
|
||||
self.customTrace = desc.get('customTrace', self.workers)
|
||||
self.customFinalize = desc.get('customFinalize', self.workers)
|
||||
if desc.get('wantsQI', None) != None:
|
||||
self._wantsQI = desc.get('wantsQI', None)
|
||||
self.wrapperCache = (not self.interface.isCallback() and
|
||||
(self.workers or
|
||||
(self.nativeOwnership == 'worker' or
|
||||
(self.nativeOwnership != 'owned' and
|
||||
desc.get('wrapperCache', True))))
|
||||
|
||||
|
@ -488,6 +486,26 @@ class Descriptor(DescriptorProvider):
|
|||
self.interface.getExtendedAttribute("PrefControlled") or
|
||||
self.interface.hasInterfacePrototypeObject())
|
||||
|
||||
def wantsQI(self):
|
||||
# If it was specified explicitly use that.
|
||||
if hasattr(self, '_wantsQI'):
|
||||
return self._wantsQI
|
||||
|
||||
# Make sure to not stick QueryInterface on abstract interfaces that
|
||||
# have hasXPConnectImpls (like EventTarget). So only put it on
|
||||
# interfaces that are concrete and all of whose ancestors are abstract.
|
||||
def allAncestorsAbstract(iface):
|
||||
if not iface.parent:
|
||||
return True
|
||||
desc = self.getDescriptor(iface.parent.identifier.name)
|
||||
if desc.concrete:
|
||||
return False
|
||||
return allAncestorsAbstract(iface.parent)
|
||||
return (not self.workers and
|
||||
self.interface.hasInterfacePrototypeObject() and
|
||||
self.concrete and
|
||||
allAncestorsAbstract(self.interface))
|
||||
|
||||
# Some utility methods
|
||||
def getTypesFromDescriptor(descriptor):
|
||||
"""
|
||||
|
|
|
@ -266,11 +266,13 @@ DOMProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid
|
|||
return ok;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
nsTArray<nsString>& names,
|
||||
bool shadowPrototypeProperties,
|
||||
DOMProxyHandler* handler,
|
||||
JS::AutoIdVector& props)
|
||||
{
|
||||
for (uint32_t i = 0; i < names.Length(); ++i) {
|
||||
|
@ -285,7 +287,7 @@ DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
|
|||
}
|
||||
|
||||
if (shadowPrototypeProperties ||
|
||||
!HasPropertyOnPrototype(cx, proxy, this, id)) {
|
||||
!HasPropertyOnPrototype(cx, proxy, handler, id)) {
|
||||
if (!props.append(id)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -77,14 +77,15 @@ public:
|
|||
|
||||
const DOMClass& mClass;
|
||||
|
||||
protected:
|
||||
// Append the property names in "names" to "props". If
|
||||
// shadowPrototypeProperties is false then skip properties that are also
|
||||
// present on our proto chain.
|
||||
bool AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
nsTArray<nsString>& names,
|
||||
bool shadowPrototypeProperties,
|
||||
JS::AutoIdVector& props);
|
||||
// present on our proto chain. If shadowPrototypeProperties is true,
|
||||
// then the "proxy" and "handler" arguments are ignored.
|
||||
static bool AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
nsTArray<nsString>& names,
|
||||
bool shadowPrototypeProperties,
|
||||
DOMProxyHandler* handler,
|
||||
JS::AutoIdVector& props);
|
||||
};
|
||||
|
||||
extern jsid s_length_id;
|
||||
|
|
|
@ -74,6 +74,7 @@ endif
|
|||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
|
||||
-I$(topsrcdir)/js/xpconnect/wrappers \
|
||||
-I$(topsrcdir)/js/ipc \
|
||||
-I$(topsrcdir)/content/canvas/src \
|
||||
-I$(topsrcdir)/content/html/content/src \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
|
||||
|
|
|
@ -932,7 +932,8 @@ class IDLInterface(IDLObjectWithScope):
|
|||
elif (identifier == "Pref" or
|
||||
identifier == "JSImplementation" or
|
||||
identifier == "HeaderFile" or
|
||||
identifier == "NavigatorProperty"):
|
||||
identifier == "NavigatorProperty" or
|
||||
identifier == "Func"):
|
||||
# Known extended attributes that take a string value
|
||||
if not attr.hasValue():
|
||||
raise WebIDLError("[%s] must have a value" % identifier,
|
||||
|
|
|
@ -63,6 +63,7 @@ MOCHITEST_FILES := \
|
|||
forOf_iframe.html \
|
||||
test_sequence_wrapping.html \
|
||||
file_bug775543.html \
|
||||
file_bug707564.html \
|
||||
test_bug788369.html \
|
||||
test_bug742191.html \
|
||||
test_namedNoIndexed.html \
|
||||
|
@ -75,10 +76,12 @@ MOCHITEST_FILES := \
|
|||
test_lenientThis.html \
|
||||
test_ByteString.html \
|
||||
test_exception_messages.html \
|
||||
test_bug707564.html \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_bug775543.html \
|
||||
test_bug707564-chrome.html \
|
||||
$(NULL)
|
||||
|
||||
ifdef GNU_CC
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<body>
|
||||
<script>
|
||||
navigator.foopy = 5;
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=707564
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 707564</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707564">Mozilla Bug 707564</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="t1" src="http://example.org/tests/dom/bindings/test/file_bug707564.html"></iframe>
|
||||
<iframe id="t2" src="http://example.org/tests/dom/bindings/test/file_bug707564.html"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 775543 **/
|
||||
function test()
|
||||
{
|
||||
var nav = document.getElementById("t1").contentWindow.navigator;
|
||||
ise(nav.foopy, undefined, "We should have an Xray now");
|
||||
is(nav.wrappedJSObject.foopy, 5, "We should have the right navigator object");
|
||||
var props = Object.getOwnPropertyNames(nav);
|
||||
isnot(props.indexOf("mozApps"), -1,
|
||||
"Should enumerate a mozApps property on navigator xray");
|
||||
|
||||
var nav = document.getElementById("t2").contentWindow.navigator;
|
||||
ise(nav.foopy, undefined, "We should have an Xray now again");
|
||||
is(nav.wrappedJSObject.foopy, 5, "We should have the right navigator object again");
|
||||
var found = false;
|
||||
for (var name in nav) {
|
||||
if (name == "mozApps") {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
ok(found, "Should enumerate a mozApps property on navigator xray via for...in");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(test);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=707564
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 707564</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 707564 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
var props = Object.getOwnPropertyNames(frames[0].navigator);
|
||||
isnot(props.indexOf("mozApps"), -1,
|
||||
"Should enumerate a mozApps property on navigator");
|
||||
|
||||
// Now enumerate a different navigator object
|
||||
var found = false;
|
||||
for (var name in frames[1].navigator) {
|
||||
if (name == "mozApps") {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
ok(found, "Should enumerate a mozApps property on navigator via for...in");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707564">Mozilla Bug 707564</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,9 +0,0 @@
|
|||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
MODULE = 'dom'
|
||||
XPIDL_MODULE = 'dom_push'
|
||||
XPIDL_SOURCES += ['nsIDOMPushManager.idl']
|
||||
XPIDL_FLAGS += ['-I$(topsrcdir)/dom/interfaces/base']
|
|
@ -1,45 +0,0 @@
|
|||
/* 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 "domstubs.idl"
|
||||
interface nsIDOMDOMRequest;
|
||||
|
||||
/**
|
||||
* Client API for SimplePush.
|
||||
*
|
||||
* The SimplePush API allows web applications to use push notifications and be
|
||||
* woken up when something of interest has changed. This frees web applications
|
||||
* from implementing polling, giving better responsiveness and conserving the
|
||||
* device's battery life.
|
||||
*/
|
||||
[scriptable,uuid(c7ad4f42-faae-4e8b-9879-780a72349945)]
|
||||
interface nsIDOMPushManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Register for a new push endpoint.
|
||||
*
|
||||
* On success, the DOMRequest's result field will be a string URL. This URL
|
||||
* is the endpoint that can be contacted to wake up the application.
|
||||
*/
|
||||
nsIDOMDOMRequest register();
|
||||
|
||||
/**
|
||||
* Unregister a push endpoint.
|
||||
*
|
||||
* On success, the DOMRequest's result field will be the endpoint that was
|
||||
* passed in.
|
||||
*
|
||||
* Stops watching for changes to this URL.
|
||||
*/
|
||||
nsIDOMDOMRequest unregister(in ACString endpoint);
|
||||
|
||||
/**
|
||||
* Get a list of active registrations for this web app.
|
||||
*
|
||||
* On success, the DOMRequest's result field is an array of endpoints.
|
||||
* For example:
|
||||
* ["https://example.com/notify/1", "https://example.com/notify/2"]
|
||||
*/
|
||||
nsIDOMDOMRequest registrations();
|
||||
};
|
|
@ -190,6 +190,12 @@ parent:
|
|||
SetCursor(uint32_t value);
|
||||
SetBackgroundColor(nscolor color);
|
||||
|
||||
/**
|
||||
* Used to set the current text of the status tooltip.
|
||||
* Nowadays this is mainly used for link locations on hover.
|
||||
*/
|
||||
SetStatus(uint32_t type, nsString status);
|
||||
|
||||
/**
|
||||
* Initiates an asynchronous request for permission for the
|
||||
* provided principal.
|
||||
|
|
|
@ -744,8 +744,10 @@ NS_IMPL_RELEASE(TabChild)
|
|||
NS_IMETHODIMP
|
||||
TabChild::SetStatus(uint32_t aStatusType, const PRUnichar* aStatus)
|
||||
{
|
||||
// FIXME/bug 617804: should the platform support this?
|
||||
return NS_OK;
|
||||
return SetStatusWithContext(aStatusType,
|
||||
aStatus ? static_cast<const nsString &>(nsDependentString(aStatus))
|
||||
: EmptyString(),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -820,10 +822,13 @@ TabChild::ExitModalEventLoop(nsresult aStatus)
|
|||
|
||||
NS_IMETHODIMP
|
||||
TabChild::SetStatusWithContext(uint32_t aStatusType,
|
||||
const nsAString& aStatusText,
|
||||
nsISupports* aStatusContext)
|
||||
const nsAString& aStatusText,
|
||||
nsISupports* aStatusContext)
|
||||
{
|
||||
// FIXME/bug 617804: should the platform support this?
|
||||
// We can only send the status after the ipc machinery is set up,
|
||||
// mRemoteFrame is a good indicator.
|
||||
if (mRemoteFrame)
|
||||
SendSetStatus(aStatusType, nsString(aStatusText));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2208,14 +2213,19 @@ TabChild::InitRenderingState()
|
|||
if (id != 0) {
|
||||
// Pushing layers transactions directly to a separate
|
||||
// compositor context.
|
||||
PCompositorChild* compositorChild = CompositorChild::Get();
|
||||
PCompositorChild* compositorChild = CompositorChild::Get();
|
||||
if (!compositorChild) {
|
||||
NS_WARNING("failed to get CompositorChild instance");
|
||||
return false;
|
||||
}
|
||||
bool success;
|
||||
shadowManager =
|
||||
compositorChild->SendPLayerTransactionConstructor(mTextureFactoryIdentifier.mParentBackend,
|
||||
id, &mTextureFactoryIdentifier);
|
||||
id, &mTextureFactoryIdentifier, &success);
|
||||
if (!success) {
|
||||
NS_WARNING("failed to properly allocate layer transaction");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Pushing transactions to the parent content.
|
||||
shadowManager = remoteFrame->SendPLayerTransactionConstructor();
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIXULBrowserWindow.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
@ -748,6 +751,42 @@ TabParent::RecvSetBackgroundColor(const nscolor& aColor)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetStatus(const uint32_t& aType, const nsString& aStatus)
|
||||
{
|
||||
nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
|
||||
if (frame) {
|
||||
nsCOMPtr<nsISupports> container = frame->OwnerDoc()->GetContainer();
|
||||
if (!container)
|
||||
return true;
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
if (!docShell)
|
||||
return true;
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
if (!treeOwner)
|
||||
return true;
|
||||
|
||||
nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
|
||||
if (window) {
|
||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
|
||||
window->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
|
||||
if (xulBrowserWindow) {
|
||||
switch (aType)
|
||||
{
|
||||
case nsIWebBrowserChrome::STATUS_SCRIPT:
|
||||
xulBrowserWindow->SetJSStatus(aStatus);
|
||||
break;
|
||||
case nsIWebBrowserChrome::STATUS_LINK:
|
||||
xulBrowserWindow->SetOverLink(aStatus, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEFocus(const bool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
|
|
|
@ -153,6 +153,7 @@ public:
|
|||
const int32_t& aFocusChange);
|
||||
virtual bool RecvSetCursor(const uint32_t& aValue);
|
||||
virtual bool RecvSetBackgroundColor(const nscolor& aValue);
|
||||
virtual bool RecvSetStatus(const uint32_t& aType, const nsString& aStatus);
|
||||
virtual bool RecvGetDPI(float* aValue);
|
||||
virtual bool RecvGetDefaultScale(double* aValue);
|
||||
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
|
||||
|
|
|
@ -27,7 +27,6 @@ interfaces = [
|
|||
'geolocation',
|
||||
'notification',
|
||||
'permission',
|
||||
'push',
|
||||
'svg',
|
||||
'smil',
|
||||
'apps',
|
||||
|
|
|
@ -350,7 +350,12 @@ TCPSocket.prototype = {
|
|||
/* end nsITCPSocketInternal methods */
|
||||
|
||||
initWindowless: function ts_initWindowless() {
|
||||
return Services.prefs.getBoolPref("dom.mozTCPSocket.enabled");
|
||||
try {
|
||||
return Services.prefs.getBoolPref("dom.mozTCPSocket.enabled");
|
||||
} catch (e) {
|
||||
// no pref means return false
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
init: function ts_init(aWindow) {
|
||||
|
|
|
@ -17,21 +17,22 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
|
||||
const PUSH_CID = Components.ID("{c7ad4f42-faae-4e8b-9879-780a72349945}");
|
||||
const PUSH_CID = Components.ID("{cde1d019-fad8-4044-b141-65fb4fb7a245}");
|
||||
|
||||
/**
|
||||
* The Push component runs in the child process and exposes the SimplePush API
|
||||
* to the web application. The PushService running in the parent process is the
|
||||
* one actually performing all operations.
|
||||
*/
|
||||
function Push()
|
||||
{
|
||||
function Push() {
|
||||
debug("Push Constructor");
|
||||
}
|
||||
|
||||
Push.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
contractID: "@mozilla.org/push/PushManager;1",
|
||||
|
||||
classID : PUSH_CID,
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
|
||||
|
@ -40,9 +41,6 @@ Push.prototype = {
|
|||
init: function(aWindow) {
|
||||
debug("init()");
|
||||
|
||||
if (!Services.prefs.getBoolPref("services.push.enabled"))
|
||||
return null;
|
||||
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
|
||||
this._pageURL = principal.URI;
|
||||
|
@ -51,13 +49,19 @@ Push.prototype = {
|
|||
.getService(Ci.nsIAppsService);
|
||||
this._app = appsService.getAppByLocalId(principal.appId);
|
||||
this._manifestURL = appsService.getManifestURLByLocalId(principal.appId);
|
||||
if (!this._manifestURL)
|
||||
return null;
|
||||
if (!this._manifestURL) {
|
||||
// Now what? XXXbz should this be tested in a Func for this
|
||||
// interface so it wouldn't appear at all?
|
||||
return;
|
||||
}
|
||||
|
||||
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
|
||||
"push");
|
||||
if (perm != Ci.nsIPermissionManager.ALLOW_ACTION)
|
||||
return null;
|
||||
if (perm != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
// Now what? XXXbz should this be tested in a Func for this
|
||||
// interface so it wouldn't appear at all?
|
||||
return;
|
||||
}
|
||||
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
"PushService:Register:OK",
|
||||
|
@ -70,18 +74,6 @@ Push.prototype = {
|
|||
|
||||
this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
|
||||
var self = this;
|
||||
return {
|
||||
register: self.register.bind(self),
|
||||
unregister: self.unregister.bind(self),
|
||||
registrations: self.registrations.bind(self),
|
||||
__exposedProps__: {
|
||||
register: "r",
|
||||
unregister: "r",
|
||||
registrations: "r"
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# DOM API
|
||||
component {c7ad4f42-faae-4e8b-9879-780a72349945} Push.js
|
||||
contract @mozilla.org/Push;1 {c7ad4f42-faae-4e8b-9879-780a72349945}
|
||||
category JavaScript-navigator-property push @mozilla.org/Push;1
|
||||
component {cde1d019-fad8-4044-b141-65fb4fb7a245} Push.js
|
||||
contract @mozilla.org/push/PushManager;1 {cde1d019-fad8-4044-b141-65fb4fb7a245}
|
||||
|
||||
# Component to initialize PushService on startup.
|
||||
component {4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d} PushServiceLauncher.js
|
||||
contract @mozilla.org/dom/push/service;1 {4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d}
|
||||
category app-startup PushServiceLauncher @mozilla.org/dom/push/service;1
|
||||
contract @mozilla.org/push/ServiceLauncher;1 {4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d}
|
||||
category app-startup PushServiceLauncher @mozilla.org/push/ServiceLauncher;1
|
||||
|
|
|
@ -18,6 +18,8 @@ function PushServiceLauncher() {
|
|||
PushServiceLauncher.prototype = {
|
||||
classID: Components.ID("{4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d}"),
|
||||
|
||||
contractID: "@mozilla.org/push/ServiceLauncher;1",
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
|
|
|
@ -434,6 +434,27 @@ NetworkManager.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
setWifiOperationMode: function setWifiOperationMode(interfaceName, mode, callback) {
|
||||
debug("setWifiOperationMode on " + interfaceName + " to " + mode);
|
||||
|
||||
let params = {
|
||||
cmd: "setWifiOperationMode",
|
||||
ifname: interfaceName,
|
||||
mode: mode
|
||||
};
|
||||
|
||||
params.report = true;
|
||||
params.isAsync = true;
|
||||
|
||||
this.controlMessage(params, function(result) {
|
||||
if (isError(result.resultCode)) {
|
||||
callback.wifiOperationModeResult("netd command error");
|
||||
} else {
|
||||
callback.wifiOperationModeResult(null);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Helpers
|
||||
|
||||
controlMessage: function controlMessage(params, callback) {
|
||||
|
|
|
@ -166,6 +166,18 @@ function updateUpStreamFail(params) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function wifiOperationModeFail(params) {
|
||||
// Notify the main thread.
|
||||
postMessage(params);
|
||||
return true;
|
||||
}
|
||||
|
||||
function wifiOperationModeSuccess(params) {
|
||||
// Notify the main thread.
|
||||
postMessage(params);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get network interface properties from the system property table.
|
||||
*
|
||||
|
@ -801,6 +813,18 @@ function getNetworkInterfaceStats(params) {
|
|||
return true;
|
||||
}
|
||||
|
||||
let gWifiOperationModeChain = [wifiFirmwareReload,
|
||||
wifiOperationModeSuccess];
|
||||
|
||||
/**
|
||||
* handling main thread's reload Wifi firmware request
|
||||
*/
|
||||
function setWifiOperationMode(params) {
|
||||
debug("setWifiOperationMode: " + params.ifname + " " + params.mode);
|
||||
chain(params, gWifiOperationModeChain, wifiOperationModeFail);
|
||||
return true;
|
||||
}
|
||||
|
||||
let debug;
|
||||
if (DEBUG) {
|
||||
debug = function (s) {
|
||||
|
|
|
@ -108,10 +108,23 @@ interface nsINetworkStatsCallback : nsISupports
|
|||
in jsval date);
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(9ede8720-f8bc-11e2-b778-0800200c9a66)]
|
||||
interface nsIWifiOperationModeCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Callback function used to report result to WifiManager.
|
||||
*
|
||||
* @param error
|
||||
* An error message if the operation wasn't successful,
|
||||
* or `null` if it was.
|
||||
*/
|
||||
void wifiOperationModeResult(in jsval error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Manage network interfaces.
|
||||
*/
|
||||
[scriptable, uuid(f39a0fb6-2752-47d2-943e-a0cdd3e43494)]
|
||||
[scriptable, uuid(5b22c620-f8b9-11e2-b778-0800200c9a66)]
|
||||
interface nsINetworkManager : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -208,4 +221,19 @@ interface nsINetworkManager : nsISupports
|
|||
*/
|
||||
void getNetworkInterfaceStats(in DOMString networkName, in nsINetworkStatsCallback callback);
|
||||
|
||||
/**
|
||||
* Reload Wifi firmware to specific operation mode.
|
||||
*
|
||||
* @param interfaceName
|
||||
* Wifi Network interface name.
|
||||
*
|
||||
* @param mode
|
||||
* AP - Access pointer mode.
|
||||
* P2P - Peer to peer connection mode.
|
||||
* STA - Station mode.
|
||||
*
|
||||
* @param callback
|
||||
* Callback to notify Wifi firmware reload result.
|
||||
*/
|
||||
void setWifiOperationMode(in DOMString interfaceName, in DOMString mode, in nsIWifiOperationModeCallback callback);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
[NoInterfaceObject, NavigatorProperty="push", JSImplementation="@mozilla.org/push/PushManager;1", Pref="services.push.enabled"]
|
||||
interface PushManager {
|
||||
DOMRequest register();
|
||||
DOMRequest unregister(DOMString pushEndpoint);
|
||||
DOMRequest registrations();
|
||||
};
|
|
@ -226,6 +226,7 @@ webidl_files = \
|
|||
PositionError.webidl \
|
||||
ProcessingInstruction.webidl \
|
||||
Promise.webidl \
|
||||
PushManager.webidl \
|
||||
Range.webidl \
|
||||
Rect.webidl \
|
||||
RGBColor.webidl \
|
||||
|
|
|
@ -1224,36 +1224,46 @@ var WifiManager = (function() {
|
|||
null);
|
||||
|
||||
prepareForStartup(function() {
|
||||
loadDriver(function (status) {
|
||||
if (status < 0) {
|
||||
gNetworkManager.setWifiOperationMode(ifname,
|
||||
WIFI_FIRMWARE_STATION,
|
||||
function (status) {
|
||||
if (status) {
|
||||
callback(status);
|
||||
manager.state = "UNINITIALIZED";
|
||||
return;
|
||||
}
|
||||
|
||||
function doStartSupplicant() {
|
||||
cancelWaitForDriverReadyTimer();
|
||||
startSupplicant(function (status) {
|
||||
if (status < 0) {
|
||||
unloadDriver(function() {
|
||||
callback(status);
|
||||
loadDriver(function (status) {
|
||||
if (status < 0) {
|
||||
callback(status);
|
||||
manager.state = "UNINITIALIZED";
|
||||
return;
|
||||
}
|
||||
|
||||
function doStartSupplicant() {
|
||||
cancelWaitForDriverReadyTimer();
|
||||
startSupplicant(function (status) {
|
||||
if (status < 0) {
|
||||
unloadDriver(function() {
|
||||
callback(status);
|
||||
});
|
||||
manager.state = "UNINITIALIZED";
|
||||
return;
|
||||
}
|
||||
|
||||
manager.supplicantStarted = true;
|
||||
enableInterface(ifname, function (ok) {
|
||||
callback(ok ? 0 : -1);
|
||||
});
|
||||
manager.state = "UNINITIALIZED";
|
||||
return;
|
||||
}
|
||||
|
||||
manager.supplicantStarted = true;
|
||||
enableInterface(ifname, function (ok) {
|
||||
callback(ok ? 0 : -1);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Driver startup on certain platforms takes longer than it takes for us
|
||||
// to return from loadDriver, so wait 2 seconds before starting
|
||||
// the supplicant to give it a chance to start.
|
||||
createWaitForDriverReadyTimer(doStartSupplicant);
|
||||
});
|
||||
// Driver startup on certain platforms takes longer than it takes for us
|
||||
// to return from loadDriver, so wait 2 seconds before starting
|
||||
// the supplicant to give it a chance to start.
|
||||
createWaitForDriverReadyTimer(doStartSupplicant);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
/* 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 "ImageData.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "nsTraceRefcnt.h"
|
||||
|
||||
#define PROPERTY_FLAGS \
|
||||
(JSPROP_ENUMERATE | JSPROP_SHARED)
|
||||
|
||||
USING_WORKERS_NAMESPACE
|
||||
|
||||
namespace {
|
||||
|
||||
class ImageData
|
||||
{
|
||||
static JSClass sClass;
|
||||
static const JSPropertySpec sProperties[];
|
||||
|
||||
enum SLOT {
|
||||
SLOT_width = 0,
|
||||
SLOT_height,
|
||||
SLOT_data,
|
||||
|
||||
SLOT_COUNT
|
||||
};
|
||||
|
||||
public:
|
||||
static JSObject*
|
||||
InitClass(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
Create(JSContext* aCx, uint32_t aWidth,
|
||||
uint32_t aHeight, JS::Handle<JSObject*> aData)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
MOZ_ASSERT(JS_IsTypedArrayObject(aData));
|
||||
MOZ_ASSERT(JS_IsUint8ClampedArray(aData));
|
||||
|
||||
JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_SetReservedSlot(obj, SLOT_width, UINT_TO_JSVAL(aWidth));
|
||||
JS_SetReservedSlot(obj, SLOT_height, UINT_TO_JSVAL(aHeight));
|
||||
JS_SetReservedSlot(obj, SLOT_data, OBJECT_TO_JSVAL(aData));
|
||||
|
||||
// This is an empty object. The point is just to differentiate instances
|
||||
// from the interface object.
|
||||
ImageData* priv = new ImageData();
|
||||
JS_SetPrivate(obj, priv);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsInstance(JSObject* aObj)
|
||||
{
|
||||
return JS_GetClass(aObj) == &sClass;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
GetWidth(JSObject* aObj)
|
||||
{
|
||||
MOZ_ASSERT(IsInstance(aObj));
|
||||
return JS_DoubleToUint32(JS_GetReservedSlot(aObj, SLOT_width).toNumber());
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
GetHeight(JSObject* aObj)
|
||||
{
|
||||
MOZ_ASSERT(IsInstance(aObj));
|
||||
return JS_DoubleToUint32(JS_GetReservedSlot(aObj, SLOT_height).toNumber());
|
||||
}
|
||||
|
||||
static
|
||||
JSObject* GetData(JSObject* aObj)
|
||||
{
|
||||
MOZ_ASSERT(IsInstance(aObj));
|
||||
return &JS_GetReservedSlot(aObj, SLOT_data).toObject();
|
||||
}
|
||||
|
||||
private:
|
||||
ImageData()
|
||||
{
|
||||
MOZ_COUNT_CTOR(mozilla::dom::workers::ImageData);
|
||||
}
|
||||
|
||||
~ImageData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(mozilla::dom::workers::ImageData);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
|
||||
{
|
||||
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
|
||||
sClass.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
Finalize(JSFreeOp* aFop, JSObject* aObj)
|
||||
{
|
||||
MOZ_ASSERT(JS_GetClass(aObj) == &sClass);
|
||||
delete static_cast<ImageData*>(JS_GetPrivate(aObj));
|
||||
}
|
||||
|
||||
static JSBool
|
||||
GetProperty(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
|
||||
JS::MutableHandle<JS::Value> aVp)
|
||||
{
|
||||
JSClass* classPtr = JS_GetClass(aObj);
|
||||
if (classPtr != &sClass) {
|
||||
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO, sClass.name, "GetProperty",
|
||||
classPtr->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(JSID_IS_INT(aIdval));
|
||||
MOZ_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < SLOT_COUNT);
|
||||
|
||||
aVp.set(JS_GetReservedSlot(aObj, JSID_TO_INT(aIdval)));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
JSClass ImageData::sClass = {
|
||||
"ImageData",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
|
||||
};
|
||||
|
||||
const JSPropertySpec ImageData::sProperties[] = {
|
||||
// These properties are read-only per spec, which means that sets must throw
|
||||
// in strict mode and silently fail otherwise. This is a problem for workers
|
||||
// in general (because js_GetterOnlyPropertyStub throws unconditionally). The
|
||||
// general plan for fixing this involves the new DOM bindings. But Peace
|
||||
// Keeper breaks if we throw when setting these properties, so we need to do
|
||||
// something about it in the mean time. So we use NULL, which defaults to the
|
||||
// class setter (JS_StrictPropertyStub), which is always a silent no-op,
|
||||
// regardless of strict mode. Not ideal, but good enough for now.
|
||||
{ "width", SLOT_width, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty), JSOP_NULLWRAPPER },
|
||||
{ "height", SLOT_height, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty), JSOP_NULLWRAPPER },
|
||||
{ "data", SLOT_data, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty), JSOP_NULLWRAPPER },
|
||||
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
namespace imagedata {
|
||||
|
||||
bool
|
||||
InitClass(JSContext* aCx, JSObject* aGlobal)
|
||||
{
|
||||
return !!ImageData::InitClass(aCx, aGlobal);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Create(JSContext* aCx, uint32_t aWidth,
|
||||
uint32_t aHeight, JS::Handle<JSObject*> aData)
|
||||
{
|
||||
return ImageData::Create(aCx, aWidth, aHeight, aData);
|
||||
}
|
||||
|
||||
bool
|
||||
IsImageData(JSObject* aObj)
|
||||
{
|
||||
return ImageData::IsInstance(aObj);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetWidth(JSObject* aObj)
|
||||
{
|
||||
return ImageData::GetWidth(aObj);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetHeight(JSObject* aObj)
|
||||
{
|
||||
return ImageData::GetHeight(aObj);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
GetData(JSObject* aObj)
|
||||
{
|
||||
return ImageData::GetData(aObj);
|
||||
}
|
||||
|
||||
|
||||
} // namespace imagedata
|
||||
|
||||
END_WORKERS_NAMESPACE
|
|
@ -1,42 +0,0 @@
|
|||
/* 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_workers_imagedata_h__
|
||||
#define mozilla_dom_workers_imagedata_h__
|
||||
|
||||
#include "Workers.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
namespace imagedata {
|
||||
|
||||
bool
|
||||
InitClass(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
JSObject*
|
||||
Create(JSContext* aCx, uint32_t aWidth,
|
||||
uint32_t aHeight, JS::Handle<JSObject*> aData);
|
||||
|
||||
/*
|
||||
* All data members live in private slots on the JS Object. Callers must
|
||||
* first check IsImageData, after which they may call the data accessors.
|
||||
*/
|
||||
|
||||
bool
|
||||
IsImageData(JSObject* aObj);
|
||||
|
||||
uint32_t
|
||||
GetWidth(JSObject* aObj);
|
||||
|
||||
uint32_t
|
||||
GetHeight(JSObject* aObj);
|
||||
|
||||
JSObject*
|
||||
GetData(JSObject* aObj);
|
||||
|
||||
} // namespace imagedata
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_workers_imagedata_h__
|
|
@ -21,6 +21,7 @@
|
|||
#include "GeckoProfiler.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "mozilla/Util.h"
|
||||
#include <Navigator.h>
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCycleCollector.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -748,20 +750,11 @@ CTypesActivityCallback(JSContext* aCx,
|
|||
}
|
||||
|
||||
JSContext*
|
||||
CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
NS_ASSERTION(!aWorkerPrivate->GetJSContext(), "Already has a context!");
|
||||
|
||||
// The number passed here doesn't matter, we're about to change it in the call
|
||||
// to JS_SetGCParameter.
|
||||
JSRuntime* runtime =
|
||||
JS_NewRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE, JS_NO_HELPER_THREADS);
|
||||
if (!runtime) {
|
||||
NS_WARNING("Could not create new runtime!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSSettings settings;
|
||||
aWorkerPrivate->CopyJSSettings(settings);
|
||||
|
||||
|
@ -779,45 +772,44 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
|||
const JSSettings::JSGCSetting& setting = gcSettings[index];
|
||||
if (setting.IsSet()) {
|
||||
NS_ASSERTION(setting.value, "Can't handle 0 values!");
|
||||
JS_SetGCParameter(runtime, setting.key, setting.value);
|
||||
JS_SetGCParameter(aRuntime, setting.key, setting.value);
|
||||
}
|
||||
}
|
||||
|
||||
JS_SetNativeStackQuota(runtime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
|
||||
JS_SetNativeStackQuota(aRuntime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
|
||||
|
||||
// Security policy:
|
||||
static JSSecurityCallbacks securityCallbacks = {
|
||||
NULL,
|
||||
ContentSecurityPolicyAllows
|
||||
};
|
||||
JS_SetSecurityCallbacks(runtime, &securityCallbacks);
|
||||
JS_SetSecurityCallbacks(aRuntime, &securityCallbacks);
|
||||
|
||||
// DOM helpers:
|
||||
static js::DOMCallbacks DOMCallbacks = {
|
||||
InstanceClassHasProtoAtDepth
|
||||
};
|
||||
SetDOMCallbacks(runtime, &DOMCallbacks);
|
||||
SetDOMCallbacks(aRuntime, &DOMCallbacks);
|
||||
|
||||
JSContext* workerCx = JS_NewContext(runtime, 0);
|
||||
JSContext* workerCx = JS_NewContext(aRuntime, 0);
|
||||
if (!workerCx) {
|
||||
JS_DestroyRuntime(runtime);
|
||||
NS_WARNING("Could not create new context!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS_SetRuntimePrivate(runtime, aWorkerPrivate);
|
||||
JS_SetRuntimePrivate(aRuntime, aWorkerPrivate);
|
||||
|
||||
JS_SetErrorReporter(workerCx, ErrorReporter);
|
||||
|
||||
JS_SetOperationCallback(workerCx, OperationCallback);
|
||||
|
||||
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
|
||||
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
|
||||
|
||||
JS_SetOptions(workerCx,
|
||||
aWorkerPrivate->IsChromeWorker() ? settings.chrome.options :
|
||||
settings.content.options);
|
||||
|
||||
JS_SetJitHardening(runtime, settings.jitHardening);
|
||||
JS_SetJitHardening(aRuntime, settings.jitHardening);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_SetGCZeal(workerCx, settings.gcZeal, settings.gcZealFrequency);
|
||||
|
@ -826,6 +818,58 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
|||
return workerCx;
|
||||
}
|
||||
|
||||
class WorkerJSRuntime : public mozilla::CycleCollectedJSRuntime
|
||||
{
|
||||
public:
|
||||
// The heap size passed here doesn't matter, we will change it later in the
|
||||
// call to JS_SetGCParameter inside CreateJSContextForWorker.
|
||||
WorkerJSRuntime(WorkerPrivate* aWorkerPrivate)
|
||||
: CycleCollectedJSRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE,
|
||||
JS_NO_HELPER_THREADS,
|
||||
false)
|
||||
{
|
||||
// We need to ensure that a JSContext outlives the cycle collector, and
|
||||
// that the internal JSContext created by ctypes is not the last JSContext
|
||||
// to die. So we create an unused JSContext here and destroy it after
|
||||
// the cycle collector shuts down. Thus all cycles will be broken before
|
||||
// the last GC and all finalizers will be run.
|
||||
mLastJSContext = JS_NewContext(Runtime(), 0);
|
||||
MOZ_ASSERT(mLastJSContext);
|
||||
}
|
||||
|
||||
~WorkerJSRuntime()
|
||||
{
|
||||
// All JSContexts except mLastJSContext should be destroyed now. The
|
||||
// worker global will be unrooted and the shutdown cycle collection
|
||||
// should break all remaining cycles. Destroying mLastJSContext will run
|
||||
// the GC the final time and finalize any JSObjects that were participating
|
||||
// in cycles that were broken during CC shutdown.
|
||||
nsCycleCollector_shutdownThreads();
|
||||
nsCycleCollector_shutdown();
|
||||
JS_DestroyContext(mLastJSContext);
|
||||
mLastJSContext = nullptr;
|
||||
}
|
||||
|
||||
// Make this public for now. Ideally we'd hide the JSRuntime inside.
|
||||
JSRuntime*
|
||||
Runtime() const
|
||||
{
|
||||
return mozilla::CycleCollectedJSRuntime::Runtime();
|
||||
}
|
||||
|
||||
void
|
||||
DispatchDeferredDeletion(bool aContinuation) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(!aContinuation);
|
||||
|
||||
// Do it immediately, no need for asynchronous behavior here.
|
||||
nsCycleCollector_doDeferredDeletion();
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext* mLastJSContext;
|
||||
};
|
||||
|
||||
class WorkerThreadRunnable : public nsRunnable
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
|
@ -845,50 +889,45 @@ public:
|
|||
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
JSContext* cx = CreateJSContextForWorker(workerPrivate);
|
||||
if (!cx) {
|
||||
// XXX need to fire an error at parent.
|
||||
NS_ERROR("Failed to create runtime and context!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSRuntime* rt = JS_GetRuntime(cx);
|
||||
|
||||
char aLocal;
|
||||
profiler_register_thread("WebWorker", &aLocal);
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
if (PseudoStack* stack = mozilla_get_pseudo_stack())
|
||||
stack->sampleRuntime(rt);
|
||||
#endif
|
||||
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
workerPrivate->DoRunLoop(cx);
|
||||
}
|
||||
nsCycleCollector_startup(CCSingleThread);
|
||||
|
||||
// XXX Bug 666963 - CTypes can create another JSContext for use with
|
||||
// closures, and then it holds that context in a reserved slot on the CType
|
||||
// prototype object. We have to destroy that context before we can destroy
|
||||
// the runtime, and we also have to make sure that it isn't the last context
|
||||
// to be destroyed (otherwise it will assert). To accomplish this we create
|
||||
// an unused dummy context, destroy our real context, and then destroy the
|
||||
// dummy. Once this bug is resolved we can remove this nastiness and simply
|
||||
// call JS_DestroyContextNoGC on our context.
|
||||
JSContext* dummyCx = JS_NewContext(rt, 0);
|
||||
if (dummyCx) {
|
||||
JS_DestroyContext(cx);
|
||||
JS_DestroyContext(dummyCx);
|
||||
}
|
||||
else {
|
||||
NS_WARNING("Failed to create dummy context!");
|
||||
WorkerJSRuntime runtime(workerPrivate);
|
||||
JSRuntime* rt = runtime.Runtime();
|
||||
JSContext* cx = CreateJSContextForWorker(workerPrivate, rt);
|
||||
if (!cx) {
|
||||
// XXX need to fire an error at parent.
|
||||
NS_ERROR("Failed to create runtime and context!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char aLocal;
|
||||
profiler_register_thread("WebWorker", &aLocal);
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
if (PseudoStack* stack = mozilla_get_pseudo_stack())
|
||||
stack->sampleRuntime(rt);
|
||||
#endif
|
||||
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
workerPrivate->DoRunLoop(cx);
|
||||
}
|
||||
|
||||
// Destroy the main context. This will unroot the main worker global and
|
||||
// GC. This is not the last JSContext (WorkerJSRuntime maintains an
|
||||
// internal JSContext).
|
||||
JS_DestroyContext(cx);
|
||||
|
||||
// Now WorkerJSRuntime goes out of scope and its destructor will shut
|
||||
// down the cycle collector and destroy the final JSContext. This
|
||||
// breaks any remaining cycles and collects the C++ and JS objects
|
||||
// participating.
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
if (PseudoStack* stack = mozilla_get_pseudo_stack())
|
||||
stack->sampleRuntime(nullptr);
|
||||
#endif
|
||||
JS_DestroyRuntime(rt);
|
||||
|
||||
workerPrivate->ScheduleDeletion(false);
|
||||
profiler_unregister_thread();
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include "js/MemoryMetrics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
|
@ -57,7 +60,6 @@
|
|||
#include "Events.h"
|
||||
#include "Exceptions.h"
|
||||
#include "File.h"
|
||||
#include "ImageData.h"
|
||||
#include "Principal.h"
|
||||
#include "RuntimeService.h"
|
||||
#include "ScriptLoader.h"
|
||||
|
@ -204,9 +206,14 @@ struct WorkerStructuredCloneCallbacks
|
|||
MOZ_ASSERT(dataArray.isObject());
|
||||
|
||||
// Construct the ImageData.
|
||||
JS::Rooted<JSObject*> dataObj(aCx, &dataArray.toObject());
|
||||
JSObject* obj = imagedata::Create(aCx, width, height, dataObj);
|
||||
return obj;
|
||||
nsRefPtr<ImageData> imageData = new ImageData(width, height,
|
||||
dataArray.toObject());
|
||||
// Wrap it in a JS::Value.
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
if (!global) {
|
||||
return nullptr;
|
||||
}
|
||||
return imageData->WrapObject(aCx, global);
|
||||
}
|
||||
|
||||
Error(aCx, 0);
|
||||
|
@ -250,16 +257,20 @@ struct WorkerStructuredCloneCallbacks
|
|||
}
|
||||
|
||||
// See if this is an ImageData object.
|
||||
if (imagedata::IsImageData(aObj)) {
|
||||
// Pull the properties off the object.
|
||||
uint32_t width = imagedata::GetWidth(aObj);
|
||||
uint32_t height = imagedata::GetHeight(aObj);
|
||||
JSObject* data = imagedata::GetData(aObj);
|
||||
{
|
||||
ImageData* imageData = nullptr;
|
||||
if (NS_SUCCEEDED(UnwrapObject<ImageData>(aCx, aObj, imageData))) {
|
||||
// Prepare the ImageData internals.
|
||||
uint32_t width = imageData->Width();
|
||||
uint32_t height = imageData->Height();
|
||||
JS::Rooted<JSObject*> dataArray(aCx, imageData->GetDataObject());
|
||||
|
||||
// Write the structured clone.
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
|
||||
JS_WriteUint32Pair(aWriter, width, height) &&
|
||||
JS_WriteTypedArray(aWriter, OBJECT_TO_JSVAL(data));
|
||||
// Write the internals to the stream.
|
||||
JSAutoCompartment ac(aCx, dataArray);
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
|
||||
JS_WriteUint32Pair(aWriter, width, height) &&
|
||||
JS_WriteTypedArray(aWriter, JS::ObjectValue(*dataArray));
|
||||
}
|
||||
}
|
||||
|
||||
Error(aCx, 0);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/FileReaderSyncBinding.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "mozilla/dom/TextDecoderBinding.h"
|
||||
#include "mozilla/dom/TextEncoderBinding.h"
|
||||
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
||||
|
@ -36,7 +38,6 @@
|
|||
#include "File.h"
|
||||
#include "FileReaderSync.h"
|
||||
#include "Location.h"
|
||||
#include "ImageData.h"
|
||||
#include "Navigator.h"
|
||||
#include "Principal.h"
|
||||
#include "ScriptLoader.h"
|
||||
|
@ -1012,13 +1013,13 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
|
|||
// Init other classes we care about.
|
||||
if (!events::InitClasses(aCx, global, false) ||
|
||||
!file::InitClasses(aCx, global) ||
|
||||
!exceptions::InitClasses(aCx, global) ||
|
||||
!imagedata::InitClass(aCx, global)) {
|
||||
!exceptions::InitClasses(aCx, global)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Init other paris-bindings.
|
||||
if (!FileReaderSyncBinding_workers::GetConstructorObject(aCx, global) ||
|
||||
!ImageDataBinding::GetConstructorObject(aCx, global) ||
|
||||
!TextDecoderBinding_workers::GetConstructorObject(aCx, global) ||
|
||||
!TextEncoderBinding_workers::GetConstructorObject(aCx, global) ||
|
||||
!XMLHttpRequestBinding_workers::GetConstructorObject(aCx, global) ||
|
||||
|
|
|
@ -39,7 +39,6 @@ CPP_SOURCES += [
|
|||
'Exceptions.cpp',
|
||||
'File.cpp',
|
||||
'FileReaderSync.cpp',
|
||||
'ImageData.cpp',
|
||||
'Location.cpp',
|
||||
'Navigator.cpp',
|
||||
'Principal.cpp',
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
};
|
||||
|
||||
DrawTargetSkia::DrawTargetSkia()
|
||||
: mSnapshot(nullptr)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
mSoftClipping = false;
|
||||
|
@ -86,19 +87,20 @@ DrawTargetSkia::DrawTargetSkia()
|
|||
|
||||
DrawTargetSkia::~DrawTargetSkia()
|
||||
{
|
||||
MOZ_ASSERT(mSnapshots.size() == 0);
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
DrawTargetSkia::Snapshot()
|
||||
{
|
||||
RefPtr<SourceSurfaceSkia> source = new SourceSurfaceSkia();
|
||||
RefPtr<SourceSurfaceSkia> snapshot = mSnapshot;
|
||||
if (!snapshot) {
|
||||
snapshot = new SourceSurfaceSkia();
|
||||
mSnapshot = snapshot;
|
||||
if (!snapshot->InitFromCanvas(mCanvas.get(), mFormat, this))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!source->InitFromCanvas(mCanvas.get(), mFormat, this))
|
||||
return nullptr;
|
||||
|
||||
AppendSnapshot(source);
|
||||
return source;
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0)
|
||||
|
@ -772,33 +774,20 @@ DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, Ex
|
|||
return new GradientStopsSkia(stops, aNumStops, aExtendMode);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::AppendSnapshot(SourceSurfaceSkia* aSnapshot)
|
||||
{
|
||||
mSnapshots.push_back(aSnapshot);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::RemoveSnapshot(SourceSurfaceSkia* aSnapshot)
|
||||
{
|
||||
std::vector<SourceSurfaceSkia*>::iterator iter = std::find(mSnapshots.begin(), mSnapshots.end(), aSnapshot);
|
||||
if (iter != mSnapshots.end()) {
|
||||
mSnapshots.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::MarkChanged()
|
||||
{
|
||||
if (mSnapshots.size()) {
|
||||
for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
|
||||
iter != mSnapshots.end(); iter++) {
|
||||
(*iter)->DrawTargetWillChange();
|
||||
}
|
||||
// All snapshots will now have copied data.
|
||||
mSnapshots.clear();
|
||||
if (mSnapshot) {
|
||||
mSnapshot->DrawTargetWillChange();
|
||||
mSnapshot = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::SnapshotDestroyed()
|
||||
{
|
||||
mSnapshot = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,8 +114,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class SourceSurfaceSkia;
|
||||
void AppendSnapshot(SourceSurfaceSkia* aSnapshot);
|
||||
void RemoveSnapshot(SourceSurfaceSkia* aSnapshot);
|
||||
void SnapshotDestroyed();
|
||||
|
||||
void MarkChanged();
|
||||
|
||||
|
@ -133,7 +132,7 @@ private:
|
|||
|
||||
IntSize mSize;
|
||||
SkRefPtr<SkCanvas> mCanvas;
|
||||
std::vector<SourceSurfaceSkia*> mSnapshots;
|
||||
SourceSurfaceSkia* mSnapshot;
|
||||
bool mSoftClipping;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,10 @@ SourceSurfaceSkia::SourceSurfaceSkia()
|
|||
SourceSurfaceSkia::~SourceSurfaceSkia()
|
||||
{
|
||||
MaybeUnlock();
|
||||
MarkIndependent();
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->SnapshotDestroyed();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
IntSize
|
||||
|
@ -108,15 +111,6 @@ SourceSurfaceSkia::DrawTargetWillChange()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::MarkIndependent()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->RemoveSnapshot(this);
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::MaybeUnlock()
|
||||
{
|
||||
|
|
|
@ -45,8 +45,6 @@ private:
|
|||
friend class DrawTargetSkia;
|
||||
|
||||
void DrawTargetWillChange();
|
||||
void DrawTargetDestroyed();
|
||||
void MarkIndependent();
|
||||
void MaybeUnlock();
|
||||
|
||||
SkBitmap mBitmap;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "GLContextProvider.h"
|
||||
#include "GLTextureImage.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "prenv.h"
|
||||
#include "prlink.h"
|
||||
|
@ -469,8 +470,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
}
|
||||
|
||||
// Check for aux symbols based on extensions
|
||||
if (IsExtensionSupported(GLContext::ANGLE_framebuffer_blit) ||
|
||||
IsExtensionSupported(GLContext::EXT_framebuffer_blit))
|
||||
if (IsExtensionSupported(XXX_framebuffer_blit))
|
||||
{
|
||||
SymLoadStruct auxSymbols[] = {
|
||||
{
|
||||
|
@ -487,15 +487,13 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports framebuffer_blit without supplying glBlitFramebuffer");
|
||||
|
||||
MarkExtensionUnsupported(ANGLE_framebuffer_blit);
|
||||
MarkExtensionUnsupported(EXT_framebuffer_blit);
|
||||
MarkExtensionGroupUnsupported(XXX_framebuffer_blit);
|
||||
mSymbols.fBlitFramebuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (SupportsFramebufferMultisample())
|
||||
if (IsExtensionSupported(XXX_framebuffer_multisample))
|
||||
{
|
||||
MOZ_ASSERT(SupportsSplitFramebuffer());
|
||||
SymLoadStruct auxSymbols[] = {
|
||||
{
|
||||
(PRFuncPtr*) &mSymbols.fRenderbufferStorageMultisample,
|
||||
|
@ -511,8 +509,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports framebuffer_multisample without supplying glRenderbufferStorageMultisample");
|
||||
|
||||
MarkExtensionUnsupported(ANGLE_framebuffer_multisample);
|
||||
MarkExtensionUnsupported(EXT_framebuffer_multisample);
|
||||
MarkExtensionGroupUnsupported(XXX_framebuffer_multisample);
|
||||
mSymbols.fRenderbufferStorageMultisample = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -572,9 +569,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
|
||||
|
||||
MarkExtensionUnsupported(ARB_vertex_array_object);
|
||||
MarkExtensionUnsupported(OES_vertex_array_object);
|
||||
MarkExtensionUnsupported(APPLE_vertex_array_object);
|
||||
MarkExtensionGroupUnsupported(XXX_vertex_array_object);
|
||||
mSymbols.fIsVertexArray = nullptr;
|
||||
mSymbols.fGenVertexArrays = nullptr;
|
||||
mSymbols.fBindVertexArray = nullptr;
|
||||
|
@ -597,7 +592,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
|
||||
|
||||
MarkExtensionUnsupported(APPLE_vertex_array_object);
|
||||
MarkExtensionGroupUnsupported(XXX_vertex_array_object);
|
||||
mSymbols.fIsVertexArray = nullptr;
|
||||
mSymbols.fGenVertexArrays = nullptr;
|
||||
mSymbols.fBindVertexArray = nullptr;
|
||||
|
@ -631,10 +626,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
if (!LoadSymbols(drawInstancedSymbols, trygl, prefix)) {
|
||||
NS_ERROR("GL supports instanced draws without supplying its functions.");
|
||||
|
||||
MarkExtensionUnsupported(ARB_draw_instanced);
|
||||
MarkExtensionUnsupported(EXT_draw_instanced);
|
||||
MarkExtensionUnsupported(NV_draw_instanced);
|
||||
MarkExtensionUnsupported(ANGLE_instanced_array);
|
||||
MarkExtensionGroupUnsupported(XXX_draw_instanced);
|
||||
mSymbols.fDrawArraysInstanced = nullptr;
|
||||
mSymbols.fDrawElementsInstanced = nullptr;
|
||||
}
|
||||
|
@ -705,7 +697,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
mMaxTextureImageSize = mMaxTextureSize;
|
||||
|
||||
mMaxSamples = 0;
|
||||
if (SupportsFramebufferMultisample()) {
|
||||
if (IsExtensionSupported(XXX_framebuffer_multisample)) {
|
||||
fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
|
||||
}
|
||||
|
||||
|
@ -731,6 +723,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
NS_WARNING("InitWithPrefix failed!");
|
||||
}
|
||||
|
||||
mVersionString = nsPrintfCString("%u.%u.%u", mVersion / 100, (mVersion / 10) % 10, mVersion % 10);
|
||||
|
||||
return mInitialized;
|
||||
}
|
||||
|
||||
|
|
|
@ -197,6 +197,13 @@ public:
|
|||
return "OpenGL unknown profile";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we are running on a OpenGL core profile context
|
||||
*/
|
||||
const char* ProfileString() const {
|
||||
return GetProfileName(mProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the context is compatible with given parameters
|
||||
*
|
||||
|
@ -228,6 +235,10 @@ public:
|
|||
return mVersion;
|
||||
}
|
||||
|
||||
const char* VersionString() const {
|
||||
return mVersionString.get();
|
||||
}
|
||||
|
||||
int Vendor() const {
|
||||
return mVendor;
|
||||
}
|
||||
|
@ -283,6 +294,7 @@ protected:
|
|||
* the context is an OpenGL 2.1 context, mVersion value will be 210.
|
||||
*/
|
||||
unsigned int mVersion;
|
||||
nsCString mVersionString;
|
||||
ContextProfile mProfile;
|
||||
|
||||
int32_t mVendor;
|
||||
|
@ -369,7 +381,8 @@ public:
|
|||
EXT_draw_instanced,
|
||||
NV_draw_instanced,
|
||||
ANGLE_instanced_array,
|
||||
Extensions_Max
|
||||
Extensions_Max,
|
||||
Extensions_End
|
||||
};
|
||||
|
||||
bool IsExtensionSupported(GLExtensions aKnownExtension) const {
|
||||
|
@ -460,86 +473,33 @@ public:
|
|||
/**
|
||||
* This enum should be sorted by name.
|
||||
*/
|
||||
enum GLExtensionPackages {
|
||||
enum GLExtensionGroup {
|
||||
XXX_draw_buffers,
|
||||
XXX_draw_instanced,
|
||||
XXX_framebuffer_blit,
|
||||
XXX_framebuffer_multisample,
|
||||
XXX_framebuffer_object,
|
||||
XXX_robustness,
|
||||
XXX_texture_float,
|
||||
XXX_texture_non_power_of_two,
|
||||
XXX_robustness,
|
||||
XXX_vertex_array_object,
|
||||
ExtensionPackages_Max
|
||||
ExtensionGroup_Max
|
||||
};
|
||||
|
||||
bool IsExtensionSupported(GLExtensionPackages aKnownExtensionPackage) const
|
||||
{
|
||||
switch (aKnownExtensionPackage)
|
||||
{
|
||||
case XXX_draw_buffers:
|
||||
return IsExtensionSupported(ARB_draw_buffers) ||
|
||||
IsExtensionSupported(EXT_draw_buffers);
|
||||
bool IsExtensionSupported(GLExtensionGroup extensionGroup) const;
|
||||
|
||||
case XXX_draw_instanced:
|
||||
return IsExtensionSupported(ARB_draw_instanced) ||
|
||||
IsExtensionSupported(EXT_draw_instanced) ||
|
||||
IsExtensionSupported(NV_draw_instanced) ||
|
||||
IsExtensionSupported(ANGLE_instanced_array);
|
||||
|
||||
case XXX_framebuffer_blit:
|
||||
return IsExtensionSupported(EXT_framebuffer_blit) ||
|
||||
IsExtensionSupported(ANGLE_framebuffer_blit);
|
||||
|
||||
case XXX_framebuffer_multisample:
|
||||
return IsExtensionSupported(EXT_framebuffer_multisample) ||
|
||||
IsExtensionSupported(ANGLE_framebuffer_multisample);
|
||||
|
||||
case XXX_framebuffer_object:
|
||||
return IsExtensionSupported(ARB_framebuffer_object) ||
|
||||
IsExtensionSupported(EXT_framebuffer_object);
|
||||
|
||||
case XXX_texture_float:
|
||||
return IsExtensionSupported(ARB_texture_float) ||
|
||||
IsExtensionSupported(OES_texture_float);
|
||||
|
||||
case XXX_robustness:
|
||||
return IsExtensionSupported(ARB_robustness) ||
|
||||
IsExtensionSupported(EXT_robustness);
|
||||
|
||||
case XXX_texture_non_power_of_two:
|
||||
return IsExtensionSupported(ARB_texture_non_power_of_two) ||
|
||||
IsExtensionSupported(OES_texture_npot);
|
||||
|
||||
case XXX_vertex_array_object:
|
||||
return IsExtensionSupported(ARB_vertex_array_object) ||
|
||||
IsExtensionSupported(OES_vertex_array_object) ||
|
||||
IsExtensionSupported(APPLE_vertex_array_object);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "GLContext::IsExtensionSupported : unknown <aKnownExtensionPackage>");
|
||||
return false;
|
||||
}
|
||||
static const char* GetExtensionGroupName(GLExtensionGroup extensionGroup);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Deprecated extension group queries (use XXX_* instead)
|
||||
public:
|
||||
private:
|
||||
|
||||
bool SupportsFramebufferMultisample() const {
|
||||
return IsExtensionSupported(XXX_framebuffer_multisample);
|
||||
}
|
||||
|
||||
bool HasExt_FramebufferBlit() const {
|
||||
return IsExtensionSupported(XXX_framebuffer_blit);
|
||||
}
|
||||
|
||||
bool SupportsSplitFramebuffer() const {
|
||||
return IsExtensionSupported(XXX_framebuffer_blit);
|
||||
}
|
||||
/**
|
||||
* Mark all extensions of this group as unsupported.
|
||||
*
|
||||
* Returns false if marking this extension group as unsupported contradicts
|
||||
* the OpenGL version and profile. Returns true otherwise.
|
||||
*/
|
||||
bool MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup);
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -565,8 +525,7 @@ private:
|
|||
// Error handling
|
||||
public:
|
||||
|
||||
// TODO: this function should be a static
|
||||
const char* GLErrorToString(GLenum aError) const
|
||||
static const char* GLErrorToString(GLenum aError)
|
||||
{
|
||||
switch (aError) {
|
||||
case LOCAL_GL_INVALID_ENUM:
|
||||
|
@ -2592,8 +2551,9 @@ public:
|
|||
if (mScreen)
|
||||
return mScreen->GetReadFB();
|
||||
|
||||
GLenum bindEnum = SupportsSplitFramebuffer() ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
|
||||
: LOCAL_GL_FRAMEBUFFER_BINDING;
|
||||
GLenum bindEnum = IsExtensionSupported(XXX_framebuffer_blit)
|
||||
? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
|
||||
: LOCAL_GL_FRAMEBUFFER_BINDING;
|
||||
|
||||
GLuint ret = 0;
|
||||
GetUIntegerv(bindEnum, &ret);
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "GLContext.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
|
||||
|
||||
struct ExtensionGroupInfo
|
||||
{
|
||||
const char* mName;
|
||||
unsigned int mOpenGLVersion;
|
||||
unsigned int mOpenGLESVersion;
|
||||
GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
|
||||
};
|
||||
|
||||
static const ExtensionGroupInfo sExtensionGroupInfoArr[] = {
|
||||
{
|
||||
"XXX_draw_buffers",
|
||||
200, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_draw_buffers,
|
||||
GLContext::EXT_draw_buffers,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_draw_instanced",
|
||||
310, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_draw_instanced,
|
||||
GLContext::EXT_draw_instanced,
|
||||
GLContext::NV_draw_instanced,
|
||||
GLContext::ANGLE_instanced_array,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_framebuffer_blit",
|
||||
300, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::EXT_framebuffer_blit,
|
||||
GLContext::ANGLE_framebuffer_blit,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_framebuffer_multisample",
|
||||
300, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::EXT_framebuffer_multisample,
|
||||
GLContext::ANGLE_framebuffer_multisample,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_framebuffer_object",
|
||||
300, // OpenGL version
|
||||
200, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_framebuffer_object,
|
||||
GLContext::EXT_framebuffer_object,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_robustness",
|
||||
0, // OpenGL version
|
||||
0, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_robustness,
|
||||
GLContext::EXT_robustness,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_texture_float",
|
||||
310, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_texture_float,
|
||||
GLContext::OES_texture_float,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_texture_non_power_of_two",
|
||||
200, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_texture_non_power_of_two,
|
||||
GLContext::OES_texture_npot,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"XXX_vertex_array_object",
|
||||
300, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::ARB_vertex_array_object,
|
||||
GLContext::OES_vertex_array_object,
|
||||
GLContext::APPLE_vertex_array_object,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static inline const ExtensionGroupInfo&
|
||||
GetExtensionGroupInfo(GLContext::GLExtensionGroup extensionGroup)
|
||||
{
|
||||
static_assert(MOZ_ARRAY_LENGTH(sExtensionGroupInfoArr) == size_t(GLContext::ExtensionGroup_Max),
|
||||
"Mismatched lengths for sExtensionGroupInfos and ExtensionGroup enums");
|
||||
|
||||
MOZ_ASSERT(extensionGroup < GLContext::ExtensionGroup_Max,
|
||||
"GLContext::GetExtensionGroupInfo : unknown <extensionGroup>");
|
||||
|
||||
return sExtensionGroupInfoArr[extensionGroup];
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
ProfileVersionForExtensionGroup(GLContext::GLExtensionGroup extensionGroup, ContextProfile profile)
|
||||
{
|
||||
MOZ_ASSERT(profile != ContextProfile::Unknown,
|
||||
"GLContext::ProfileVersionForExtensionGroup : unknown <profile>");
|
||||
|
||||
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
|
||||
|
||||
if (profile == ContextProfile::OpenGLES) {
|
||||
return groupInfo.mOpenGLESVersion;
|
||||
}
|
||||
|
||||
return groupInfo.mOpenGLVersion;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsExtensionGroupIsPartOfProfileVersion(GLContext::GLExtensionGroup extensionGroup,
|
||||
ContextProfile profile, unsigned int version)
|
||||
{
|
||||
unsigned int profileVersion = ProfileVersionForExtensionGroup(extensionGroup, profile);
|
||||
|
||||
return profileVersion && version >= profileVersion;
|
||||
}
|
||||
|
||||
const char*
|
||||
GLContext::GetExtensionGroupName(GLExtensionGroup extensionGroup)
|
||||
{
|
||||
return GetExtensionGroupInfo(extensionGroup).mName;
|
||||
}
|
||||
|
||||
bool
|
||||
GLContext::IsExtensionSupported(GLExtensionGroup extensionGroup) const
|
||||
{
|
||||
if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
|
||||
|
||||
for (size_t i = 0; true; i++)
|
||||
{
|
||||
MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
|
||||
|
||||
if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsExtensionSupported(groupInfo.mExtensions[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GLContext::MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup)
|
||||
{
|
||||
MOZ_ASSERT(IsExtensionSupported(extensionGroup), "extension group is already unsupported!");
|
||||
|
||||
if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
|
||||
NS_WARNING(nsPrintfCString("%s marked as unsupported, but it's supposed to be supported by %s %s",
|
||||
GetExtensionGroupName(extensionGroup),
|
||||
ProfileString(),
|
||||
VersionString()).get());
|
||||
return false;
|
||||
}
|
||||
|
||||
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
|
||||
|
||||
for (size_t i = 0; true; i++)
|
||||
{
|
||||
MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
|
||||
|
||||
if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
|
||||
break;
|
||||
}
|
||||
|
||||
MarkExtensionUnsupported(groupInfo.mExtensions[i]);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!IsExtensionSupported(extensionGroup), "GLContext::MarkExtensionGroupUnsupported has failed!");
|
||||
|
||||
NS_WARNING(nsPrintfCString("%s marked as unsupported", GetExtensionGroupName(extensionGroup)).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
|
@ -138,12 +138,13 @@ public:
|
|||
|
||||
if (mContext) {
|
||||
[mContext makeCurrentContext];
|
||||
// Use blocking swap only with the default frame rate.
|
||||
// Use non-blocking swap in "ASAP mode".
|
||||
// ASAP mode means that rendering is iterated as fast as possible.
|
||||
// ASAP mode is entered when layout.frame_rate=0 (requires restart).
|
||||
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
|
||||
// While this is fine for the default refresh rate, if the user chooses some
|
||||
// other rate, and specifically if this rate is higher than the screen refresh rate,
|
||||
// then we want a non-blocking glSwapBuffers, which will happen when swapInt==0.
|
||||
GLint swapInt = gfxPlatform::GetPrefLayoutFrameRate() == -1 ? 1 : 0;
|
||||
// When we're iterating as fast as possible, however, we want a non-blocking
|
||||
// glSwapBuffers, which will happen when swapInt==0.
|
||||
GLint swapInt = gfxPlatform::GetPrefLayoutFrameRate() == 0 ? 0 : 1;
|
||||
[mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -29,7 +29,7 @@ GLScreenBuffer::Create(GLContext* gl,
|
|||
const SurfaceCaps& caps)
|
||||
{
|
||||
if (caps.antialias &&
|
||||
!gl->SupportsFramebufferMultisample())
|
||||
!gl->IsExtensionSupported(GLContext::XXX_framebuffer_multisample))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
|
|||
GLuint drawFB = DrawFB();
|
||||
GLuint readFB = ReadFB();
|
||||
|
||||
if (!gl->HasExt_FramebufferBlit()) {
|
||||
if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
|
||||
MOZ_ASSERT(drawFB == readFB);
|
||||
gl->raw_fBindFramebuffer(target, readFB);
|
||||
return;
|
||||
|
@ -92,14 +92,14 @@ GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
|
|||
break;
|
||||
|
||||
case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
|
||||
if (!gl->HasExt_FramebufferBlit())
|
||||
if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
|
||||
NS_WARNING("DRAW_FRAMEBUFFER requested but unavailable.");
|
||||
|
||||
gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_READ_FRAMEBUFFER_EXT:
|
||||
if (!gl->HasExt_FramebufferBlit())
|
||||
if (!gl->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
|
||||
NS_WARNING("READ_FRAMEBUFFER requested but unavailable.");
|
||||
|
||||
gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
|
||||
|
@ -124,7 +124,7 @@ GLScreenBuffer::BindFB(GLuint fb)
|
|||
if (mInternalDrawFB == mInternalReadFB) {
|
||||
mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
|
||||
} else {
|
||||
MOZ_ASSERT(mGL->SupportsSplitFramebuffer());
|
||||
MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit));
|
||||
mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
|
||||
mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ GLScreenBuffer::BindFB(GLuint fb)
|
|||
void
|
||||
GLScreenBuffer::BindDrawFB(GLuint fb)
|
||||
{
|
||||
if (!mGL->SupportsSplitFramebuffer()) {
|
||||
if (!mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
|
||||
NS_WARNING("DRAW_FRAMEBUFFER requested, but unsupported.");
|
||||
|
||||
mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
|
||||
|
@ -158,7 +158,7 @@ GLScreenBuffer::BindDrawFB(GLuint fb)
|
|||
void
|
||||
GLScreenBuffer::BindReadFB(GLuint fb)
|
||||
{
|
||||
if (!mGL->SupportsSplitFramebuffer()) {
|
||||
if (!mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit)) {
|
||||
NS_WARNING("READ_FRAMEBUFFER requested, but unsupported.");
|
||||
|
||||
mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
|
||||
|
@ -233,7 +233,7 @@ GLScreenBuffer::GetReadFB() const
|
|||
// We use raw_ here because this is debug code and we need to see what
|
||||
// the driver thinks.
|
||||
GLuint actual = 0;
|
||||
if (mGL->SupportsSplitFramebuffer())
|
||||
if (mGL->IsExtensionSupported(GLContext::XXX_framebuffer_blit))
|
||||
mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
|
||||
else
|
||||
mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
|
||||
|
|
|
@ -101,6 +101,7 @@ if gl_provider == 'EGL':
|
|||
|
||||
CPP_SOURCES += [
|
||||
'GLContext.cpp',
|
||||
'GLContextExtensionGroupQueries.cpp',
|
||||
'GLContextTypes.cpp',
|
||||
'GLContextUtils.cpp',
|
||||
'GLLibraryLoader.cpp',
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#define MOZILLA_LAYERS_COMPOSITORTYPES_H
|
||||
|
||||
#include "LayersTypes.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -67,11 +69,30 @@ const TextureFlags TEXTURE_DEALLOCATE_HOST = 1 << 26;
|
|||
// modified, it can only be read. It is safe to not Lock/Unlock immutable
|
||||
// textures.
|
||||
const TextureFlags TEXTURE_IMMUTABLE = 1 << 27;
|
||||
// The contents of the texture must be uploaded or copied immediately
|
||||
// during the transaction, because the producer may want to write
|
||||
// to it again.
|
||||
const TextureFlags TEXTURE_IMMEDIATE_UPLOAD = 1 << 28;
|
||||
// The texture is going to be used as part of a double
|
||||
// buffered pair, and so we can guarantee that the producer/consumer
|
||||
// won't be racing to access its contents.
|
||||
const TextureFlags TEXTURE_DOUBLE_BUFFERED = 1 << 29;
|
||||
|
||||
// the default flags
|
||||
const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_DEALLOCATE_HOST
|
||||
| TEXTURE_FRONT;
|
||||
|
||||
static inline bool
|
||||
TextureRequiresLocking(TextureFlags aFlags)
|
||||
{
|
||||
// If we're not double buffered, or uploading
|
||||
// within a transaction, then we need to support
|
||||
// locking correctly.
|
||||
return !(aFlags & (TEXTURE_IMMEDIATE_UPLOAD |
|
||||
TEXTURE_DOUBLE_BUFFERED |
|
||||
TEXTURE_IMMUTABLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* See gfx/layers/Effects.h
|
||||
*/
|
||||
|
@ -104,7 +125,8 @@ enum DeprecatedTextureClientType
|
|||
TEXTURE_SHARED_GL_EXTERNAL, // GLContext::SharedTextureHandle, the ownership of
|
||||
// the SurfaceDescriptor passed to the texture
|
||||
// remains with whoever passed it.
|
||||
TEXTURE_STREAM_GL // WebGL streaming buffer
|
||||
TEXTURE_STREAM_GL, // WebGL streaming buffer
|
||||
TEXTURE_FALLBACK // A fallback path appropriate for the platform
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -147,15 +169,18 @@ enum DeprecatedTextureHostFlags
|
|||
struct TextureFactoryIdentifier
|
||||
{
|
||||
LayersBackend mParentBackend;
|
||||
GeckoProcessType mParentProcessId;
|
||||
int32_t mMaxTextureSize;
|
||||
bool mSupportsTextureBlitting;
|
||||
bool mSupportsPartialUploads;
|
||||
|
||||
TextureFactoryIdentifier(LayersBackend aLayersBackend = LAYERS_NONE,
|
||||
GeckoProcessType aParentProcessId = GeckoProcessType_Default,
|
||||
int32_t aMaxTextureSize = 0,
|
||||
bool aSupportsTextureBlitting = false,
|
||||
bool aSupportsPartialUploads = false)
|
||||
: mParentBackend(aLayersBackend)
|
||||
, mParentProcessId(aParentProcessId)
|
||||
, mMaxTextureSize(aMaxTextureSize)
|
||||
, mSupportsTextureBlitting(aSupportsTextureBlitting)
|
||||
, mSupportsPartialUploads(aSupportsPartialUploads)
|
||||
|
|
|
@ -446,7 +446,8 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
|||
PaintState result;
|
||||
// We need to disable rotation if we're going to be resampled when
|
||||
// drawing, because we might sample across the rotation boundary.
|
||||
bool canHaveRotation = !(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
bool canHaveRotation = gfxPlatform::BufferRotationEnabled() &&
|
||||
!(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
|
||||
|
||||
nsIntRegion validRegion = aLayer->GetValidRegion();
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct YCbCrBufferInfo
|
|||
uint32_t mYHeight;
|
||||
uint32_t mCbCrWidth;
|
||||
uint32_t mCbCrHeight;
|
||||
StereoMode mStereoMode;
|
||||
};
|
||||
|
||||
static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
|
||||
|
@ -103,6 +104,12 @@ gfxIntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
|
|||
return gfxIntSize(info->mCbCrWidth, info->mCbCrHeight);
|
||||
}
|
||||
|
||||
StereoMode YCbCrImageDataDeserializerBase::GetStereoMode()
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
return info->mStereoMode;
|
||||
}
|
||||
|
||||
// Offset in bytes
|
||||
static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
|
||||
{
|
||||
|
@ -144,7 +151,8 @@ YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
|
|||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize)
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
|
||||
info->mYOffset = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
|
||||
|
@ -157,14 +165,17 @@ YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
|
|||
info->mYHeight = aYSize.height;
|
||||
info->mCbCrWidth = aCbCrSize.width;
|
||||
info->mCbCrHeight = aCbCrSize.height;
|
||||
info->mStereoMode = aStereoMode;
|
||||
}
|
||||
|
||||
void
|
||||
YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize)
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
InitializeBufferInfo(gfx::IntSize(aYSize.width, aYSize.height),
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height));
|
||||
gfx::IntSize(aCbCrSize.width, aCbCrSize.height),
|
||||
aStereoMode);
|
||||
}
|
||||
|
||||
static void CopyLineWithSkip(const uint8_t* src, uint8_t* dst, uint32_t len, uint32_t skip) {
|
||||
|
|
|
@ -66,6 +66,11 @@ public:
|
|||
*/
|
||||
gfxIntSize GetCbCrSize();
|
||||
|
||||
/**
|
||||
* Stereo mode for the image.
|
||||
*/
|
||||
StereoMode GetStereoMode();
|
||||
|
||||
/**
|
||||
* Return a pointer to the begining of the data buffer.
|
||||
*/
|
||||
|
@ -111,9 +116,11 @@ public:
|
|||
* buffer on which we want to store the image.
|
||||
*/
|
||||
void InitializeBufferInfo(const gfx::IntSize& aYSize,
|
||||
const gfx::IntSize& aCbCrSize);
|
||||
const gfx::IntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
void InitializeBufferInfo(const gfxIntSize& aYSize,
|
||||
const gfxIntSize& aCbCrSize);
|
||||
const gfxIntSize& aCbCrSize,
|
||||
StereoMode aStereoMode);
|
||||
|
||||
bool CopyData(const uint8_t* aYData,
|
||||
const uint8_t* aCbData, const uint8_t* aCrData,
|
||||
|
|
|
@ -43,7 +43,9 @@ public:
|
|||
|
||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
|
||||
{
|
||||
return TextureFactoryIdentifier(LAYERS_BASIC, GetMaxTextureSize());
|
||||
return TextureFactoryIdentifier(LAYERS_BASIC,
|
||||
XRE_GetProcessType(),
|
||||
GetMaxTextureSize());
|
||||
}
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
|
|
|
@ -28,27 +28,77 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
|
|||
{
|
||||
if (aType == CanvasClientGLContext &&
|
||||
aForwarder->GetCompositorBackendType() == LAYERS_OPENGL) {
|
||||
return new CanvasClientSurfaceStream(aForwarder, aFlags);
|
||||
return new DeprecatedCanvasClientSurfaceStream(aForwarder, aFlags);
|
||||
}
|
||||
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
|
||||
return new DeprecatedCanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClient::Updated()
|
||||
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (mBuffer &&
|
||||
(mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
|
||||
RemoveTextureClient(mBuffer);
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (!mBuffer) {
|
||||
bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
|
||||
gfxASurface::gfxContentType contentType = isOpaque
|
||||
? gfxASurface::CONTENT_COLOR
|
||||
: gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
gfxASurface::gfxImageFormat format
|
||||
= gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType);
|
||||
mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
|
||||
MOZ_ASSERT(mBuffer->AsTextureClientSurface());
|
||||
mBuffer->AsTextureClientSurface()->AllocateForSurface(aSize);
|
||||
|
||||
AddTextureClient(mBuffer);
|
||||
}
|
||||
|
||||
if (!mBuffer->Lock(OPEN_READ_WRITE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface = mBuffer->AsTextureClientSurface()->GetAsSurface();
|
||||
if (surface) {
|
||||
aLayer->UpdateSurface(surface);
|
||||
}
|
||||
|
||||
mBuffer->Unlock();
|
||||
|
||||
if (surface) {
|
||||
GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
|
||||
GetForwarder()->UseTexture(this, mBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
return CompositableClient::CreateBufferTextureClient(aFormat,
|
||||
mTextureInfo.mTextureFlags);
|
||||
}
|
||||
|
||||
void
|
||||
DeprecatedCanvasClient2D::Updated()
|
||||
{
|
||||
mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->GetDescriptor());
|
||||
}
|
||||
|
||||
|
||||
CanvasClient2D::CanvasClient2D(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags)
|
||||
DeprecatedCanvasClient2D::DeprecatedCanvasClient2D(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aFwd, aFlags)
|
||||
{
|
||||
mTextureInfo.mCompositableType = BUFFER_IMAGE_SINGLE;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (!mDeprecatedTextureClient) {
|
||||
mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
|
@ -67,7 +117,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|||
}
|
||||
|
||||
void
|
||||
CanvasClientSurfaceStream::Updated()
|
||||
DeprecatedCanvasClientSurfaceStream::Updated()
|
||||
{
|
||||
if (mNeedsUpdate) {
|
||||
mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->GetDescriptor());
|
||||
|
@ -76,8 +126,8 @@ CanvasClientSurfaceStream::Updated()
|
|||
}
|
||||
|
||||
|
||||
CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags)
|
||||
DeprecatedCanvasClientSurfaceStream::DeprecatedCanvasClientSurfaceStream(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aFwd, aFlags)
|
||||
, mNeedsUpdate(false)
|
||||
{
|
||||
|
@ -85,7 +135,7 @@ CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aFwd
|
|||
}
|
||||
|
||||
void
|
||||
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (!mDeprecatedTextureClient) {
|
||||
mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_STREAM_GL);
|
||||
|
|
|
@ -44,15 +44,9 @@ public:
|
|||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) = 0;
|
||||
|
||||
virtual void Updated();
|
||||
virtual void Updated() { }
|
||||
|
||||
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
|
||||
const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE
|
||||
{
|
||||
mDeprecatedTextureClient->SetDescriptorFromReply(aDescriptor);
|
||||
}
|
||||
protected:
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
|
||||
TextureInfo mTextureInfo;
|
||||
};
|
||||
|
||||
|
@ -61,23 +55,40 @@ class CanvasClient2D : public CanvasClient
|
|||
{
|
||||
public:
|
||||
CanvasClient2D(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags);
|
||||
|
||||
TextureInfo GetTextureInfo() const MOZ_OVERRIDE
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aLayerForwarder, aFlags)
|
||||
{
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
};
|
||||
TextureInfo GetTextureInfo() const
|
||||
{
|
||||
return TextureInfo(COMPOSITABLE_IMAGE);
|
||||
}
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
// GL backend.
|
||||
class CanvasClientSurfaceStream : public CanvasClient
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
|
||||
|
||||
virtual void AddTextureClient(TextureClient* aTexture) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT((mTextureInfo.mTextureFlags & aTexture->GetFlags()) == mTextureInfo.mTextureFlags);
|
||||
CompositableClient::AddTextureClient(aTexture);
|
||||
}
|
||||
|
||||
virtual TemporaryRef<BufferTextureClient>
|
||||
CreateBufferTextureClient(gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Detach() MOZ_OVERRIDE
|
||||
{
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mBuffer;
|
||||
};
|
||||
class DeprecatedCanvasClient2D : public CanvasClient
|
||||
{
|
||||
public:
|
||||
CanvasClientSurfaceStream(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags);
|
||||
DeprecatedCanvasClient2D(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags);
|
||||
|
||||
TextureInfo GetTextureInfo() const MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -87,7 +98,40 @@ public:
|
|||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
virtual void Updated() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
|
||||
const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE
|
||||
{
|
||||
mDeprecatedTextureClient->SetDescriptorFromReply(aDescriptor);
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
|
||||
};
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
// GL backend.
|
||||
class DeprecatedCanvasClientSurfaceStream : public CanvasClient
|
||||
{
|
||||
public:
|
||||
DeprecatedCanvasClientSurfaceStream(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags);
|
||||
|
||||
TextureInfo GetTextureInfo() const MOZ_OVERRIDE
|
||||
{
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
virtual void Updated() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
|
||||
const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE
|
||||
{
|
||||
mDeprecatedTextureClient->SetDescriptorFromReply(aDescriptor);
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
|
||||
bool mNeedsUpdate;
|
||||
};
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ ClientCanvasLayer::RenderLayer()
|
|||
}
|
||||
|
||||
if (!mCanvasClient) {
|
||||
TextureFlags flags = 0;
|
||||
TextureFlags flags = TEXTURE_IMMEDIATE_UPLOAD;
|
||||
if (mNeedsYFlip) {
|
||||
flags |= NeedsYFlip;
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ ClientCanvasLayer::RenderLayer()
|
|||
|
||||
ClientManager()->Hold(this);
|
||||
mCanvasClient->Updated();
|
||||
mCanvasClient->OnTransaction();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
|
|
|
@ -86,8 +86,9 @@ protected:
|
|||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
|
||||
friend class DeprecatedCanvasClient2D;
|
||||
friend class CanvasClient2D;
|
||||
friend class CanvasClientSurfaceStream;
|
||||
friend class DeprecatedCanvasClientSurfaceStream;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,6 +145,9 @@ ClientImageLayer::RenderLayer()
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (mImageClient) {
|
||||
mImageClient->OnTransaction();
|
||||
}
|
||||
ClientManager()->Hold(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "gfxPlatform.h"
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/TextureD3D9.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
@ -112,6 +113,7 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
|||
break;
|
||||
case TEXTURE_YCBCR:
|
||||
if (parentBackend == LAYERS_OPENGL ||
|
||||
parentBackend == LAYERS_D3D9 ||
|
||||
parentBackend == LAYERS_D3D11 ||
|
||||
parentBackend == LAYERS_BASIC) {
|
||||
result = new DeprecatedTextureClientShmemYCbCr(GetForwarder(), GetTextureInfo());
|
||||
|
@ -123,11 +125,23 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
|||
result = new DeprecatedTextureClientD3D11(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
if (parentBackend == LAYERS_D3D9 &&
|
||||
!GetForwarder()->ForwardsToDifferentProcess()) {
|
||||
result = new DeprecatedTextureClientD3D9(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through to TEXTURE_SHMEM
|
||||
case TEXTURE_SHMEM:
|
||||
result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
case TEXTURE_FALLBACK:
|
||||
#ifdef XP_WIN
|
||||
if (parentBackend == LAYERS_D3D9) {
|
||||
result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unhandled texture client type");
|
||||
}
|
||||
|
@ -147,16 +161,22 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
|
|||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
|
||||
CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
|
||||
RefPtr<BufferTextureClient> result = new MemoryTextureClient(this, aFormat);
|
||||
RefPtr<BufferTextureClient> result = new MemoryTextureClient(this, aFormat, aTextureFlags);
|
||||
return result.forget();
|
||||
}
|
||||
RefPtr<BufferTextureClient> result = new ShmemTextureClient(this, aFormat);
|
||||
RefPtr<BufferTextureClient> result = new ShmemTextureClient(this, aFormat, aTextureFlags);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
return CreateBufferTextureClient(aFormat, TEXTURE_FLAGS_DEFAULT);
|
||||
}
|
||||
|
||||
void
|
||||
CompositableClient::AddTextureClient(TextureClient* aClient)
|
||||
|
|
|
@ -77,6 +77,9 @@ public:
|
|||
CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType);
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
|
||||
|
||||
virtual TemporaryRef<BufferTextureClient>
|
||||
CreateBufferTextureClient(gfx::SurfaceFormat aFormat);
|
||||
|
||||
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
|
||||
|
|
|
@ -26,9 +26,10 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
|||
{
|
||||
LayersBackend backend = aForwarder->GetCompositorBackendType();
|
||||
if (backend != LAYERS_OPENGL &&
|
||||
backend != LAYERS_D3D9 &&
|
||||
backend != LAYERS_D3D11 &&
|
||||
backend != LAYERS_BASIC) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool useDoubleBuffering = false;
|
||||
|
@ -138,6 +139,25 @@ ContentClientRemoteBuffer::EndPaint()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtr<DeprecatedTextureClient>& aClient)
|
||||
{
|
||||
aClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(aClient, "Failed to create texture client");
|
||||
|
||||
if (!aClient->EnsureAllocated(mSize, mContentType)) {
|
||||
aClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK);
|
||||
MOZ_ASSERT(aClient, "Failed to create texture client");
|
||||
if (!aClient->EnsureAllocated(mSize, mContentType)) {
|
||||
NS_WARNING("Could not allocate texture client");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*aClient->GetDescriptor()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
|
||||
const nsIntRect& aRect,
|
||||
|
@ -155,22 +175,20 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
|
|||
}
|
||||
DestroyBuffers();
|
||||
}
|
||||
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
|
||||
mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client");
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
mDeprecatedTextureClientOnWhite = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mDeprecatedTextureClientOnWhite, "Failed to create texture client");
|
||||
mTextureInfo.mTextureFlags |= ComponentAlpha;
|
||||
}
|
||||
|
||||
mContentType = aType;
|
||||
mSize = gfx::IntSize(aRect.width, aRect.height);
|
||||
mDeprecatedTextureClient->EnsureAllocated(mSize, mContentType);
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*mDeprecatedTextureClient->GetDescriptor()));
|
||||
if (mDeprecatedTextureClientOnWhite) {
|
||||
mDeprecatedTextureClientOnWhite->EnsureAllocated(mSize, mContentType);
|
||||
MOZ_ASSERT(IsSurfaceDescriptorValid(*mDeprecatedTextureClientOnWhite->GetDescriptor()));
|
||||
mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
|
||||
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aFlags & BUFFER_COMPONENT_ALPHA) {
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClientOnWhite)) {
|
||||
return;
|
||||
}
|
||||
mTextureInfo.mTextureFlags |= ComponentAlpha;
|
||||
}
|
||||
|
||||
CreateFrontBufferAndNotify(aRect);
|
||||
|
@ -283,19 +301,19 @@ ContentClientDoubleBuffered::~ContentClientDoubleBuffered()
|
|||
void
|
||||
ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect)
|
||||
{
|
||||
mFrontClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mFrontClient, "Failed to create texture client");
|
||||
mFrontClient->EnsureAllocated(mSize, mContentType);
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClient)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTextureInfo.mTextureFlags & ComponentAlpha) {
|
||||
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClientOnWhite)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mFrontBufferRect = aBufferRect;
|
||||
mFrontBufferRotation = nsIntPoint();
|
||||
|
||||
if (mTextureInfo.mTextureFlags & ComponentAlpha) {
|
||||
mFrontClientOnWhite = CreateDeprecatedTextureClient(TEXTURE_CONTENT);
|
||||
MOZ_ASSERT(mFrontClientOnWhite, "Failed to create texture client");
|
||||
mFrontClientOnWhite->EnsureAllocated(mSize, mContentType);
|
||||
}
|
||||
|
||||
mForwarder->CreatedDoubleBuffer(this,
|
||||
*mFrontClient->GetDescriptor(),
|
||||
*mDeprecatedTextureClient->GetDescriptor(),
|
||||
|
|
|
@ -253,6 +253,8 @@ protected:
|
|||
// lock it now.
|
||||
virtual void LockFrontBuffer() {}
|
||||
|
||||
bool CreateAndAllocateDeprecatedTextureClient(RefPtr<DeprecatedTextureClient>& aClient);
|
||||
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClient;
|
||||
RefPtr<DeprecatedTextureClient> mDeprecatedTextureClientOnWhite;
|
||||
// keep a record of texture clients we have created and need to keep
|
||||
|
|
|
@ -121,7 +121,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
|||
mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV);
|
||||
gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
|
||||
gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
|
||||
if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize)) {
|
||||
if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) {
|
||||
mFrontBuffer = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
@ -146,7 +146,10 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
|||
nsRefPtr<gfxASurface> surface = image->GetAsSurface();
|
||||
MOZ_ASSERT(surface);
|
||||
|
||||
if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
|
||||
gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
|
||||
|
||||
if (mFrontBuffer &&
|
||||
(mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
|
||||
RemoveTextureClient(mFrontBuffer);
|
||||
mFrontBuffer = nullptr;
|
||||
}
|
||||
|
@ -155,7 +158,6 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
|||
gfxASurface::gfxImageFormat format
|
||||
= gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
|
||||
mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
|
||||
gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
|
||||
MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface());
|
||||
mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size);
|
||||
|
||||
|
@ -195,10 +197,16 @@ ImageClientBuffered::UpdateImage(ImageContainer* aContainer,
|
|||
void
|
||||
ImageClientSingle::AddTextureClient(TextureClient* aTexture)
|
||||
{
|
||||
aTexture->AddFlags(mTextureFlags);
|
||||
MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
|
||||
CompositableClient::AddTextureClient(aTexture);
|
||||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
ImageClientSingle::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
return CompositableClient::CreateBufferTextureClient(aFormat, mTextureFlags);
|
||||
}
|
||||
|
||||
void
|
||||
ImageClientSingle::Detach()
|
||||
{
|
||||
|
|
|
@ -77,6 +77,9 @@ public:
|
|||
|
||||
virtual void AddTextureClient(TextureClient* aTexture) MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<BufferTextureClient>
|
||||
CreateBufferTextureClient(gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE;
|
||||
protected:
|
||||
RefPtr<TextureClient> mFrontBuffer;
|
||||
|
|
|
@ -88,8 +88,9 @@ ShmemTextureClient::GetBufferSize() const
|
|||
}
|
||||
|
||||
ShmemTextureClient::ShmemTextureClient(CompositableClient* aCompositable,
|
||||
gfx::SurfaceFormat aFormat)
|
||||
: BufferTextureClient(aCompositable, aFormat)
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: BufferTextureClient(aCompositable, aFormat, aFlags)
|
||||
, mAllocated(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ShmemTextureClient);
|
||||
|
@ -125,8 +126,10 @@ MemoryTextureClient::Allocate(uint32_t aSize)
|
|||
return true;
|
||||
}
|
||||
|
||||
MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat)
|
||||
: BufferTextureClient(aCompositable, aFormat)
|
||||
MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: BufferTextureClient(aCompositable, aFormat, aFlags)
|
||||
, mBuffer(nullptr)
|
||||
, mBufSize(0)
|
||||
{
|
||||
|
@ -144,8 +147,9 @@ MemoryTextureClient::~MemoryTextureClient()
|
|||
}
|
||||
|
||||
BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable,
|
||||
gfx::SurfaceFormat aFormat)
|
||||
: TextureClient()
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aFlags)
|
||||
, mCompositable(aCompositable)
|
||||
, mFormat(aFormat)
|
||||
{}
|
||||
|
@ -172,9 +176,28 @@ BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
|
|||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->DrawSurface(aSurface, gfxSize(serializer.GetSize().width,
|
||||
serializer.GetSize().height));
|
||||
|
||||
if (TextureRequiresLocking(mFlags)) {
|
||||
// We don't have support for proper locking yet, so we'll
|
||||
// have to be immutable instead.
|
||||
MarkImmutable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BufferTextureClient::GetAsSurface()
|
||||
{
|
||||
ImageDataSerializer serializer(GetBuffer());
|
||||
if (!serializer.IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
|
||||
nsRefPtr<gfxASurface> result = surf.get();
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureClient::AllocateForSurface(gfx::IntSize aSize)
|
||||
{
|
||||
|
@ -187,6 +210,7 @@ BufferTextureClient::AllocateForSurface(gfx::IntSize aSize)
|
|||
}
|
||||
ImageDataSerializer serializer(GetBuffer());
|
||||
serializer.InitializeBufferInfo(aSize, mFormat);
|
||||
mSize = aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -206,11 +230,19 @@ BufferTextureClient::UpdateYCbCr(const PlanarYCbCrImage::Data& aData)
|
|||
NS_WARNING("Failed to copy image data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TextureRequiresLocking(mFlags)) {
|
||||
// We don't have support for proper locking yet, so we'll
|
||||
// have to be immutable instead.
|
||||
MarkImmutable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize)
|
||||
BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode)
|
||||
{
|
||||
size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize,
|
||||
aCbCrSize);
|
||||
|
@ -219,7 +251,9 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSiz
|
|||
}
|
||||
YCbCrImageDataSerializer serializer(GetBuffer());
|
||||
serializer.InitializeBufferInfo(aYSize,
|
||||
aCbCrSize);
|
||||
aCbCrSize,
|
||||
aStereoMode);
|
||||
mSize = aYSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -273,7 +307,7 @@ DeprecatedTextureClientShmem::ReleaseResources()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aContentType)
|
||||
{
|
||||
|
@ -290,6 +324,7 @@ DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize,
|
|||
NS_WARNING("creating SurfaceDescriptor failed!");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -401,11 +436,12 @@ DeprecatedTextureClientShmemYCbCr::SetDescriptorFromReply(const SurfaceDescripto
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientShmemYCbCr::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
NS_RUNTIMEABORT("not enough arguments to do this (need both Y and CbCr sizes)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -417,7 +453,7 @@ DeprecatedTextureClientTile::DeprecatedTextureClientTile(CompositableForwarder*
|
|||
mTextureInfo.mDeprecatedTextureHostFlags = TEXTURE_HOST_TILED;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
|
||||
{
|
||||
if (!mSurface ||
|
||||
|
@ -428,6 +464,7 @@ DeprecatedTextureClientTile::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gf
|
|||
mSurface = new gfxReusableSurfaceWrapper(tmpTile);
|
||||
mContentType = aType;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
|
@ -549,7 +586,8 @@ bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage
|
|||
|
||||
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
|
||||
serializer.InitializeBufferInfo(data->mYSize,
|
||||
data->mCbCrSize);
|
||||
data->mCbCrSize,
|
||||
data->mStereoMode);
|
||||
|
||||
*mDescriptor = YCbCrImage(shmem, 0);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class TextureClientSurface
|
|||
{
|
||||
public:
|
||||
virtual bool UpdateSurface(gfxASurface* aSurface) = 0;
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize) = 0;
|
||||
};
|
||||
|
||||
|
@ -54,7 +55,9 @@ class TextureClientYCbCr
|
|||
{
|
||||
public:
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) = 0;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) = 0;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -124,30 +127,7 @@ public:
|
|||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
|
||||
|
||||
void SetFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
mFlags = aFlags;
|
||||
}
|
||||
|
||||
void AddFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
// make sure we don't deallocate on both client and host;
|
||||
MOZ_ASSERT(!(aFlags & TEXTURE_DEALLOCATE_CLIENT && aFlags & TEXTURE_DEALLOCATE_HOST));
|
||||
if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
|
||||
mFlags &= ~TEXTURE_DEALLOCATE_HOST;
|
||||
} else if (aFlags & TEXTURE_DEALLOCATE_HOST) {
|
||||
mFlags &= ~TEXTURE_DEALLOCATE_CLIENT;
|
||||
}
|
||||
mFlags |= aFlags;
|
||||
}
|
||||
|
||||
void RemoveFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
mFlags &= (~aFlags);
|
||||
}
|
||||
virtual gfx::IntSize GetSize() const = 0;
|
||||
|
||||
TextureFlags GetFlags() const { return mFlags; }
|
||||
|
||||
|
@ -164,6 +144,19 @@ public:
|
|||
|
||||
bool ShouldDeallocateInDestructor() const;
|
||||
protected:
|
||||
void AddFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
// make sure we don't deallocate on both client and host;
|
||||
MOZ_ASSERT(!(aFlags & TEXTURE_DEALLOCATE_CLIENT && aFlags & TEXTURE_DEALLOCATE_HOST));
|
||||
if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
|
||||
mFlags &= ~TEXTURE_DEALLOCATE_HOST;
|
||||
} else if (aFlags & TEXTURE_DEALLOCATE_HOST) {
|
||||
mFlags &= ~TEXTURE_DEALLOCATE_CLIENT;
|
||||
}
|
||||
mFlags |= aFlags;
|
||||
}
|
||||
|
||||
uint64_t mID;
|
||||
RefPtr<TextureClient> mNextSibling;
|
||||
TextureFlags mFlags;
|
||||
|
@ -179,7 +172,8 @@ class BufferTextureClient : public TextureClient
|
|||
, TextureClientYCbCr
|
||||
{
|
||||
public:
|
||||
BufferTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
|
||||
BufferTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual ~BufferTextureClient();
|
||||
|
||||
|
@ -193,12 +187,16 @@ public:
|
|||
|
||||
virtual size_t GetBufferSize() const = 0;
|
||||
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
// TextureClientSurface
|
||||
|
||||
virtual TextureClientSurface* AsTextureClientSurface() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual bool UpdateSurface(gfxASurface* aSurface) MOZ_OVERRIDE;
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize) MOZ_OVERRIDE;
|
||||
|
||||
// TextureClientYCbCr
|
||||
|
@ -207,13 +205,16 @@ public:
|
|||
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrImage::Data& aData) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize) MOZ_OVERRIDE;
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) MOZ_OVERRIDE;
|
||||
|
||||
gfx::SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
protected:
|
||||
CompositableClient* mCompositable;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -223,7 +224,8 @@ protected:
|
|||
class ShmemTextureClient : public BufferTextureClient
|
||||
{
|
||||
public:
|
||||
ShmemTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
|
||||
ShmemTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
~ShmemTextureClient();
|
||||
|
||||
|
@ -255,7 +257,8 @@ protected:
|
|||
class MemoryTextureClient : public BufferTextureClient
|
||||
{
|
||||
public:
|
||||
MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat);
|
||||
MemoryTextureClient(CompositableClient* aCompositable, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
~MemoryTextureClient();
|
||||
|
||||
|
@ -355,8 +358,9 @@ public:
|
|||
/**
|
||||
* Ensure that the texture client is suitable for the given size and content
|
||||
* type and that any initialisation has taken place.
|
||||
* Returns true if succeeded, false if failed.
|
||||
*/
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) = 0;
|
||||
|
||||
/**
|
||||
|
@ -423,13 +427,13 @@ public:
|
|||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE
|
||||
{
|
||||
return aType == TEXTURE_SHMEM || aType == TEXTURE_CONTENT;
|
||||
return aType == TEXTURE_SHMEM || aType == TEXTURE_CONTENT || aType == TEXTURE_FALLBACK;
|
||||
}
|
||||
virtual gfxImageSurface* LockImageSurface() MOZ_OVERRIDE;
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE { return GetSurface(); }
|
||||
virtual gfx::DrawTarget* LockDrawTarget();
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ReleaseResources() MOZ_OVERRIDE;
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
|
@ -457,7 +461,7 @@ public:
|
|||
~DeprecatedTextureClientShmemYCbCr() { ReleaseResources(); }
|
||||
|
||||
virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_YCBCR; }
|
||||
void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
bool EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
virtual void SetDescriptorFromReply(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual void ReleaseResources();
|
||||
|
@ -472,7 +476,7 @@ public:
|
|||
const TextureInfo& aTextureInfo);
|
||||
~DeprecatedTextureClientTile();
|
||||
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxImageSurface* LockImageSurface() MOZ_OVERRIDE;
|
||||
|
|
|
@ -33,7 +33,8 @@ CanvasLayerComposite::~CanvasLayerComposite()
|
|||
CleanupResources();
|
||||
}
|
||||
|
||||
void CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
|
||||
void
|
||||
CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) {
|
||||
mImageHost = aHost;
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,7 @@ CanvasLayerComposite::GetLayer()
|
|||
LayerRenderState
|
||||
CanvasLayerComposite::GetRenderState()
|
||||
{
|
||||
if (mDestroyed || !mImageHost) {
|
||||
if (mDestroyed || !mImageHost || !mImageHost->IsAttached()) {
|
||||
return LayerRenderState();
|
||||
}
|
||||
return mImageHost->GetRenderState();
|
||||
|
@ -56,7 +57,7 @@ void
|
|||
CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mImageHost) {
|
||||
if (!mImageHost || !mImageHost->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -98,8 +99,13 @@ CanvasLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
|||
}
|
||||
|
||||
CompositableHost*
|
||||
CanvasLayerComposite::GetCompositableHost() {
|
||||
return mImageHost.get();
|
||||
CanvasLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mImageHost->IsAttached()) {
|
||||
return mImageHost.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -117,7 +123,7 @@ CanvasLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
|||
{
|
||||
CanvasLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mImageHost->PrintInfo(aTo, pfx.get());
|
||||
|
|
|
@ -18,6 +18,7 @@ CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
|
|||
: mTextureInfo(aTextureInfo)
|
||||
, mCompositor(nullptr)
|
||||
, mLayer(nullptr)
|
||||
, mAttached(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositableHost);
|
||||
}
|
||||
|
|
|
@ -187,13 +187,18 @@ public:
|
|||
virtual void Attach(Layer* aLayer, Compositor* aCompositor)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor, "Compositor is required");
|
||||
MOZ_ASSERT(!IsAttached());
|
||||
SetCompositor(aCompositor);
|
||||
SetLayer(aLayer);
|
||||
mAttached = true;
|
||||
}
|
||||
void Detach() {
|
||||
void Detach()
|
||||
{
|
||||
SetLayer(nullptr);
|
||||
SetCompositor(nullptr);
|
||||
mAttached = false;
|
||||
}
|
||||
bool IsAttached() { return mAttached; }
|
||||
|
||||
virtual void Dump(FILE* aFile=nullptr,
|
||||
const char* aPrefix="",
|
||||
|
@ -219,6 +224,7 @@ protected:
|
|||
Compositor* mCompositor;
|
||||
Layer* mLayer;
|
||||
RefPtr<TextureHost> mFirstTexture;
|
||||
bool mAttached;
|
||||
};
|
||||
|
||||
class CompositableParentManager;
|
||||
|
|
|
@ -54,7 +54,7 @@ ImageLayerComposite::Disconnect()
|
|||
LayerRenderState
|
||||
ImageLayerComposite::GetRenderState()
|
||||
{
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
return mImageHost->GetRenderState();
|
||||
}
|
||||
return LayerRenderState();
|
||||
|
@ -70,7 +70,7 @@ void
|
|||
ImageLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mImageHost) {
|
||||
if (!mImageHost || !mImageHost->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,8 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
|||
// Snap image edges to pixel boundaries
|
||||
gfxRect sourceRect(0, 0, 0, 0);
|
||||
if (mImageHost &&
|
||||
(mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) {
|
||||
mImageHost->IsAttached() &&
|
||||
(mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) {
|
||||
IntSize size =
|
||||
mImageHost->GetTextureHost() ? mImageHost->GetTextureHost()->GetSize()
|
||||
: mImageHost->GetDeprecatedTextureHost()->GetSize();
|
||||
|
@ -132,8 +133,12 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
|||
}
|
||||
|
||||
CompositableHost*
|
||||
ImageLayerComposite::GetCompositableHost() {
|
||||
return mImageHost.get();
|
||||
ImageLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mImageHost->IsAttached())
|
||||
return mImageHost.get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -151,7 +156,7 @@ ImageLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
|||
{
|
||||
ImageLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mImageHost) {
|
||||
if (mImageHost && mImageHost->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mImageHost->PrintInfo(aTo, pfx.get());
|
||||
|
|
|
@ -86,6 +86,7 @@ LayerManagerComposite::ClearCachedResources(Layer* aSubtree)
|
|||
LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
|
||||
: mCompositor(aCompositor)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor);
|
||||
}
|
||||
|
||||
LayerManagerComposite::~LayerManagerComposite()
|
||||
|
|
|
@ -27,15 +27,11 @@ TemporaryRef<DeprecatedTextureHost> CreateBasicDeprecatedTextureHost(SurfaceDesc
|
|||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
NS_RUNTIMEABORT("not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t aTextureFlags);
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aDeprecatedTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
|
@ -51,11 +47,11 @@ DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptorType aDescri
|
|||
return CreateDeprecatedTextureHostOGL(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D9:
|
||||
return CreateDeprecatedTextureHostD3D9(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D11:
|
||||
return CreateDeprecatedTextureHostD3D11(aDescriptorType,
|
||||
aDeprecatedTextureHostFlags,
|
||||
|
@ -229,6 +225,9 @@ BufferTextureHost::Updated(const nsIntRegion* aRegion)
|
|||
} else {
|
||||
mPartialUpdate = false;
|
||||
}
|
||||
if (GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) {
|
||||
MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -268,11 +267,8 @@ NewTextureSource*
|
|||
BufferTextureHost::GetTextureSources()
|
||||
{
|
||||
MOZ_ASSERT(mLocked, "should never be called while not locked");
|
||||
if (!mFirstSource || mUpdateSerial != mFirstSource->GetUpdateSerial()) {
|
||||
if (!Upload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr)) {
|
||||
if (!MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr)) {
|
||||
return nullptr;
|
||||
}
|
||||
mFirstSource->SetUpdateSerial(mUpdateSerial);
|
||||
}
|
||||
return mFirstSource;
|
||||
}
|
||||
|
@ -293,6 +289,19 @@ BufferTextureHost::GetFormat() const
|
|||
return mFormat;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureHost::MaybeUpload(nsIntRegion *aRegion)
|
||||
{
|
||||
if (mFirstSource && mFirstSource->GetUpdateSerial() == mUpdateSerial) {
|
||||
return true;
|
||||
}
|
||||
if (!Upload(aRegion)) {
|
||||
return false;
|
||||
}
|
||||
mFirstSource->SetUpdateSerial(mUpdateSerial);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureHost::Upload(nsIntRegion *aRegion)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ class Compositor;
|
|||
class SurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureSourceOGL;
|
||||
class TextureSourceD3D9;
|
||||
class TextureSourceD3D11;
|
||||
class TextureSourceBasic;
|
||||
class TextureParent;
|
||||
|
@ -87,18 +88,11 @@ public:
|
|||
virtual gfx::SurfaceFormat GetFormat() const { return gfx::FORMAT_UNKNOWN; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the OpenGL backend.
|
||||
* Cast to a TextureSource for for each backend..
|
||||
*/
|
||||
virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the D3D11 backend.
|
||||
*/
|
||||
virtual TextureSourceD3D9* AsSourceD3D9() { return nullptr; }
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to a TextureSource for the software backend.
|
||||
*/
|
||||
virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
|
||||
|
||||
/**
|
||||
|
@ -449,6 +443,7 @@ public:
|
|||
|
||||
protected:
|
||||
bool Upload(nsIntRegion *aRegion = nullptr);
|
||||
bool MaybeUpload(nsIntRegion *aRegion = nullptr);
|
||||
|
||||
Compositor* mCompositor;
|
||||
RefPtr<DataTextureSource> mFirstSource;
|
||||
|
|
|
@ -29,6 +29,7 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
|
|||
: ThebesLayer(aManager, nullptr)
|
||||
, LayerComposite(aManager)
|
||||
, mBuffer(nullptr)
|
||||
, mRequiresTiledProperties(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ThebesLayerComposite);
|
||||
mImplData = static_cast<LayerComposite*>(this);
|
||||
|
@ -37,15 +38,13 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
|
|||
ThebesLayerComposite::~ThebesLayerComposite()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ThebesLayerComposite);
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
CleanupResources();
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerComposite::SetCompositableHost(CompositableHost* aHost)
|
||||
{
|
||||
mBuffer= static_cast<ContentHost*>(aHost);
|
||||
mBuffer = static_cast<ContentHost*>(aHost);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -58,10 +57,7 @@ void
|
|||
ThebesLayerComposite::Destroy()
|
||||
{
|
||||
if (!mDestroyed) {
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
mBuffer = nullptr;
|
||||
CleanupResources();
|
||||
mDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +71,14 @@ ThebesLayerComposite::GetLayer()
|
|||
TiledLayerComposer*
|
||||
ThebesLayerComposite::GetTiledLayerComposer()
|
||||
{
|
||||
MOZ_ASSERT(mBuffer && mBuffer->IsAttached());
|
||||
return mBuffer->AsTiledLayerComposer();
|
||||
}
|
||||
|
||||
LayerRenderState
|
||||
ThebesLayerComposite::GetRenderState()
|
||||
{
|
||||
if (!mBuffer || mDestroyed) {
|
||||
if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
|
||||
return LayerRenderState();
|
||||
}
|
||||
return mBuffer->GetRenderState();
|
||||
|
@ -91,10 +88,14 @@ void
|
|||
ThebesLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
||||
const nsIntRect& aClipRect)
|
||||
{
|
||||
if (!mBuffer) {
|
||||
if (!mBuffer || !mBuffer->IsAttached()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBuffer->GetCompositor() == mCompositeManager->GetCompositor() &&
|
||||
mBuffer->GetLayer() == this,
|
||||
"buffer is corrupted");
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
|
@ -145,14 +146,19 @@ ThebesLayerComposite::RenderLayer(const nsIntPoint& aOffset,
|
|||
}
|
||||
|
||||
CompositableHost*
|
||||
ThebesLayerComposite::GetCompositableHost() {
|
||||
return mBuffer.get();
|
||||
ThebesLayerComposite::GetCompositableHost()
|
||||
{
|
||||
if (mBuffer->IsAttached()) {
|
||||
return mBuffer.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerComposite::CleanupResources()
|
||||
{
|
||||
if (mBuffer) {
|
||||
if (mBuffer) {
|
||||
mBuffer->Detach();
|
||||
}
|
||||
mBuffer = nullptr;
|
||||
|
@ -283,7 +289,7 @@ ThebesLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix)
|
|||
{
|
||||
ThebesLayer::PrintInfo(aTo, aPrefix);
|
||||
aTo += "\n";
|
||||
if (mBuffer) {
|
||||
if (mBuffer && mBuffer->IsAttached()) {
|
||||
nsAutoCString pfx(aPrefix);
|
||||
pfx += " ";
|
||||
mBuffer->PrintInfo(aTo, pfx.get());
|
||||
|
|
|
@ -319,6 +319,7 @@ CompositorD3D11::GetTextureFactoryIdentifier()
|
|||
{
|
||||
TextureFactoryIdentifier ident;
|
||||
ident.mMaxTextureSize = GetMaxTextureSize();
|
||||
ident.mParentProcessId = XRE_GetProcessType();
|
||||
ident.mParentBackend = LAYERS_D3D11;
|
||||
return ident;
|
||||
}
|
||||
|
@ -566,39 +567,47 @@ CompositorD3D11::BeginFrame(const Rect* aClipRectIn,
|
|||
Rect* aClipRectOut,
|
||||
Rect* aRenderBoundsOut)
|
||||
{
|
||||
VerifyBufferSize();
|
||||
UpdateRenderTarget();
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
if (mSize.width == 0 || mSize.height == 0) {
|
||||
*aRenderBoundsOut = Rect();
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT->SetSize(IntSize(rect.width, rect.height));
|
||||
|
||||
mContext->IASetInputLayout(mAttachments->mInputLayout);
|
||||
|
||||
ID3D11Buffer* buffer = mAttachments->mVertexBuffer;
|
||||
UINT size = sizeof(Vertex);
|
||||
UINT offset = 0;
|
||||
mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
|
||||
SetRenderTarget(mDefaultRT);
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, rect.width, rect.height);
|
||||
*aClipRectOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
if (aRenderBoundsOut) {
|
||||
*aRenderBoundsOut = Rect(0, 0, rect.width, rect.height);
|
||||
*aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
|
||||
D3D11_RECT scissor;
|
||||
if (aClipRectIn) {
|
||||
scissor.left = aClipRectIn->x;
|
||||
scissor.right = aClipRectIn->XMost();
|
||||
scissor.top = aClipRectIn->y;
|
||||
scissor.bottom = aClipRectIn->YMost();
|
||||
} else {
|
||||
scissor.left = scissor.top = 0;
|
||||
scissor.right = mSize.width;
|
||||
scissor.bottom = mSize.height;
|
||||
}
|
||||
mContext->RSSetScissorRects(1, &scissor);
|
||||
|
||||
FLOAT black[] = { 0, 0, 0, 0 };
|
||||
mContext->ClearRenderTargetView(mDefaultRT->mRTView, black);
|
||||
|
||||
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
mContext->RSSetState(mAttachments->mRasterizerState);
|
||||
|
||||
SetRenderTarget(mDefaultRT);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -640,43 +649,41 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
|
|||
memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection));
|
||||
}
|
||||
|
||||
const nsIntSize&
|
||||
CompositorD3D11::GetWidgetSize()
|
||||
void
|
||||
CompositorD3D11::EnsureSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mSize = rect.Size();
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::VerifyBufferSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
mSwapChain->GetDesc(&swapDesc);
|
||||
|
||||
if ((swapDesc.BufferDesc.Width == rect.width &&
|
||||
swapDesc.BufferDesc.Height == rect.height) || rect.IsEmpty()) {
|
||||
if ((swapDesc.BufferDesc.Width == mSize.width &&
|
||||
swapDesc.BufferDesc.Height == mSize.height) ||
|
||||
mSize.width == 0 || mSize.height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT = nullptr;
|
||||
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
#ifdef MOZ_METRO
|
||||
} else if (IsRunningInWindowsMetro()) {
|
||||
mSwapChain->ResizeBuffers(2, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(2, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
#endif
|
||||
} else {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
||||
}
|
||||
|
@ -685,6 +692,9 @@ CompositorD3D11::VerifyBufferSize()
|
|||
void
|
||||
CompositorD3D11::UpdateRenderTarget()
|
||||
{
|
||||
EnsureSize();
|
||||
VerifyBufferSize();
|
||||
|
||||
if (mDefaultRT) {
|
||||
return;
|
||||
}
|
||||
|
@ -699,6 +709,7 @@ CompositorD3D11::UpdateRenderTarget()
|
|||
}
|
||||
|
||||
mDefaultRT = new CompositingRenderTargetD3D11(backBuf);
|
||||
mDefaultRT->SetSize(mSize);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -706,7 +717,6 @@ CompositorD3D11::CreateShaders()
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
||||
hr = mDevice->CreateVertexShader(LayerQuadVS,
|
||||
sizeof(LayerQuadVS),
|
||||
nullptr,
|
||||
|
@ -824,7 +834,7 @@ CompositorD3D11::PaintToTarget()
|
|||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(tmpSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
mTarget->Paint();
|
||||
|
||||
mContext->Unmap(readTexture, 0);
|
||||
|
|
|
@ -137,11 +137,20 @@ public:
|
|||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
|
||||
|
||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE;
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
||||
{
|
||||
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
|
||||
"You should not do that outside of BeginFrame, so the best we can do is return "
|
||||
"the last size we got, that might not be up to date. So you probably shouldn't "
|
||||
"use this method.");
|
||||
return mSize;
|
||||
}
|
||||
|
||||
ID3D11Device* GetDevice() { return mDevice; }
|
||||
|
||||
private:
|
||||
// ensure mSize is up to date with respect to mWidget
|
||||
void EnsureSize();
|
||||
void VerifyBufferSize();
|
||||
void UpdateRenderTarget();
|
||||
bool CreateShaders();
|
||||
|
@ -161,9 +170,7 @@ private:
|
|||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsIWidget* mWidget;
|
||||
// GetWidgetSize requires us to return a reference to an nsIntSize. Since we
|
||||
// don't otherwise keep this value around, we need mSize to avoid a dangling
|
||||
// reference problem.
|
||||
|
||||
nsIntSize mSize;
|
||||
|
||||
HWND mHwnd;
|
||||
|
|
|
@ -77,7 +77,7 @@ DeprecatedTextureClientD3D11::~DeprecatedTextureClientD3D11()
|
|||
ClearDT();
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType)
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
|||
mTexture->GetDesc(&desc);
|
||||
|
||||
if (desc.Width == aSize.width && desc.Height == aSize.height) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
mTexture = nullptr;
|
||||
|
@ -109,7 +109,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
|||
|
||||
if (FAILED(hr)) {
|
||||
LOGD3D11("Error creating texture for client!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<IDXGIResource> resource;
|
||||
|
@ -126,6 +126,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize,
|
|||
aType == gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
|
||||
mContentType = aType;
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
return aType == TEXTURE_CONTENT;
|
||||
}
|
||||
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize,
|
||||
virtual bool EnsureAllocated(gfx::IntSize aSize,
|
||||
gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE;
|
||||
|
|
|
@ -46,7 +46,7 @@ RenderColorLayerD3D9(ColorLayer* aLayer, LayerManagerD3D9 *aManager)
|
|||
color[2] = (float)(layerColor.b * opacity);
|
||||
color[3] = (float)(opacity);
|
||||
|
||||
aManager->device()->SetPixelShaderConstantF(0, color, 1);
|
||||
aManager->device()->SetPixelShaderConstantF(CBvColor, color, 1);
|
||||
|
||||
aManager->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER,
|
||||
aLayer->GetMaskLayer());
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче