new file mode 100644
--- /dev/null
+++ b/.reviewboardrc
@@ -0,0 +1,5 @@
+# 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/.
+
+REVIEWBOARD_URL = 'https://reviewboard.allizom.org/'
--- a/accessible/public/ia2/Makefile.in
+++ b/accessible/public/ia2/Makefile.in
@@ -1,18 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEFFILE = $(win_srcdir)/IA2Marshal.def
IA2DIR = $(topsrcdir)/other-licenses/ia2
-DEFINES += -DREGISTER_PROXY_DLL
-
GARBAGE += $(MIDL_GENERATED_FILES)
# Please keep this list in sync with the moz.build file until the rest of this
# Makefile is ported over.
MIDL_INTERFACES = \
Accessible2.idl \
Accessible2_2.idl \
AccessibleAction.idl \
--- a/accessible/public/ia2/moz.build
+++ b/accessible/public/ia2/moz.build
@@ -2,8 +2,10 @@
# 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/.
LIBRARY_NAME = 'IA2Marshal'
FORCE_SHARED_LIB = True
+
+DEFINES['REGISTER_PROXY_DLL'] = True
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -1,16 +1,14 @@
# 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/.
DEFFILE = $(win_srcdir)/AccessibleMarshal.def
-DEFINES += -DREGISTER_PROXY_DLL
-
GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
MIDL_GENERATED_FILES = \
ISimpleDOMNode.h \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMDocument.h \
ISimpleDOMDocument_p.c \
--- a/accessible/public/msaa/moz.build
+++ b/accessible/public/msaa/moz.build
@@ -12,8 +12,10 @@ GENERATED_SOURCES += [
'ISimpleDOMDocument_p.c',
'ISimpleDOMNode_i.c',
'ISimpleDOMNode_p.c',
'ISimpleDOMText_i.c',
'ISimpleDOMText_p.c',
]
FORCE_SHARED_LIB = True
+
+DEFINES['REGISTER_PROXY_DLL'] = True
--- a/accessible/tests/mochitest/jsat/a11y.ini
+++ b/accessible/tests/mochitest/jsat/a11y.ini
@@ -1,12 +1,14 @@
[DEFAULT]
support-files =
jsatcommon.js
output.js
+ doc_traversal.html
[test_alive.html]
[test_braille.html]
[test_explicit_names.html]
[test_landmarks.html]
[test_live_regions.html]
[test_tables.html]
+[test_traversal.html]
[test_utterance_order.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/jsat/doc_traversal.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Traversal Rule test document</title>
+ <meta charset="utf-8" />
+</head>
+<body>
+ <h3 id="heading-1">A small first heading</h3>
+ <form>
+ <label for="input-1-1">Name:</label>
+ <input id="input-1-1">
+ <label id="label-1-2">Favourite Ice Cream Flavour:<input id="input-1-2"></label>
+ <button id="button-1-1">Magic Button</button>
+ <label for="radio-1-1">Radios are old: </label>
+ <input id="radio-1-1" type="radio">
+ <label for="radio-1-2">Radios are new: </label>
+ <input id="radio-1-2" type="radio">
+ <label for="input-1-3">Password:</label>
+ <input id="input-1-3" type="password">
+ <label for="input-1-4">Unlucky number:</label>
+ <input id="input-1-4" type="tel">
+ <input id="button-1-2" type="button" value="Fun">
+ <label for="checkbox-1-1">Check me: </label>
+ <input id="checkbox-1-1" type="checkbox">
+ <select id="select-1-1">
+ <option>Value 1</option>
+ <option>Value 2</option>
+ <option>Value 3</option>
+ </select>
+ <select id="select-1-2" multiple="true">
+ <option>Value 1</option>
+ <option>Value 2</option>
+ <option>Value 3</option>
+ </select>
+ <label for="checkbox-1-2">Check me too: </label>
+ <input id="checkbox-1-2" type="checkbox">
+ <label for="checkbox-1-3">But not me: </label>
+ <input id="checkbox-1-3" type="checkbox" aria-hidden="true">
+ <label for="checkbox-1-4">Or me! </label>
+ <input id="checkbox-1-3" type="checkbox" style="visibility:hidden">
+ <select id="select-1-3" size="3">
+ <option>Value 1</option>
+ <option>Value 2</option>
+ <option>Value 3</option>
+ </select>
+ <label for="input-1-5">Electronic mailing address:</label>
+ <input id="input-1-5" type="email">
+ <input id="button-1-3" type="submit" value="Submit">
+
+ </form>
+ <h2 id="heading-2">A larger second</h2>
+ <div id="heading-3" role="heading">ARIA is fun</div>
+ <input id="button-2-1" type="button" value="More Fun">
+ <div id="button-2-2" tabindex="0" role="button">ARIA fun</div>
+ <div id="button-2-3" tabindex="0" role="button" aria-pressed="false">My little togglebutton</div>
+ <div id="button-2-4" tabindex="0" role="spinbutton">ARIA fun</div>
+ <h1 id="heading-4" style="display:none">Invisible header</h1>
+ <dl id="list-1">
+ <dt id="listitem-1-1">Programming Language</dt>
+ <dd>A esoteric weapon wielded by only the most formidable warriors,
+ for its unrelenting strict power is unfathomable.</dd>
+ </dl>
+ <ul id="list-2">
+ <li id="listitem-2-1">Lists of Programming Languages</li>
+ <li id="listitem-2-2">Lisp
+ <ol id="list-3">
+ <li id="listitem-3-1">Scheme</li>
+ <li id="listitem-3-2">Racket</li>
+ <li id="listitem-3-3">Clojure</li>
+ </ol>
+ </li>
+ <li id="listitem-2-3">JavaScript</li>
+ </ul>
+ <h6 id="heading-5">The last (visible) one!</h6>
+ <img id="image-1" src="http://example.com" alt="">
+ <img id="image-2" src="../moz.png" alt="stuff">
+ <div id="image-3" tabindex="0" role="img">Not actually an image</div>
+ <h4 id="heading-6" aria-hidden="true">Hidden header</h4>
+ <a id="link-1" href="http://www.mozilla.org">Link</a>
+ <a id="anchor-1">Words</a>
+ <a id="link-2" href="http://www.mozilla.org">Link the second</a>
+ <a id="anchor-2">Sentences</a>
+ <a id="link-3" href="http://www.example.com">Link the third</a>
+ <hr id="separator-1">
+ <table id="table-1">
+ <tr>
+ <td>3</td>
+ <td>1</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>1</td>
+ </tr>
+ </table>
+ <div id="separator-2" role="separator">Just an innocuous separator</div>
+ <table id="table-2">
+ <thead>
+ <tr>
+ <th>Dirty Words</th>
+ <th>Meaning</th>
+ </tr>
+ </thead>
+ <tfoot>
+ <tr>
+ <td>Mud</td>
+ <td>Wet Dirt</td>
+ </tr>
+ </tfoot>
+ <tbody>
+ <tr>
+ <td>Dirt</td>
+ <td>Messy Stuff</td>
+ </tr>
+ </tbody>
+ </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/jsat/test_traversal.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Tests AccessFu TraversalRules</title>
+ <meta charset="utf-8" />
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/chrome-harness.js">
+ </script>
+
+ <script type="application/javascript" src="../common.js"></script>
+ <script type="application/javascript" src="../browser.js"></script>
+ <script type="application/javascript" src="../events.js"></script>
+ <script type="application/javascript" src="../role.js"></script>
+ <script type="application/javascript" src="../states.js"></script>
+ <script type="application/javascript" src="../pivot.js"></script>
+ <script type="application/javascript" src="../layout.js"></script>
+
+ <script type="application/javascript">
+ Components.utils.import("resource://gre/modules/accessibility/TraversalRules.jsm");
+ var gBrowserWnd = null;
+ var gQueue = null;
+
+ function doTest()
+ {
+ var doc = currentTabDocument();
+ var docAcc = getAccessible(doc, [nsIAccessibleDocument]);
+
+ gQueue = new eventQueue();
+
+ gQueue.onFinish = function onFinish()
+ {
+ closeBrowserWindow();
+ }
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Heading, null,
+ ['heading-1', 'heading-2', 'heading-3', 'heading-5']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Entry, null,
+ ['input-1-1', 'label-1-2', 'input-1-3',
+ 'input-1-4', 'input-1-5']);
+
+ // move back an element to hit all the form elements, because the VC is
+ // currently at the first input element
+ gQueue.push(new setVCPosInvoker(docAcc, "movePrevious",
+ TraversalRules.Heading, "heading-1"));
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.FormElement, null,
+ ['input-1-1', 'label-1-2', 'button-1-1',
+ 'radio-1-1', 'radio-1-2', 'input-1-3',
+ 'input-1-4', 'button-1-2', 'checkbox-1-1',
+ 'select-1-1', 'select-1-2', 'checkbox-1-2',
+ 'select-1-3', 'input-1-5', 'button-1-3',
+ 'button-2-1', 'button-2-2', 'button-2-3',
+ 'button-2-4']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Button, null,
+ ['button-1-1', 'button-1-2', 'button-1-3',
+ 'button-2-1', 'button-2-2', 'button-2-3',
+ 'button-2-4']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.RadioButton, null,
+ ['radio-1-1', 'radio-1-2']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Checkbox, null,
+ ['checkbox-1-1', 'checkbox-1-2']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Combobox, null,
+ ['select-1-1', 'select-1-2', 'select-1-3']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.List, null,
+ ['list-1', 'list-2', 'list-3']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.ListItem, null,
+ ['listitem-1-1', 'listitem-2-1', 'listitem-2-2',
+ 'listitem-3-1', 'listitem-3-2', 'listitem-3-3',
+ 'listitem-2-3']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Graphic, null,
+ ['image-2', 'image-3']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Link, null,
+ ['link-1', 'link-2', 'link-3']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Anchor, null,
+ ['anchor-1', 'anchor-2']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Separator, null,
+ ['separator-1', 'separator-2']);
+
+ queueTraversalSequence(gQueue, docAcc, TraversalRules.Table, null,
+ ['table-1', 'table-2']);
+
+ gQueue.invoke();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(function () {
+ /* We open a new browser because we need to test with a top-level content
+ document. */
+ openBrowserWindow(
+ doTest,
+ getRootDirectory(window.location.href) + "doc_traversal.html");
+ });
+ </script>
+</head>
+<body id="body">
+
+ <a target="_blank"
+ title="Add tests for AccessFu TraversalRules"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=933808">Mozilla Bug 933808</a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+</body>
+</html>
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -2,20 +2,16 @@
# 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/.
USE_RCS_MK := 1
include $(topsrcdir)/config/makefiles/rcs.mk
PREF_JS_EXPORTS = $(srcdir)/b2g.js
-ifdef ENABLE_MARIONETTE
-DEFINES += -DENABLE_MARIONETTE=1
-endif
-
ifndef LIBXUL_SDK
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
LIBS += \
-lui \
-lEGL \
-lhardware_legacy \
-lhardware \
@@ -34,17 +30,16 @@ OS_LDFLAGS += -Wl,--export-dynamic
LOCAL_INCLUDES += -I$(topsrcdir)/widget/gonk/libdisplay
endif
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
LOCAL_INCLUDES += -I$(DEPTH)/build
-DEFINES += -DXPCOM_GLUE
STL_FLAGS=
LIBS += $(JEMALLOC_LIBS)
LIBS += \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)
@@ -78,22 +73,16 @@ INSTALL_TARGETS += UA_UPDATE
# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
NSDISTMODE = copy
include $(topsrcdir)/config/rules.mk
APP_ICON = b2g
-DEFINES += \
- -DAPP_NAME=$(MOZ_APP_NAME) \
- -DAPP_VERSION=$(MOZ_APP_VERSION) \
- -DMOZ_UPDATER=$(MOZ_UPDATER) \
- $(NULL)
-
source_repo ?= $(call getSourceRepo,$(srcdir)/..)
ifneq (,$(filter http%,$(source_repo)))
DEFINES += -DMOZ_SOURCE_REPO="$(source_repo)"
endif
ifeq ($(OS_ARCH),WINNT)
REDIT_PATH = $(LIBXUL_DIST)/bin
endif
--- a/b2g/app/moz.build
+++ b/b2g/app/moz.build
@@ -7,8 +7,16 @@
if not CONFIG['LIBXUL_SDK']:
if CONFIG['GAIADIR']:
PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin"
else:
PROGRAM = CONFIG['MOZ_APP_NAME']
SOURCES += [
'nsBrowserApp.cpp',
]
+
+if CONFIG['ENABLE_MARIONETTE']:
+ DEFINES['ENABLE_MARIONETTE'] = 1
+
+DEFINES['XPCOM_GLUE'] = True
+
+for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER'):
+ DEFINES[var] = CONFIG[var]
deleted file mode 100644
--- a/b2g/chrome/Makefile.in
+++ /dev/null
@@ -1,8 +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/.
-
-DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) \
- -DPACKAGE=browser \
- -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
- $(NULL)
--- a/b2g/chrome/moz.build
+++ b/b2g/chrome/moz.build
@@ -1,6 +1,9 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
+DEFINES['AB_CD'] = CONFIG['MOZ_UI_LOCALE']
+DEFINES['PACKAGE'] = 'browser'
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
{
- "revision": "74ed51578aa6d69a994d88be8d97f3b136288cd7",
+ "revision": "3fe38577e17209728a54b14624143dbf99ade2df",
"repo_path": "/integration/gaia-central"
}
--- a/b2g/gaia/Makefile.in
+++ b/b2g/gaia/Makefile.in
@@ -1,26 +1,14 @@
# 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/.
GAIA_PATH := gaia/profile
-ifeq ($(OS_ARCH),WINNT)
-DEFINES += \
- -DB2G_NAME=L\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
- -DGAIA_PATH=L\"$(subst /,\\\\,$(GAIA_PATH))\" \
- $(NULL)
-else # Non-windows machines use the same wrapper program
-DEFINES += \
- -DB2G_NAME=\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
- -DGAIA_PATH=\"$(GAIA_PATH)\" \
- $(NULL)
-endif
-
ifdef .PYMAKE
# For use of GNU make in pymake builds.
GAIA_MAKE=$(GMAKE)
else
GAIA_MAKE=$(MAKE)
endif
# This is needed to avoid making run-b2g depend on mozglue
--- a/b2g/gaia/moz.build
+++ b/b2g/gaia/moz.build
@@ -5,12 +5,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
PROGRAM = CONFIG['MOZ_APP_NAME']
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'run-b2g.cpp',
]
+ DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
+ DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
else:
SOURCES += [
'run-b2g.c',
]
+ DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
+ DEFINES['GAIA_PATH'] = '"gaia/profile"'
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -1,54 +1,43 @@
# 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/.
dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
-ifdef ENABLE_MARIONETTE
-DEFINES += -DENABLE_MARIONETTE=1
-endif
-
PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
$(NULL)
# hardcode en-US for the moment
AB_CD = en-US
DEFINES += \
-DAB_CD=$(AB_CD) \
- -DAPP_VERSION="$(MOZ_APP_VERSION)" \
-DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" \
-DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" \
-DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \
-DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \
-DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \
$(NULL)
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DMOZILLA_OFFICIAL
-endif
-
ifdef LIBXUL_SDK #{
PREF_JS_EXPORTS += $(srcdir)/profile/channel-prefs.js
-DEFINES += -DLIBXUL_SDK
endif #} LIBXUL_SDK
# Build a binary bootstrapping with XRE_main
LOCAL_INCLUDES += \
-I$(topsrcdir)/toolkit/xre \
-I$(topsrcdir)/xpcom/base \
-I$(topsrcdir)/xpcom/build \
-I$(DEPTH)/build \
$(NULL)
-DEFINES += -DXPCOM_GLUE
STL_FLAGS=
LIBS += \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)
ifdef MOZ_LINKER
LIBS += $(MOZ_ZLIB_LIBS)
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -6,8 +6,19 @@
DIRS += ['profile/extensions']
PROGRAM = CONFIG['MOZ_APP_NAME']
SOURCES += [
'nsBrowserApp.cpp',
]
+
+if CONFIG['ENABLE_MARIONETTE']:
+ DEFINES['ENABLE_MARIONETTE'] = 1
+
+DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+
+for var in ('MOZILLA_OFFICIAL', 'LIBXUL_SDK'):
+ if CONFIG[var]:
+ DEFINES[var] = True
+
+DEFINES['XPCOM_GLUE'] = True
deleted file mode 100644
--- a/browser/base/Makefile.in
+++ /dev/null
@@ -1,34 +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 $(topsrcdir)/config/config.mk
-
-abs_srcdir = $(abspath $(srcdir))
-
-include $(topsrcdir)/config/rules.mk
-
-PRE_RELEASE_SUFFIX := ""
-
-DEFINES += \
- -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
- -DAPP_LICENSE_BLOCK=$(abs_srcdir)/content/overrides/app-license.html \
- -DPRE_RELEASE_SUFFIX="$(PRE_RELEASE_SUFFIX)" \
- $(NULL)
-
-ifneq (,$(filter windows gtk2 gtk3 cocoa, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DHAVE_SHELL_SERVICE=1
-endif
-
-ifneq (,$(filter windows cocoa gtk2 gtk3, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1
-endif
-
-ifneq (,$(filter windows cocoa, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
-endif
-
-ifneq (,$(filter windows gtk2 gtk3, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
-endif
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -22,29 +22,29 @@
#include browser-doctype.inc
<window id="main-window"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="gBrowserInit.onLoad()" onunload="gBrowserInit.onUnload()" onclose="return WindowIsClosing();"
- title="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
- title_normal="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
+ title="&mainWindow.title;"
+ title_normal="&mainWindow.title;"
#ifdef XP_MACOSX
- title_privatebrowsing="&mainWindow.title;@PRE_RELEASE_SUFFIX@&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
- titledefault="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
+ title_privatebrowsing="&mainWindow.title;&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
+ titledefault="&mainWindow.title;"
titlemodifier=""
titlemodifier_normal=""
titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
#else
- title_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;"
- titlemodifier="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
- titlemodifier_normal="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
- titlemodifier_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;"
+ title_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
+ titlemodifier="&mainWindow.titlemodifier;"
+ titlemodifier_normal="&mainWindow.titlemodifier;"
+ titlemodifier_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
#endif
#ifdef CAN_DRAW_IN_TITLEBAR
#ifdef XP_WIN
chromemargin="0,2,2,2"
#else
chromemargin="0,-1,-1,-1"
#endif
tabsintitlebar="true"
--- a/browser/base/content/chatWindow.xul
+++ b/browser/base/content/chatWindow.xul
@@ -13,17 +13,17 @@
<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
#include browser-doctype.inc
<window id="chat-window"
windowtype="Social:Chat"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
+ title="&mainWindow.title;"
onload="gChatWindow.onLoad();"
onunload="gChatWindow.onUnload();"
macanimationtype="document"
fullscreenbutton="true"
# width and height are also used in socialchat.xml: chatbar dragend handler
width="400px"
height="420px"
persist="screenX screenY width height sizemode">
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4083,59 +4083,47 @@
.add(Date.now() - aTab._animStartTime);
aTab._animStartTime = 0;
// Handle tab animation smoothness telemetry/logging of frame intervals and paint times
if (!("_recordingHandle" in aTab)) {
return;
}
- let paints = {};
let intervals = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
- .stopFrameTimeRecording(aTab._recordingHandle, paints);
+ .stopFrameTimeRecording(aTab._recordingHandle);
delete aTab._recordingHandle;
- paints = paints.value; // The result array itself.
let frameCount = intervals.length;
if (this._tabAnimationLoggingEnabled) {
- let msg = "Tab " + (aTab.closing ? "close" : "open") + " (Frame-interval / paint-processing):\n";
+ let msg = "Tab " + (aTab.closing ? "close" : "open") + " (Frame-interval):\n";
for (let i = 0; i < frameCount; i++) {
- msg += Math.round(intervals[i]) + " / " + Math.round(paints[i]) + "\n";
+ msg += Math.round(intervals[i]) + "\n";
}
Services.console.logStringMessage(msg);
}
// For telemetry, the first frame interval is not useful since it may represent an interval
// to a relatively old frame (prior to recording start). So we'll ignore it for the average.
- // But if we recorded only 1 frame (very rare), then the first paint duration is a good
- // representative of the first frame interval for our cause (indicates very bad animation).
- // First paint duration is always useful for us.
- if (frameCount > 0) {
+ if (frameCount > 1) {
let averageInterval = 0;
- let averagePaint = paints[0];
for (let i = 1; i < frameCount; i++) {
averageInterval += intervals[i];
- averagePaint += paints[i];
};
- averagePaint /= frameCount;
- averageInterval = (frameCount == 1)
- ? averagePaint
- : averageInterval / (frameCount - 1);
+ averageInterval = averageInterval / (frameCount - 1);
Services.telemetry.getHistogramById("FX_TAB_ANIM_ANY_FRAME_INTERVAL_MS").add(averageInterval);
- Services.telemetry.getHistogramById("FX_TAB_ANIM_ANY_FRAME_PAINT_MS").add(averagePaint);
if (aTab._recordingTabOpenPlain) {
delete aTab._recordingTabOpenPlain;
// While we do have a telemetry probe NEWTAB_PAGE_ENABLED to monitor newtab preview, it'll be
// easier to overview the data without slicing by it. Hence the additional histograms with _PREVIEW.
let preview = this._browserNewtabpageEnabled ? "_PREVIEW" : "";
Services.telemetry.getHistogramById("FX_TAB_ANIM_OPEN" + preview + "_FRAME_INTERVAL_MS").add(averageInterval);
- Services.telemetry.getHistogramById("FX_TAB_ANIM_OPEN" + preview + "_FRAME_PAINT_MS").add(averagePaint);
}
}
]]>
</body>
</method>
<!-- Deprecated stuff, implemented for backwards compatibility. -->
<property name="mTabstripClosebutton" readonly="true"
--- a/browser/base/moz.build
+++ b/browser/base/moz.build
@@ -16,8 +16,21 @@ MOCHITEST_CHROME_MANIFESTS += [
'content/test/chrome/chrome.ini',
]
BROWSER_CHROME_MANIFESTS += [
'content/test/general/browser.ini',
'content/test/newtab/browser.ini',
'content/test/social/browser.ini',
]
+
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
+ DEFINES['HAVE_SHELL_SERVICE'] = 1
+ DEFINES['CONTEXT_COPY_IMAGE_CONTENTS'] = 1
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
+ DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
+ DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
--- a/browser/branding/aurora/locales/Makefile.in
+++ b/browser/branding/aurora/locales/Makefile.in
@@ -1,5 +1,5 @@
# 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/.
-DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
+DEFINES += -DAB_CD=$(AB_CD)
--- a/browser/branding/aurora/locales/moz.build
+++ b/browser/branding/aurora/locales/moz.build
@@ -1,6 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
+DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
--- a/browser/branding/nightly/locales/Makefile.in
+++ b/browser/branding/nightly/locales/Makefile.in
@@ -1,5 +1,5 @@
# 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/.
-DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
+DEFINES += -DAB_CD=$(AB_CD)
--- a/browser/branding/nightly/locales/moz.build
+++ b/browser/branding/nightly/locales/moz.build
@@ -1,6 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
+DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
--- a/browser/branding/unofficial/locales/Makefile.in
+++ b/browser/branding/unofficial/locales/Makefile.in
@@ -1,5 +1,5 @@
# 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/.
-DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
+DEFINES += -DAB_CD=$(AB_CD)
--- a/browser/branding/unofficial/locales/moz.build
+++ b/browser/branding/unofficial/locales/moz.build
@@ -1,6 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
+DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
--- a/browser/components/feeds/src/Makefile.in
+++ b/browser/components/feeds/src/Makefile.in
@@ -1,11 +1,5 @@
# 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/.
-DEFINES += \
- -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
- -DMOZ_MACBUNDLE_NAME=$(MOZ_MACBUNDLE_NAME) \
- $(NULL)
-
-
LOCAL_INCLUDES = -I$(srcdir)/../../build
--- a/browser/components/feeds/src/moz.build
+++ b/browser/components/feeds/src/moz.build
@@ -14,8 +14,11 @@ EXTRA_COMPONENTS += [
'WebContentConverter.js',
]
EXTRA_PP_COMPONENTS += [
'FeedWriter.js',
]
FINAL_LIBRARY = 'browsercomps'
+
+for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
+ DEFINES[var] = CONFIG[var]
deleted file mode 100644
--- a/browser/components/migration/src/Makefile.in
+++ /dev/null
@@ -1,12 +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/.
-
-ifeq ($(OS_ARCH),WINNT)
-
-DEFINES += -DHAS_IE_MIGRATOR -DHAS_SAFARI_MIGRATOR
-endif
-
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-DEFINES += -DHAS_SAFARI_MIGRATOR
-endif
--- a/browser/components/migration/src/moz.build
+++ b/browser/components/migration/src/moz.build
@@ -13,29 +13,32 @@ EXTRA_COMPONENTS += [
'FirefoxProfileMigrator.js',
'ProfileMigrator.js',
]
if CONFIG['OS_ARCH'] == 'WINNT':
EXTRA_COMPONENTS += [
'IEProfileMigrator.js',
]
+ DEFINES['HAS_IE_MIGRATOR'] = True
EXTRA_PP_COMPONENTS += [
'BrowserProfileMigrators.manifest',
'ChromeProfileMigrator.js',
]
if CONFIG['OS_ARCH'] == 'WINNT':
EXTRA_PP_COMPONENTS += [
'SafariProfileMigrator.js',
]
+ DEFINES['HAS_SAFARI_MIGRATOR'] = True
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXTRA_PP_COMPONENTS += [
'SafariProfileMigrator.js',
]
+ DEFINES['HAS_SAFARI_MIGRATOR'] = True
EXTRA_PP_JS_MODULES += [
'MigrationUtils.jsm',
]
FINAL_LIBRARY = 'browsercomps'
deleted file mode 100644
--- a/browser/components/preferences/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- Mode: Java; tab-width: 4; 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 $(topsrcdir)/config/rules.mk
-
-DEFINES += \
- -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
- -DMOZ_MACBUNDLE_NAME=$(MOZ_MACBUNDLE_NAME) \
- $(NULL)
-
-ifneq (,$(filter windows gtk2 gtk3 cocoa, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DHAVE_SHELL_SERVICE=1
-endif
deleted file mode 100644
--- a/browser/components/preferences/in-content/Makefile.in
+++ /dev/null
@@ -1,14 +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 $(topsrcdir)/config/rules.mk
-
-DEFINES += \
- -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
- -DMOZ_MACBUNDLE_NAME=$(MOZ_MACBUNDLE_NAME) \
- $(NULL)
-
-ifneq (,$(filter windows gtk2 cocoa, $(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DHAVE_SHELL_SERVICE=1
-endif
--- a/browser/components/preferences/in-content/moz.build
+++ b/browser/components/preferences/in-content/moz.build
@@ -1,6 +1,11 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
+for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
+ DEFINES[var] = CONFIG[var]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'cocoa'):
+ DEFINES['HAVE_SHELL_SERVICE'] = 1
--- a/browser/components/preferences/moz.build
+++ b/browser/components/preferences/moz.build
@@ -5,8 +5,14 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
PARALLEL_DIRS += ['in-content']
BROWSER_CHROME_MANIFESTS += [
'in-content/tests/browser.ini',
'tests/browser.ini',
]
+
+for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
+ DEFINES[var] = CONFIG[var]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
+ DEFINES['HAVE_SHELL_SERVICE'] = 1
--- a/browser/components/shell/src/Makefile.in
+++ b/browser/components/shell/src/Makefile.in
@@ -1,14 +1,11 @@
#
# 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 $(topsrcdir)/config/rules.mk
-DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\" \
- -DMOZ_APP_VERSION=\"$(MOZ_APP_VERSION)\"
-
CXXFLAGS += $(TK_CFLAGS)
clobber::
rm -f $(DIST)/lib/$(LIBRARY_NAME).lib
--- a/browser/components/shell/src/moz.build
+++ b/browser/components/shell/src/moz.build
@@ -19,8 +19,11 @@ elif CONFIG['MOZ_WIDGET_GTK']:
if SOURCES:
FINAL_LIBRARY = 'browsercomps'
EXTRA_COMPONENTS += [
'nsSetDefaultBrowser.js',
'nsSetDefaultBrowser.manifest',
]
+
+for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION'):
+ DEFINES[var] = '"%s"' % CONFIG[var]
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -13,11 +13,10 @@ MOCHITEST_BROWSER_FILES += \
$(NULL)
endif
# Bug 895426:
# Disable browser_dbg_break-on-dom-event.js due to frequent failures
ifneq (Darwin,$(OS_ARCH))
MOCHITEST_BROWSER_FILES += \
browser_dbg_break-on-dom-event.js \
- browser_dbg_event-listeners.js \
$(NULL)
endif
--- a/browser/devtools/debugger/test/browser.ini
+++ b/browser/devtools/debugger/test/browser.ini
@@ -92,16 +92,17 @@ skip-if = true
[browser_dbg_cmd-blackbox.js]
[browser_dbg_cmd-break.js]
[browser_dbg_cmd-dbg.js]
[browser_dbg_conditional-breakpoints-01.js]
[browser_dbg_conditional-breakpoints-02.js]
[browser_dbg_debugger-statement.js]
[browser_dbg_editor-contextmenu.js]
[browser_dbg_editor-mode.js]
+[browser_dbg_event-listeners.js]
[browser_dbg_function-display-name.js]
[browser_dbg_globalactor.js]
[browser_dbg_host-layout.js]
[browser_dbg_iframes.js]
[browser_dbg_instruments-pane-collapse.js]
[browser_dbg_listaddons.js]
[browser_dbg_listtabs-01.js]
[browser_dbg_listtabs-02.js]
--- a/browser/installer/windows/Makefile.in
+++ b/browser/installer/windows/Makefile.in
@@ -3,18 +3,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
CONFIG_DIR = instgen
SFX_MODULE = $(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
APP_VERSION := $(shell cat $(srcdir)/../../config/version.txt)
DEFINES += -DAPP_VERSION=$(APP_VERSION)
-PRE_RELEASE_SUFFIX := ""
-DEFINES += -DPRE_RELEASE_SUFFIX="$(PRE_RELEASE_SUFFIX)"
INSTALLER_FILES = \
app.tag \
nsis/installer.nsi \
nsis/uninstaller.nsi \
nsis/stub.nsi \
nsis/shared.nsh \
stub.tag \
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -27,18 +27,17 @@
!define AB_CD "@AB_CD@"
!define FileMainEXE "@MOZ_APP_NAME@.exe"
!define WindowClass "FirefoxMessageWindow"
!define DDEApplication "Firefox"
!define AppRegName "Firefox"
!define BrandShortName "@MOZ_APP_DISPLAYNAME@"
-!define PreReleaseSuffix "@PRE_RELEASE_SUFFIX@"
-!define BrandFullName "${BrandFullNameInternal}${PreReleaseSuffix}"
+!define BrandFullName "${BrandFullNameInternal}"
!define NO_UNINSTALL_SURVEY
!define CERTIFICATE_NAME "Mozilla Corporation"
!define CERTIFICATE_ISSUER "DigiCert Assured ID Code Signing CA-1"
# LSP_CATEGORIES is the permitted LSP categories for the application. Each LSP
# category value is ANDed together to set multiple permitted categories.
@@ -55,25 +54,16 @@
# Due to official and beta using the same branding this is needed to
# differentiante between the url used by the stub for downloading.
!if "@MOZ_UPDATE_CHANNEL@" == "beta"
!define BETA_UPDATE_CHANNEL
!endif
!define BaseURLStubPing "http://download-stats.mozilla.org/stub"
-# NO_INSTDIR_FROM_REG is defined for pre-releases which have a PreReleaseSuffix
-# (e.g. Alpha X, Beta X, etc.) to prevent finding a non-default installation
-# directory in the registry and using that as the default. This prevents
-# Beta releases built with official branding from finding an existing install
-# of an official release and defaulting to its installation directory.
-!if "@PRE_RELEASE_SUFFIX@" != ""
-!define NO_INSTDIR_FROM_REG
-!endif
-
# ARCH is used when it is necessary to differentiate the x64 registry keys from
# the x86 registry keys (e.g. the uninstall registry key).
#ifdef HAVE_64BIT_OS
!define HAVE_64BIT_OS
!define ARCH "x64"
!define MinSupportedVer "Microsoft Windows Vista x64"
#else
!define ARCH "x86"
--- a/browser/metro/Makefile.in
+++ b/browser/metro/Makefile.in
@@ -2,22 +2,18 @@
# 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 $(topsrcdir)/config/rules.mk
#########################################
# application.ini
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DMOZILLA_OFFICIAL
-endif
-
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
-DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
+DEFINES += -DGRE_BUILDID=$(GRE_BUILDID)
# 'application.ini' breaks firefox build config. So we use something different.
metroapp.ini: metroapp.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt
$(RM) "metroapp.ini"
$(call py_action,preprocessor,$(DEFINES) $< -o $@)
libs:: metroapp.ini
$(INSTALL) metroapp.ini $(FINAL_TARGET)
deleted file mode 100644
--- a/browser/metro/base/Makefile.in
+++ /dev/null
@@ -1,10 +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 $(topsrcdir)/config/config.mk
-
-DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) \
- -DPACKAGE=browser \
- -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
- $(NULL)
--- a/browser/metro/base/moz.build
+++ b/browser/metro/base/moz.build
@@ -3,8 +3,12 @@
# 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/.
METRO_CHROME_MANIFESTS += ['tests/mochiperf/metro.ini', 'tests/mochitest/metro.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
DIST_SUBDIR = 'metro'
+
+DEFINES['AB_CD'] = CONFIG['MOZ_UI_LOCALE']
+DEFINES['PACKAGE'] = 'browser'
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
--- a/browser/metro/moz.build
+++ b/browser/metro/moz.build
@@ -12,8 +12,13 @@ DIRS += [
'profile',
'locales',
]
if CONFIG['OS_ARCH'] == 'WINNT':
DIRS += ['shell']
DIST_SUBDIR = 'metro'
+
+if CONFIG['MOZILLA_OFFICIAL']:
+ DEFINES['MOZILLA_OFFICIAL'] = True
+
+DEFINES['GRE_MILESTONE'] = CONFIG['GRE_MILESTONE']
--- a/browser/metro/shell/commandexecutehandler/Makefile.in
+++ b/browser/metro/shell/commandexecutehandler/Makefile.in
@@ -16,10 +16,8 @@ OS_LIBS = \
kernel32.lib \
user32.lib \
ole32.lib \
shlwapi.lib \
propsys.lib \
advapi32.lib \
wininet.lib \
$(NULL)
-
-DEFINES += -DUNICODE -D_UNICODE -DNS_NO_XPCOM
--- a/browser/metro/shell/commandexecutehandler/moz.build
+++ b/browser/metro/shell/commandexecutehandler/moz.build
@@ -8,8 +8,11 @@ PROGRAM = 'CommandExecuteHandler'
SOURCES += [
'CEHHelper.cpp',
'CommandExecuteHandler.cpp',
]
# We want this exe in dist/bin
DIST_SUBDIR = ''
+
+for var in ('UNICODE', '_UNICODE', 'NS_NO_XPCOM'):
+ DEFINES[var] = True
--- a/browser/metro/shell/linktool/Makefile.in
+++ b/browser/metro/shell/linktool/Makefile.in
@@ -9,10 +9,8 @@ include $(topsrcdir)/config/config.mk
OS_LIBS = \
kernel32.lib \
user32.lib \
ole32.lib \
shlwapi.lib \
shell32.lib \
propsys.lib \
$(NULL)
-
-DEFINES += -DUNICODE -D_UNICODE
--- a/browser/metro/shell/linktool/moz.build
+++ b/browser/metro/shell/linktool/moz.build
@@ -6,8 +6,11 @@
PROGRAM = 'linktool'
SOURCES += [
'linktool.cpp',
]
DIST_SUBDIR = 'metro/install'
+
+for var in ('UNICODE', '_UNICODE'):
+ DEFINES[var] = True
--- a/browser/metro/shell/testing/Makefile.in
+++ b/browser/metro/shell/testing/Makefile.in
@@ -16,10 +16,8 @@ include $(topsrcdir)/config/config.mk
OS_LIBS = \
kernel32.lib \
user32.lib \
ole32.lib \
shlwapi.lib \
propsys.lib \
advapi32.lib \
$(NULL)
-
-DEFINES += -DUNICODE -D_UNICODE
--- a/browser/metro/shell/testing/moz.build
+++ b/browser/metro/shell/testing/moz.build
@@ -7,8 +7,11 @@
PROGRAM = 'metrotestharness'
SOURCES += [
'metrotestharness.cpp',
]
# We want this exe in dist/bin
DIST_SUBDIR = ''
+
+for var in ('UNICODE', '_UNICODE'):
+ DEFINES[var] = True
deleted file mode 100644
--- a/browser/modules/Makefile.in
+++ /dev/null
@@ -1,9 +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 $(topsrcdir)/config/config.mk
-
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DMOZILLA_OFFICIAL=1
-endif
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -29,8 +29,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
'WindowsPreviewPerTab.jsm',
]
EXTRA_PP_JS_MODULES += [
'AboutHome.jsm',
'RecentWindow.jsm',
]
+if CONFIG['MOZILLA_OFFICIAL']:
+ DEFINES['MOZILLA_OFFICIAL'] = 1
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -19,59 +19,30 @@ ifdef LIBXUL_SDK
APP_INI_DEPS = $(LIBXUL_DIST)/bin/platform.ini
else
APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
endif
APP_BUILDID := $(shell cat $(DEPTH)/config/buildid)
APP_INI_DEPS += $(DEPTH)/config/buildid
-DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
+DEFINES += -DAPP_BUILDID=$(APP_BUILDID)
-DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
MOZ_SOURCE_STAMP := $(firstword $(shell cd $(topsrcdir)/$(MOZ_BUILD_APP)/.. && hg parent --template="{node|short}\n" 2>/dev/null))
ifdef MOZ_SOURCE_STAMP
DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
endif
source_repo ?= $(call getSourceRepo,$(topsrcdir)/$(MOZ_BUILD_APP)/..)
ifneq (,$(source_repo))
DEFINES += -DMOZ_SOURCE_REPO="$(source_repo)"
endif
-DEFINES += \
- -DMOZ_APP_BASENAME="$(MOZ_APP_BASENAME)" \
- -DMOZ_APP_VENDOR="$(MOZ_APP_VENDOR)" \
- -DMOZ_APP_ID="$(MOZ_APP_ID)" \
- -DMAR_CHANNEL_ID="$(MAR_CHANNEL_ID)" \
- -DACCEPTED_MAR_CHANNEL_IDS="$(ACCEPTED_MAR_CHANNEL_IDS)" \
- $(NULL)
-
-ifeq ($(MOZ_BUILD_APP),browser)
-DEFINES += -DMOZ_BUILD_APP_IS_BROWSER
-endif
-
-ifdef MOZ_APP_PROFILE
-DEFINES += -DMOZ_APP_PROFILE="$(MOZ_APP_PROFILE)"
-endif
-
-ifdef MOZ_CRASHREPORTER
-DEFINES += -DMOZ_CRASHREPORTER
-endif
-
-ifdef MOZ_PROFILE_MIGRATOR
-DEFINES += -DMOZ_PROFILE_MIGRATOR
-endif
-
-ifdef MOZ_EXTENSION_MANAGER
-DEFINES += -DMOZ_EXTENSION_MANAGER
-endif
-
endif
# Put a useful .gdbinit in the bin directory, to be picked up automatically
# by GDB when we debug executables there.
# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
GDBINIT_FILES := $(topsrcdir)/.gdbinit
GDBINIT_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += GDBINIT
@@ -118,18 +89,16 @@ leaktest.py: leaktest.py.in
$(call py_action,preprocessor,$^ -o $@)
chmod +x $@
GARBAGE += leaktest.py
ifdef MOZ_APP_BASENAME
$(FINAL_TARGET)/application.ini: $(APP_INI_DEPS)
ifdef MOZ_APP_STATIC_INI
-DEFINES += -DMOZ_APP_STATIC_INI
-
application.ini.h: appini_header.py $(FINAL_TARGET)/application.ini
$(PYTHON) $^ > $@
export:: application.ini.h
GARBAGE += application.ini.h
endif
endif
libs:: $(_LEAKTEST_FILES)
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -565,24 +565,17 @@ class ShutdownLeaks(object):
# don't track a test if no windows or docShells leaked
if self.currentTest and (self.currentTest["windows"] or self.currentTest["docShells"]):
self.tests.append(self.currentTest)
self.currentTest = None
elif line.startswith("INFO TEST-START | Shutdown"):
self.seenShutdown = True
def process(self):
- leakingTests = self._parseLeakingTests()
-
- if leakingTests:
- totalWindows = sum(len(test["leakedWindows"]) for test in leakingTests)
- totalDocShells = sum(len(test["leakedDocShells"]) for test in leakingTests)
- self.logger("TEST-UNEXPECTED-FAIL | ShutdownLeaks | leaked %d DOMWindow(s) and %d DocShell(s) until shutdown", totalWindows, totalDocShells)
-
- for test in leakingTests:
+ for test in self._parseLeakingTests():
for url, count in self._zipLeakedWindows(test["leakedWindows"]):
self.logger("TEST-UNEXPECTED-FAIL | %s | leaked %d window(s) until shutdown [url = %s]", test["fileName"], count, url)
if test["leakedDocShells"]:
self.logger("TEST-UNEXPECTED-FAIL | %s | leaked %d docShell(s) until shutdown", test["fileName"], len(test["leakedDocShells"]))
def _logWindow(self, line):
created = line[:2] == "++"
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -70,20 +70,16 @@ GARBAGE += \
JAVAFILES += \
$(java-harness) \
$(java-tests) \
$(robocop-deps) \
$(testconstants-dep) \
$(NULL)
-DEFINES += \
- -DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \
- $(NULL)
-
include $(topsrcdir)/config/rules.mk
tools:: $(ANDROID_APK_NAME).apk
GENERATED_DIRS += $(dir-tests)
# The test APK needs to know the contents of the target APK while not
# being linked against them. This is a best effort to avoid getting
--- a/build/mobile/robocop/moz.build
+++ b/build/mobile/robocop/moz.build
@@ -2,8 +2,10 @@
# 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/.
ANDROID_RESFILES = [
'res/values/strings.xml',
]
+
+DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
--- a/build/moz.build
+++ b/build/moz.build
@@ -17,8 +17,24 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
TEST_DIRS += [
'mobile/sutagent/android',
'mobile/sutagent/android/watcher',
'mobile/sutagent/android/ffxcp',
'mobile/sutagent/android/fencp',
'mobile/robocop',
]
+for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
+ 'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
+ 'ACCEPTED_MAR_CHANNEL_IDS'):
+ DEFINES[var] = CONFIG[var]
+
+if CONFIG['MOZ_BUILD_APP'] == 'browser':
+ DEFINES['MOZ_BUILD_APP_IS_BROWSER'] = True
+
+if CONFIG['MOZ_APP_PROFILE']:
+ DEFINES['MOZ_APP_PROFILE'] = CONFIG['MOZ_APP_PROFILE']
+
+for var in ('MOZ_CRASHREPORTER', 'MOZ_PROFILE_MIGRATOR',
+ 'MOZ_EXTENSION_MANAGER', 'MOZ_APP_STATIC_INI'):
+ if CONFIG[var]:
+ DEFINES[var] = True
+
--- a/build/stlport/Makefile.in
+++ b/build/stlport/Makefile.in
@@ -6,11 +6,10 @@ MODULES = stlport
STL_FLAGS =
# Force to build a static library, instead of a fake library, without
# installing it in dist/lib.
LIBRARY = $(LIB_PREFIX)$(LIBRARY_NAME).$(LIB_SUFFIX)
include $(topsrcdir)/config/rules.mk
-DEFINES += -D_GNU_SOURCE
CXXFLAGS += -fuse-cxa-atexit
INCLUDES += -I$(srcdir)/stlport
--- a/build/stlport/moz.build
+++ b/build/stlport/moz.build
@@ -40,8 +40,10 @@ SOURCES += [
'src/strstream.cpp',
'src/time_facets.cpp',
]
SOURCES += [
'src/c_locale.c',
'src/cxa.c',
]
+
+DEFINES['_GNU_SOURCE'] = True
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -10,18 +10,16 @@ NO_PROFILE_GUIDED_OPTIMIZE = 1
VPATH += $(topsrcdir)/build
OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
WRAP_LDFLAGS=
include $(topsrcdir)/config/rules.mk
-DEFINES += -DELFHACK_BUILD
-
test-array$(DLL_SUFFIX) test-ctors$(DLL_SUFFIX): %$(DLL_SUFFIX): %.$(OBJ_SUFFIX) elfhack
$(MKSHLIB) $(LDFLAGS) $< -nostartfiles
@echo ===
@echo === If you get failures below, please file a bug describing the error
@echo === and your environment \(compiler and linker versions\), and use
@echo === --disable-elf-hack until this is fixed.
@echo ===
# Fail if the library doesn't have $(DT_TYPE) .dynamic info
--- a/build/unix/elfhack/inject/Makefile.in
+++ b/build/unix/elfhack/inject/Makefile.in
@@ -10,11 +10,9 @@ include $(topsrcdir)/config/rules.mk
export:: $(CSRCS:.c=.$(OBJ_SUFFIX))
$(CSRCS): %.c: ../inject.c
cp $< $@
GARBAGE += $(CSRCS)
-DEFINES += -DELFHACK_BUILD
-
CFLAGS := -O2 -fno-stack-protector $(filter -m% -I%,$(CFLAGS))
--- a/build/unix/elfhack/inject/moz.build
+++ b/build/unix/elfhack/inject/moz.build
@@ -11,8 +11,10 @@ if CONFIG['TARGET_CPU'].endswith('86'):
elif CONFIG['TARGET_CPU'].startswith('arm'):
cpu = 'arm'
else:
cpu = CONFIG['TARGET_CPU']
GENERATED_SOURCES += [
"%s.c" % cpu,
]
+
+DEFINES['ELFHACK_BUILD'] = True
--- a/build/unix/elfhack/moz.build
+++ b/build/unix/elfhack/moz.build
@@ -18,8 +18,10 @@ if not CONFIG['CROSS_COMPILE']:
]
HOST_SOURCES += [
'elf.cpp',
'elfhack.cpp',
]
HOST_PROGRAM = 'elfhack'
+
+DEFINES['ELFHACK_BUILD'] = True
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -30,30 +30,30 @@ NS_IMPL_CLASSINFO(nsNullPrincipal, nullp
NS_NULLPRINCIPAL_CID)
NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal,
nsIPrincipal,
nsISerializable)
NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal,
nsIPrincipal,
nsISerializable)
-NS_IMETHODIMP_(nsrefcnt)
+NS_IMETHODIMP_(nsrefcnt)
nsNullPrincipal::AddRef()
{
NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
- nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
+ nsrefcnt count = ++refcount;
NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this));
return count;
}
NS_IMETHODIMP_(nsrefcnt)
nsNullPrincipal::Release()
{
NS_PRECONDITION(0 != refcount, "dup release");
- nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
+ nsrefcnt count = --refcount;
NS_LOG_RELEASE(this, count, "nsNullPrincipal");
if (count == 0) {
delete this;
}
return count;
}
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -46,26 +46,26 @@ static bool URIIsImmutable(nsIURI* aURI)
// Static member variables
const char nsBasePrincipal::sInvalid[] = "Invalid";
NS_IMETHODIMP_(nsrefcnt)
nsBasePrincipal::AddRef()
{
NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
// XXXcaa does this need to be threadsafe? See bug 143559.
- nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
+ nsrefcnt count = ++refcount;
NS_LOG_ADDREF(this, count, "nsBasePrincipal", sizeof(*this));
return count;
}
NS_IMETHODIMP_(nsrefcnt)
nsBasePrincipal::Release()
{
NS_PRECONDITION(0 != refcount, "dup release");
- nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
+ nsrefcnt count = --refcount;
NS_LOG_RELEASE(this, count, "nsBasePrincipal");
if (count == 0) {
delete this;
}
return count;
}
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -24,30 +24,30 @@ NS_IMPL_CLASSINFO(nsSystemPrincipal, nul
NS_SYSTEMPRINCIPAL_CID)
NS_IMPL_QUERY_INTERFACE2_CI(nsSystemPrincipal,
nsIPrincipal,
nsISerializable)
NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPrincipal,
nsIPrincipal,
nsISerializable)
-NS_IMETHODIMP_(nsrefcnt)
+NS_IMETHODIMP_(nsrefcnt)
nsSystemPrincipal::AddRef()
{
NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
- nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount);
+ nsrefcnt count = ++refcount;
NS_LOG_ADDREF(this, count, "nsSystemPrincipal", sizeof(*this));
return count;
}
NS_IMETHODIMP_(nsrefcnt)
nsSystemPrincipal::Release()
{
NS_PRECONDITION(0 != refcount, "dup release");
- nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount);
+ nsrefcnt count = --refcount;
NS_LOG_RELEASE(this, count, "nsSystemPrincipal");
if (count == 0) {
delete this;
}
return count;
}
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -902,17 +902,17 @@ public:
return outer && outer->IsBackground();
}
/**
* Return the inner window used as the script compilation scope for
* this document. If you're not absolutely sure you need this, use
* GetWindow().
*/
- nsPIDOMWindow* GetInnerWindow()
+ nsPIDOMWindow* GetInnerWindow() const
{
return mRemovedFromDocShell ? nullptr : mWindow;
}
/**
* Return the outer window ID.
*/
uint64_t OuterWindowID() const
@@ -1608,17 +1608,20 @@ public:
/**
* Return whether the document and all its ancestors are visible in the sense of
* pageshow / hide.
*/
bool IsVisibleConsideringAncestors() const;
/**
* Return true when this document is active, i.e., the active document
- * in a content viewer.
+ * in a content viewer. Note that this will return true for bfcached
+ * documents, so this does NOT match the "active document" concept in
+ * the WHATWG spec. That would correspond to GetInnerWindow() &&
+ * GetInnerWindow()->IsCurrentInnerWindow().
*/
bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; }
void RegisterFreezableElement(nsIContent* aContent);
bool UnregisterFreezableElement(nsIContent* aContent);
typedef void (* FreezableElementEnumerator)(nsIContent*, void*);
void EnumerateFreezableElements(FreezableElementEnumerator aEnumerator,
void* aData);
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -5,17 +5,17 @@
#include "WebGLContext.h"
#include "WebGL1Context.h"
#include "WebGLObjectModel.h"
#include "WebGLExtensions.h"
#include "WebGLContextUtils.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
-#include "WebGLMemoryReporterWrapper.h"
+#include "WebGLMemoryTracker.h"
#include "WebGLFramebuffer.h"
#include "WebGLVertexArray.h"
#include "WebGLQuery.h"
#include "AccessCheck.h"
#include "nsIConsoleService.h"
#include "nsServiceManagerUtils.h"
#include "nsIClassInfoImpl.h"
@@ -173,17 +173,17 @@ WebGLContext::WebGLContext()
mGLMaxColorAttachments = 1;
mGLMaxDrawBuffers = 1;
mGLMaxTransformFeedbackSeparateAttribs = 0;
// See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
mPixelStorePackAlignment = 4;
mPixelStoreUnpackAlignment = 4;
- WebGLMemoryReporterWrapper::AddWebGLContext(this);
+ WebGLMemoryTracker::AddWebGLContext(this);
mAllowRestore = true;
mContextLossTimerRunning = false;
mDrawSinceContextLossTimerSet = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
mContextStatus = ContextNotLost;
mContextLostErrorSet = false;
mLoseContextOnHeapMinimize = false;
@@ -207,17 +207,17 @@ WebGLContext::WebGLContext()
mDisableFragHighP = false;
mDrawCallsSinceLastFlush = 0;
}
WebGLContext::~WebGLContext()
{
DestroyResourcesAndContext();
- WebGLMemoryReporterWrapper::RemoveWebGLContext(this);
+ WebGLMemoryTracker::RemoveWebGLContext(this);
TerminateContextLossTimer();
mContextRestorer = nullptr;
}
void
WebGLContext::DestroyResourcesAndContext()
{
if (mMemoryPressureObserver) {
@@ -664,18 +664,18 @@ void WebGLContext::LoseOldestWebGLContex
#endif
MOZ_ASSERT(kMaxWebGLContextsPerPrincipal < kMaxWebGLContexts);
// it's important to update the index on a new context before losing old contexts,
// otherwise new unused contexts would all have index 0 and we couldn't distinguish older ones
// when choosing which one to lose first.
UpdateLastUseIndex();
- WebGLMemoryReporterWrapper::ContextsArrayType &contexts
- = WebGLMemoryReporterWrapper::Contexts();
+ WebGLMemoryTracker::ContextsArrayType &contexts
+ = WebGLMemoryTracker::Contexts();
// quick exit path, should cover a majority of cases
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {
return;
}
// note that here by "context" we mean "non-lost context". See the check for
// IsContextLost() below. Indeed, the point of this function is to maybe lose
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -117,17 +117,17 @@ class WebGLContext :
public nsIDOMWebGLRenderingContext,
public nsICanvasRenderingContextInternal,
public nsSupportsWeakReference,
public WebGLRectangleObject,
public nsWrapperCache
{
friend class WebGLContextUserData;
friend class WebGLMemoryPressureObserver;
- friend class WebGLMemoryReporterWrapper;
+ friend class WebGLMemoryTracker;
friend class WebGLExtensionLoseContext;
friend class WebGLExtensionCompressedTextureS3TC;
friend class WebGLExtensionCompressedTextureATC;
friend class WebGLExtensionCompressedTexturePVRTC;
friend class WebGLExtensionDepthTexture;
friend class WebGLExtensionDrawBuffers;
friend class WebGLExtensionVertexArray;
--- a/content/canvas/src/WebGLContextReporter.cpp
+++ b/content/canvas/src/WebGLContextReporter.cpp
@@ -1,15 +1,15 @@
/* -*- 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 "WebGLContext.h"
-#include "WebGLMemoryReporterWrapper.h"
+#include "WebGLMemoryTracker.h"
#include "nsIMemoryReporter.h"
using namespace mozilla;
NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
class WebGLMemoryReporter MOZ_FINAL : public MemoryMultiReporter
{
@@ -32,111 +32,113 @@ WebGLMemoryReporter::CollectReports(nsIM
rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), _kind, \
_units, _amount, NS_LITERAL_CSTRING(_desc), \
aClosure); \
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
REPORT("webgl-texture-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
- WebGLMemoryReporterWrapper::GetTextureMemoryUsed(),
+ WebGLMemoryTracker::GetTextureMemoryUsed(),
"Memory used by WebGL textures.The OpenGL"
" implementation is free to store these textures in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided.");
REPORT("webgl-texture-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
- WebGLMemoryReporterWrapper::GetTextureCount(),
+ WebGLMemoryTracker::GetTextureCount(),
"Number of WebGL textures.");
REPORT("webgl-buffer-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
- WebGLMemoryReporterWrapper::GetBufferMemoryUsed(),
+ WebGLMemoryTracker::GetBufferMemoryUsed(),
"Memory used by WebGL buffers. The OpenGL"
" implementation is free to store these buffers in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided.");
REPORT("explicit/webgl/buffer-cache-memory",
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
- WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed(),
+ WebGLMemoryTracker::GetBufferCacheMemoryUsed(),
"Memory used by WebGL buffer caches. The WebGL"
" implementation caches the contents of element array buffers"
" only.This adds up with the webgl-buffer-memory value, but"
" contrary to it, this one represents bytes on the heap,"
" not managed by OpenGL.");
REPORT("webgl-buffer-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
- WebGLMemoryReporterWrapper::GetBufferCount(),
+ WebGLMemoryTracker::GetBufferCount(),
"Number of WebGL buffers.");
REPORT("webgl-renderbuffer-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
- WebGLMemoryReporterWrapper::GetRenderbufferMemoryUsed(),
+ WebGLMemoryTracker::GetRenderbufferMemoryUsed(),
"Memory used by WebGL renderbuffers. The OpenGL"
" implementation is free to store these renderbuffers in either"
" video memory or main memory. This measurement is only a lower"
" bound, actual memory usage may be higher for example if the"
" storage is strided.");
REPORT("webgl-renderbuffer-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
- WebGLMemoryReporterWrapper::GetRenderbufferCount(),
+ WebGLMemoryTracker::GetRenderbufferCount(),
"Number of WebGL renderbuffers.");
REPORT("explicit/webgl/shader",
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
- WebGLMemoryReporterWrapper::GetShaderSize(),
+ WebGLMemoryTracker::GetShaderSize(),
"Combined size of WebGL shader ASCII sources and translation"
" logs cached on the heap.");
REPORT("webgl-shader-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
- WebGLMemoryReporterWrapper::GetShaderCount(),
+ WebGLMemoryTracker::GetShaderCount(),
"Number of WebGL shaders.");
REPORT("webgl-context-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
- WebGLMemoryReporterWrapper::GetContextCount(),
+ WebGLMemoryTracker::GetContextCount(),
"Number of WebGL contexts.");
#undef REPORT
return NS_OK;
}
-WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::sUniqueInstance = nullptr;
+NS_IMPL_ISUPPORTS1(WebGLMemoryTracker, nsISupports)
-WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::UniqueInstance()
+StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
+
+WebGLMemoryTracker* WebGLMemoryTracker::UniqueInstance()
{
if (!sUniqueInstance) {
- sUniqueInstance = new WebGLMemoryReporterWrapper;
+ sUniqueInstance = new WebGLMemoryTracker;
}
return sUniqueInstance;
}
-WebGLMemoryReporterWrapper::WebGLMemoryReporterWrapper()
+WebGLMemoryTracker::WebGLMemoryTracker()
{
mReporter = new WebGLMemoryReporter;
NS_RegisterMemoryReporter(mReporter);
}
-WebGLMemoryReporterWrapper::~WebGLMemoryReporterWrapper()
+WebGLMemoryTracker::~WebGLMemoryTracker()
{
NS_UnregisterMemoryReporter(mReporter);
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
int64_t
-WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed() {
+WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer *buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
if (buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
@@ -144,17 +146,17 @@ WebGLMemoryReporterWrapper::GetBufferCac
}
}
return result;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
int64_t
-WebGLMemoryReporterWrapper::GetShaderSize() {
+WebGLMemoryTracker::GetShaderSize() {
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLShader *shader = contexts[i]->mShaders.getFirst();
shader;
shader = shader->getNext())
{
result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf);
rename from content/canvas/src/WebGLMemoryReporterWrapper.h
rename to content/canvas/src/WebGLMemoryTracker.h
--- a/content/canvas/src/WebGLMemoryReporterWrapper.h
+++ b/content/canvas/src/WebGLMemoryTracker.h
@@ -1,58 +1,60 @@
/* -*- Mode: C++; tab-width: 4; 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/. */
-#ifndef WEBGLMEMORYREPORTERWRAPPER_H_
-#define WEBGLMEMORYREPORTERWRAPPER_H_
+#ifndef WEBGLMEMORYTRACKER_H_
+#define WEBGLMEMORYTRACKER_H_
#include "WebGLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLShader.h"
#include "WebGLProgram.h"
#include "WebGLUniformLocation.h"
#include "WebGLTexture.h"
#include "WebGLRenderbuffer.h"
+#include "mozilla/StaticPtr.h"
namespace mozilla {
-class WebGLMemoryReporterWrapper
+class WebGLMemoryTracker : public nsISupports
{
- WebGLMemoryReporterWrapper();
- ~WebGLMemoryReporterWrapper();
- static WebGLMemoryReporterWrapper* sUniqueInstance;
+ NS_DECL_ISUPPORTS
+
+ WebGLMemoryTracker();
+ virtual ~WebGLMemoryTracker();
+ static StaticRefPtr<WebGLMemoryTracker> sUniqueInstance;
// here we store plain pointers, not RefPtrs: we don't want the
- // WebGLMemoryReporterWrapper unique instance to keep alive all
+ // WebGLMemoryTracker unique instance to keep alive all
// WebGLContexts ever created.
typedef nsTArray<const WebGLContext*> ContextsArrayType;
ContextsArrayType mContexts;
nsCOMPtr<nsIMemoryReporter> mReporter;
- static WebGLMemoryReporterWrapper* UniqueInstance();
+ static WebGLMemoryTracker* UniqueInstance();
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
friend class WebGLContext;
public:
static void AddWebGLContext(const WebGLContext* c) {
Contexts().AppendElement(c);
}
static void RemoveWebGLContext(const WebGLContext* c) {
ContextsArrayType & contexts = Contexts();
contexts.RemoveElement(c);
if (contexts.IsEmpty()) {
- delete sUniqueInstance;
sUniqueInstance = nullptr;
}
}
static int64_t GetTextureMemoryUsed() {
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -353,8 +353,22 @@ nsDOMEventTargetHelper::WantsUntrusted(b
nsIScriptContext* context = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> doc =
nsContentUtils::GetDocumentFromScriptContext(context);
// We can let listeners on workers to always handle all the events.
*aRetVal = (doc && !nsContentUtils::IsChromeDoc(doc)) || !NS_IsMainThread();
return rv;
}
+
+void
+nsDOMEventTargetHelper::EventListenerAdded(nsIAtom* aType)
+{
+ mozilla::ErrorResult rv;
+ EventListenerWasAdded(Substring(nsDependentAtomString(aType), 2), rv);
+}
+
+void
+nsDOMEventTargetHelper::EventListenerRemoved(nsIAtom* aType)
+{
+ mozilla::ErrorResult rv;
+ EventListenerWasRemoved(Substring(nsDependentAtomString(aType), 2), rv);
+}
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -12,19 +12,24 @@
#include "nsPIDOMWindow.h"
#include "nsIScriptGlobalObject.h"
#include "nsEventListenerManager.h"
#include "nsIScriptContext.h"
#include "MainThreadUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/EventTarget.h"
+class JSCompartment;
+namespace mozilla {
+class ErrorResult;
+}
+
#define NS_DOMEVENTTARGETHELPER_IID \
-{ 0xda0e6d40, 0xc17b, 0x4937, \
- { 0x8e, 0xa2, 0x99, 0xca, 0x1c, 0x81, 0xea, 0xbe } }
+{ 0xa28385c6, 0x9451, 0x4d7e, \
+ { 0xa3, 0xdd, 0xf4, 0xb6, 0x87, 0x2f, 0xa4, 0x76 } }
class nsDOMEventTargetHelper : public mozilla::dom::EventTarget
{
public:
nsDOMEventTargetHelper()
: mParentObject(nullptr)
, mOwnerWindow(nullptr)
, mHasOrHasHadOwnerWindow(false)
@@ -120,16 +125,25 @@ public:
nsPIDOMWindow* GetOwner() const { return mOwnerWindow; }
void BindToOwner(nsIGlobalObject* aOwner);
void BindToOwner(nsPIDOMWindow* aOwner);
void BindToOwner(nsDOMEventTargetHelper* aOther);
virtual void DisconnectFromOwner();
nsIGlobalObject* GetParentObject() const { return mParentObject; }
bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
+
+ virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
+ virtual void EventListenerRemoved(nsIAtom* aType) MOZ_OVERRIDE;
+ virtual void EventListenerWasAdded(const nsAString& aType,
+ mozilla::ErrorResult& aRv,
+ JSCompartment* aCompartment = nullptr) {}
+ virtual void EventListenerWasRemoved(const nsAString& aType,
+ mozilla::ErrorResult& aRv,
+ JSCompartment* aCompartment = nullptr) {}
protected:
nsresult WantsUntrusted(bool* aRetVal);
nsRefPtr<nsEventListenerManager> mListenerManager;
// Dispatch a trusted, non-cancellable and non-bubbling event to |this|.
nsresult DispatchTrustedEvent(const nsAString& aEventName);
// Make |event| trusted and dispatch |aEvent| to |this|.
nsresult DispatchTrustedEvent(nsIDOMEvent* aEvent);
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -569,38 +569,37 @@ nsEventListenerManager::FindEventHandler
EVENT_TYPE_EQUALS(ls, aEventType, aTypeAtom, aTypeString, false)) {
return ls;
}
}
return nullptr;
}
nsListenerStruct*
-nsEventListenerManager::SetEventHandlerInternal(nsIScriptContext *aContext,
- JS::Handle<JSObject*> aScopeObject,
+nsEventListenerManager::SetEventHandlerInternal(JS::Handle<JSObject*> aScopeObject,
nsIAtom* aName,
const nsAString& aTypeString,
const nsEventHandler& aHandler,
bool aPermitUntrustedEvents)
{
- MOZ_ASSERT((aContext && aScopeObject) || aHandler.HasEventHandler(),
+ MOZ_ASSERT(aScopeObject || aHandler.HasEventHandler(),
"Must have one or the other!");
MOZ_ASSERT(aName || !aTypeString.IsEmpty());
uint32_t eventType = nsContentUtils::GetEventId(aName);
nsListenerStruct* ls = FindEventHandler(eventType, aName, aTypeString);
if (!ls) {
// If we didn't find a script listener or no listeners existed
// create and add a new one.
EventListenerFlags flags;
flags.mListenerIsJSListener = true;
nsCOMPtr<nsIJSEventListener> scriptListener;
- NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
+ NS_NewJSEventListener(aScopeObject, mTarget, aName,
aHandler, getter_AddRefs(scriptListener));
if (!aName && aTypeString.EqualsLiteral("error")) {
eventType = NS_LOAD_ERROR;
}
EventListenerHolder holder(scriptListener);
AddEventListenerInternal(holder, eventType, aName, aTypeString, flags,
@@ -609,18 +608,18 @@ nsEventListenerManager::SetEventHandlerI
ls = FindEventHandler(eventType, aName, aTypeString);
} else {
nsIJSEventListener* scriptListener = ls->GetJSListener();
MOZ_ASSERT(scriptListener,
"How can we have an event handler with no nsIJSEventListener?");
bool same = scriptListener->GetHandler() == aHandler;
// Possibly the same listener, but update still the context and scope.
- scriptListener->SetHandler(aHandler, aContext, aScopeObject);
- if (mTarget && !same) {
+ scriptListener->SetHandler(aHandler, aScopeObject);
+ if (mTarget && !same && aName) {
mTarget->EventListenerRemoved(aName);
mTarget->EventListenerAdded(aName);
}
}
// Set flag to indicate possible need for compilation later
ls->mHandlerIsString = !aHandler.HasEventHandler();
if (aPermitUntrustedEvents) {
@@ -646,41 +645,19 @@ nsEventListenerManager::SetEventHandler(
// such scripts based on the source of their code, not just the source
// of the event.
if (aPermitUntrustedEvents &&
aLanguage != nsIProgrammingLanguage::JAVASCRIPT) {
NS_WARNING("Discarding non-JS event listener from untrusted source");
return NS_ERROR_FAILURE;
}
- nsCOMPtr<nsINode> node(do_QueryInterface(mTarget));
-
nsCOMPtr<nsIDocument> doc;
-
- nsCOMPtr<nsIScriptGlobalObject> global;
-
- if (node) {
- // Try to get context from doc
- // XXX sXBL/XBL2 issue -- do we really want the owner here? What
- // if that's the XBL document?
- doc = node->OwnerDoc();
- MOZ_ASSERT(!doc->IsLoadedAsData(), "Should not get in here at all");
-
- // We want to allow compiling an event handler even in an unloaded
- // document, so use GetScopeObject here, not GetScriptHandlingObject.
- global = do_QueryInterface(doc->GetScopeObject());
- } else {
- nsCOMPtr<nsPIDOMWindow> win = GetTargetAsInnerWindow();
- if (win) {
- doc = win->GetDoc();
- global = do_QueryInterface(win);
- } else {
- global = do_QueryInterface(mTarget);
- }
- }
+ nsCOMPtr<nsIScriptGlobalObject> global =
+ GetScriptGlobalAndDocument(getter_AddRefs(doc));
if (!global) {
// This can happen; for example this document might have been
// loaded as data.
return NS_OK;
}
#ifdef DEBUG
@@ -749,23 +726,24 @@ nsEventListenerManager::SetEventHandler(
nsIScriptContext* context = global->GetScriptContext();
NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
JSAutoRequest ar(context->GetNativeContext());
JS::Rooted<JSObject*> scope(context->GetNativeContext(),
global->GetGlobalJSObject());
- nsListenerStruct* ls = SetEventHandlerInternal(context, scope, aName,
+ nsListenerStruct* ls = SetEventHandlerInternal(scope, aName,
EmptyString(),
nsEventHandler(),
aPermitUntrustedEvents);
if (!aDeferCompilation) {
- return CompileEventHandlerInternal(ls, true, &aBody);
+ nsCxPusher pusher;
+ return CompileEventHandlerInternal(ls, pusher, &aBody);
}
return NS_OK;
}
void
nsEventListenerManager::RemoveEventHandler(nsIAtom* aName,
const nsAString& aTypeString)
@@ -784,38 +762,43 @@ nsEventListenerManager::RemoveEventHandl
if (mTarget) {
mTarget->EventListenerRemoved(aName);
}
}
}
nsresult
nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerStruct,
- bool aNeedsCxPush,
+ nsCxPusher& aPusher,
const nsAString* aBody)
{
NS_PRECONDITION(aListenerStruct->GetJSListener(),
"Why do we not have a JS listener?");
NS_PRECONDITION(aListenerStruct->mHandlerIsString,
"Why are we compiling a non-string JS listener?");
nsresult result = NS_OK;
nsIJSEventListener *listener = aListenerStruct->GetJSListener();
NS_ASSERTION(!listener->GetHandler().HasEventHandler(),
"What is there to compile?");
- nsIScriptContext *context = listener->GetEventContext();
+ nsCOMPtr<nsIDocument> doc;
+ nsCOMPtr<nsIScriptGlobalObject> global =
+ GetScriptGlobalAndDocument(getter_AddRefs(doc));
+ NS_ENSURE_STATE(global);
+
+ nsIScriptContext* context = global->GetScriptContext();
+ NS_ENSURE_STATE(context);
+
JSContext *cx = context->GetNativeContext();
JS::Rooted<JSObject*> handler(cx);
- nsCOMPtr<nsPIDOMWindow> win; // Will end up non-null if mTarget is a window
-
nsCxPusher pusher;
- if (aNeedsCxPush) {
+ if (aPusher.GetCurrentScriptContext() != context) {
pusher.Push(cx);
}
if (aListenerStruct->mHandlerIsString) {
// OK, we didn't find an existing compiled event handler. Flag us
// as not a string so we don't keep trying to compile strings
// which can't be compiled
aListenerStruct->mHandlerIsString = false;
@@ -854,26 +837,16 @@ nsEventListenerManager::CompileEventHand
attrName = nsGkAtoms::onend;
content->GetAttr(kNameSpaceID_None, attrName, handlerBody);
body = &handlerBody;
}
uint32_t lineNo = 0;
nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener"));
- nsCOMPtr<nsIDocument> doc;
- if (content) {
- doc = content->OwnerDoc();
- } else {
- win = do_QueryInterface(mTarget);
- if (win) {
- doc = win->GetExtantDoc();
- }
- }
-
if (doc) {
nsIURI *uri = doc->GetDocumentURI();
if (uri) {
uri->GetSpec(url);
lineNo = 1;
}
}
@@ -899,16 +872,17 @@ nsEventListenerManager::CompileEventHand
nsAtomCString(aListenerStruct->mTypeAtom),
argCount, argNames, *body, handlerFun.address());
NS_ENSURE_SUCCESS(result, result);
handler = handlerFun;
NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);
}
if (handler) {
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
// Bind it
JS::Rooted<JSObject*> boundHandler(cx);
JS::Rooted<JSObject*> scope(cx, listener->GetEventScope());
context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
aListenerStruct = nullptr;
if (!boundHandler) {
listener->ForgetHandler();
} else if (listener->EventName() == nsGkAtoms::onerror && win) {
@@ -937,21 +911,17 @@ nsEventListenerManager::HandleEventSubTy
{
nsresult result = NS_OK;
EventListenerHolder listener(aListenerStruct->mListener); // strong ref
// If this is a script handler and we haven't yet
// compiled the event handler itself
if ((aListenerStruct->mListenerType == eJSEventListener) &&
aListenerStruct->mHandlerIsString) {
- nsIJSEventListener *jslistener = aListenerStruct->GetJSListener();
- result = CompileEventHandlerInternal(aListenerStruct,
- jslistener->GetEventContext() !=
- aPusher->GetCurrentScriptContext(),
- nullptr);
+ result = CompileEventHandlerInternal(aListenerStruct, *aPusher, nullptr);
aListenerStruct = nullptr;
}
if (NS_SUCCEEDED(result)) {
if (mIsMainThreadELM) {
nsContentUtils::EnterMicroTask();
}
// nsIDOMEvent::currentTarget is set in nsEventDispatcher.
@@ -1192,18 +1162,19 @@ nsEventListenerManager::GetListenerInfo(
NS_ENSURE_STATE(target);
aList->Clear();
uint32_t count = mListeners.Length();
for (uint32_t i = 0; i < count; ++i) {
const nsListenerStruct& ls = mListeners.ElementAt(i);
// If this is a script handler and we haven't yet
// compiled the event handler itself go ahead and compile it
if ((ls.mListenerType == eJSEventListener) && ls.mHandlerIsString) {
+ nsCxPusher pusher;
CompileEventHandlerInternal(const_cast<nsListenerStruct*>(&ls),
- true, nullptr);
+ pusher, nullptr);
}
nsAutoString eventType;
if (ls.mAllEvents) {
eventType.SetIsVoid(true);
} else {
eventType.Assign(Substring(nsDependentAtomString(ls.mTypeAtom), 2));
}
// EventListenerInfo is defined in XPCOM, so we have to go ahead
@@ -1239,60 +1210,60 @@ nsEventListenerManager::SetEventHandler(
{
if (!aHandler) {
RemoveEventHandler(aEventName, aTypeString);
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
- SetEventHandlerInternal(nullptr, JS::NullPtr(), aEventName,
+ SetEventHandlerInternal(JS::NullPtr(), aEventName,
aTypeString, nsEventHandler(aHandler),
!mIsMainThreadELM ||
!nsContentUtils::IsCallerChrome());
}
void
nsEventListenerManager::SetEventHandler(OnErrorEventHandlerNonNull* aHandler)
{
if (mIsMainThreadELM) {
if (!aHandler) {
RemoveEventHandler(nsGkAtoms::onerror, EmptyString());
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
- SetEventHandlerInternal(nullptr, JS::NullPtr(), nsGkAtoms::onerror,
+ SetEventHandlerInternal(JS::NullPtr(), nsGkAtoms::onerror,
EmptyString(), nsEventHandler(aHandler),
!nsContentUtils::IsCallerChrome());
} else {
if (!aHandler) {
RemoveEventHandler(nullptr, NS_LITERAL_STRING("error"));
return;
}
// Untrusted events are always permitted.
- SetEventHandlerInternal(nullptr, JS::NullPtr(), nullptr,
+ SetEventHandlerInternal(JS::NullPtr(), nullptr,
NS_LITERAL_STRING("error"),
nsEventHandler(aHandler), true);
}
}
void
nsEventListenerManager::SetEventHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
{
if (!aHandler) {
RemoveEventHandler(nsGkAtoms::onbeforeunload, EmptyString());
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
- SetEventHandlerInternal(nullptr, JS::NullPtr(), nsGkAtoms::onbeforeunload,
+ SetEventHandlerInternal(JS::NullPtr(), nsGkAtoms::onbeforeunload,
EmptyString(), nsEventHandler(aHandler),
!mIsMainThreadELM ||
!nsContentUtils::IsCallerChrome());
}
const nsEventHandler*
nsEventListenerManager::GetEventHandlerInternal(nsIAtom *aEventName,
const nsAString& aTypeString)
@@ -1302,17 +1273,18 @@ nsEventListenerManager::GetEventHandlerI
if (!ls) {
return nullptr;
}
nsIJSEventListener *listener = ls->GetJSListener();
if (ls->mHandlerIsString) {
- CompileEventHandlerInternal(ls, true, nullptr);
+ nsCxPusher pusher;
+ CompileEventHandlerInternal(ls, pusher, nullptr);
}
const nsEventHandler& handler = listener->GetHandler();
if (handler.HasEventHandler()) {
return &handler;
}
return nullptr;
@@ -1354,8 +1326,38 @@ nsEventListenerManager::MarkForCC()
// Callback() unmarks gray
ls.mListener.GetWebIDLCallback()->Callback();
}
}
if (mRefCnt.IsPurple()) {
mRefCnt.RemovePurple();
}
}
+
+already_AddRefed<nsIScriptGlobalObject>
+nsEventListenerManager::GetScriptGlobalAndDocument(nsIDocument** aDoc)
+{
+ nsCOMPtr<nsINode> node(do_QueryInterface(mTarget));
+ nsCOMPtr<nsIDocument> doc;
+ nsCOMPtr<nsIScriptGlobalObject> global;
+ if (node) {
+ // Try to get context from doc
+ // XXX sXBL/XBL2 issue -- do we really want the owner here? What
+ // if that's the XBL document?
+ doc = node->OwnerDoc();
+ MOZ_ASSERT(!doc->IsLoadedAsData(), "Should not get in here at all");
+
+ // We want to allow compiling an event handler even in an unloaded
+ // document, so use GetScopeObject here, not GetScriptHandlingObject.
+ global = do_QueryInterface(doc->GetScopeObject());
+ } else {
+ nsCOMPtr<nsPIDOMWindow> win = GetTargetAsInnerWindow();
+ if (win) {
+ doc = win->GetExtantDoc();
+ global = do_QueryInterface(win);
+ } else {
+ global = do_QueryInterface(mTarget);
+ }
+ }
+
+ doc.forget(aDoc);
+ return global.forget();
+}
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -422,35 +422,34 @@ protected:
nsCxPusher* aPusher);
/**
* Compile the "inline" event listener for aListenerStruct. The
* body of the listener can be provided in aBody; if this is null we
* will look for it on mTarget.
*/
nsresult CompileEventHandlerInternal(nsListenerStruct *aListenerStruct,
- bool aNeedsCxPush,
+ nsCxPusher& aPusher,
const nsAString* aBody);
/**
* Find the nsListenerStruct for the "inline" event listener for aTypeAtom.
*/
nsListenerStruct* FindEventHandler(uint32_t aEventType, nsIAtom* aTypeAtom,
const nsAString& aTypeString);
/**
* Set the "inline" event listener for aName to aHandler. aHandler may be
* have no actual handler set to indicate that we should lazily get and
* compile the string for this listener, but in that case aContext and
* aScopeGlobal must be non-null. Otherwise, aContext and aScopeGlobal are
* allowed to be null. The nsListenerStruct that results, if any, is returned
* in aListenerStruct.
*/
- nsListenerStruct* SetEventHandlerInternal(nsIScriptContext *aContext,
- JS::Handle<JSObject*> aScopeGlobal,
+ nsListenerStruct* SetEventHandlerInternal(JS::Handle<JSObject*> aScopeGlobal,
nsIAtom* aName,
const nsAString& aTypeString,
const nsEventHandler& aHandler,
bool aPermitUntrustedEvents);
bool IsDeviceType(uint32_t aType);
void EnableDevice(uint32_t aType);
void DisableDevice(uint32_t aType);
@@ -533,16 +532,19 @@ protected:
void RemoveAllListeners();
const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
nsPIDOMWindow* GetInnerWindowForTarget();
already_AddRefed<nsPIDOMWindow> GetTargetAsInnerWindow() const;
bool ListenerCanHandle(nsListenerStruct* aLs, mozilla::WidgetEvent* aEvent);
+ already_AddRefed<nsIScriptGlobalObject>
+ GetScriptGlobalAndDocument(nsIDocument** aDoc);
+
uint32_t mMayHavePaintEventListener : 1;
uint32_t mMayHaveMutationListeners : 1;
uint32_t mMayHaveCapturingListeners : 1;
uint32_t mMayHaveSystemGroupListeners : 1;
uint32_t mMayHaveAudioAvailableEventListener : 1;
uint32_t mMayHaveTouchEventListener : 1;
uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
uint32_t mClearingListeners : 1;
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -3315,18 +3315,19 @@ HTMLInputElement::PreHandleEvent(nsEvent
return rv;
}
void
HTMLInputElement::StartRangeThumbDrag(WidgetGUIEvent* aEvent)
{
mIsDraggingRange = true;
mRangeThumbDragStartValue = GetValueAsDecimal();
- nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED |
- CAPTURE_RETARGETTOELEMENT);
+ // Don't use CAPTURE_RETARGETTOELEMENT, as that breaks pseudo-class styling
+ // of the thumb.
+ nsIPresShell::SetCapturingContent(this, CAPTURE_IGNOREALLOWED);
nsRangeFrame* rangeFrame = do_QueryFrame(GetPrimaryFrame());
// Before we change the value, record the current value so that we'll
// correctly send a 'change' event if appropriate. We need to do this here
// because the 'focus' event is handled after the 'mousedown' event that
// we're being called for (i.e. too late to update mFocusedValue, since we'll
// have changed it by then).
GetValueInternal(mFocusedValue);
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -13,16 +13,17 @@
#include "VideoUtils.h"
#include "MediaDecoderStateMachine.h"
#include "mozilla/dom/TimeRanges.h"
#include "nsContentUtils.h"
#include "ImageContainer.h"
#include "MediaResource.h"
#include "nsError.h"
#include "mozilla/Preferences.h"
+#include "mozilla/StaticPtr.h"
#include "nsIMemoryReporter.h"
#include "nsComponentManagerUtils.h"
#include "nsITimer.h"
#include <algorithm>
#ifdef MOZ_WMF
#include "WMFDecoder.h"
#endif
@@ -48,21 +49,23 @@ static const int64_t CAN_PLAY_THROUGH_MA
#ifdef PR_LOGGING
PRLogModuleInfo* gMediaDecoderLog;
#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
#else
#define DECODER_LOG(type, msg)
#endif
-class MediaMemoryTracker
+class MediaMemoryTracker : public nsISupports
{
+ NS_DECL_ISUPPORTS
+
MediaMemoryTracker();
- ~MediaMemoryTracker();
- static MediaMemoryTracker* sUniqueInstance;
+ virtual ~MediaMemoryTracker();
+ static StaticRefPtr<MediaMemoryTracker> sUniqueInstance;
static MediaMemoryTracker* UniqueInstance() {
if (!sUniqueInstance) {
sUniqueInstance = new MediaMemoryTracker();
}
return sUniqueInstance;
}
@@ -81,34 +84,35 @@ public:
Decoders().AppendElement(aDecoder);
}
static void RemoveMediaDecoder(MediaDecoder* aDecoder)
{
DecodersArray& decoders = Decoders();
decoders.RemoveElement(aDecoder);
if (decoders.IsEmpty()) {
- delete sUniqueInstance;
sUniqueInstance = nullptr;
}
}
static void GetAmounts(int64_t* aVideo, int64_t* aAudio)
{
*aVideo = 0;
*aAudio = 0;
DecodersArray& decoders = Decoders();
for (size_t i = 0; i < decoders.Length(); ++i) {
*aVideo += decoders[i]->VideoQueueMemoryInUse();
*aAudio += decoders[i]->AudioQueueMemoryInUse();
}
}
};
-MediaMemoryTracker* MediaMemoryTracker::sUniqueInstance = nullptr;
+StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
+
+NS_IMPL_ISUPPORTS1(MediaMemoryTracker, nsISupports)
NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver)
void MediaDecoder::SetDormantIfNecessary(bool aDormant)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
--- a/content/media/fmp4/MP4Reader.cpp
+++ b/content/media/fmp4/MP4Reader.cpp
@@ -88,72 +88,96 @@ MP4Reader::MP4Reader(AbstractMediaDecode
MOZ_COUNT_CTOR(MP4Reader);
}
MP4Reader::~MP4Reader()
{
MOZ_COUNT_DTOR(MP4Reader);
}
+void
+MP4Reader::InitLayersBackendType()
+{
+ if (!IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
+ // Not playing video, we don't care about the layers backend type.
+ return;
+ }
+ // Extract the layer manager backend type so that platform decoders
+ // can determine whether it's worthwhile using hardware accelerated
+ // video decoding.
+ MediaDecoderOwner* owner = mDecoder->GetOwner();
+ if (!owner) {
+ NS_WARNING("MP4Reader without a decoder owner, can't get HWAccel");
+ return;
+ }
+
+ dom::HTMLMediaElement* element = owner->GetMediaElement();
+ NS_ENSURE_TRUE_VOID(element);
+
+ nsRefPtr<LayerManager> layerManager =
+ nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
+ NS_ENSURE_TRUE_VOID(layerManager);
+
+ mLayersBackendType = layerManager->GetBackendType();
+}
+
nsresult
MP4Reader::Init(MediaDecoderReader* aCloneDonor)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
mMP4Stream = new MP4Stream(mDecoder->GetResource());
mDemuxer = new MP4Demuxer(mMP4Stream);
mPlatform = PlatformDecoderModule::Create();
NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE);
- if (IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
- // Extract the layer manager backend type so that platform decoders
- // can determine whether it's worthwhile using hardware accelerated
- // video decoding.
- MediaDecoderOwner* owner = mDecoder->GetOwner();
- NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
-
- dom::HTMLMediaElement* element = owner->GetMediaElement();
- NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
-
- nsRefPtr<LayerManager> layerManager =
- nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
- NS_ENSURE_TRUE(layerManager, NS_ERROR_FAILURE);
-
- mLayersBackendType = layerManager->GetBackendType();
- }
+ InitLayersBackendType();
return NS_OK;
}
nsresult
MP4Reader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{
bool ok = mDemuxer->Init();
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
- mInfo.mAudio.mHasAudio = mHasAudio = mDemuxer->HasAudio();
+ const AudioDecoderConfig& audio = mDemuxer->AudioConfig();
+ mInfo.mAudio.mHasAudio = mHasAudio = mDemuxer->HasAudio() &&
+ audio.IsValidConfig();
+ // If we have audio, we *only* allow AAC to be decoded.
+ if (mHasAudio && audio.codec() != kCodecAAC) {
+ return NS_ERROR_FAILURE;
+ }
+
+ const VideoDecoderConfig& video = mDemuxer->VideoConfig();
+ mInfo.mVideo.mHasVideo = mHasVideo = mDemuxer->HasVideo() &&
+ video.IsValidConfig();
+ // If we have video, we *only* allow H.264 to be decoded.
+ if (mHasVideo && video.codec() != kCodecH264) {
+ return NS_ERROR_FAILURE;
+ }
+
if (mHasAudio) {
- const AudioDecoderConfig& config = mDemuxer->AudioConfig();
- mInfo.mAudio.mRate = config.samples_per_second();
- mInfo.mAudio.mChannels = ChannelLayoutToChannelCount(config.channel_layout());
+ mInfo.mAudio.mRate = audio.samples_per_second();
+ mInfo.mAudio.mChannels = ChannelLayoutToChannelCount(audio.channel_layout());
mAudioDecoder = mPlatform->CreateAudioDecoder(mInfo.mAudio.mChannels,
mInfo.mAudio.mRate,
- config.bits_per_channel(),
- config.extra_data(),
- config.extra_data_size());
+ audio.bits_per_channel(),
+ audio.extra_data(),
+ audio.extra_data_size());
NS_ENSURE_TRUE(mAudioDecoder != nullptr, NS_ERROR_FAILURE);
}
mInfo.mVideo.mHasVideo = mHasVideo = mDemuxer->HasVideo();
if (mHasVideo) {
const VideoDecoderConfig& config = mDemuxer->VideoConfig();
IntSize sz = config.natural_size();
mInfo.mVideo.mDisplay = nsIntSize(sz.width(), sz.height());
-
mVideoDecoder = mPlatform->CreateVideoDecoder(mLayersBackendType,
mDecoder->GetImageContainer());
NS_ENSURE_TRUE(mVideoDecoder != nullptr, NS_ERROR_FAILURE);
}
// Get the duration, and report it to the decoder if we have it.
Microseconds duration = mDemuxer->Duration();
if (duration != -1) {
--- a/content/media/fmp4/MP4Reader.h
+++ b/content/media/fmp4/MP4Reader.h
@@ -48,16 +48,18 @@ public:
int64_t aStartTime,
int64_t aEndTime,
int64_t aCurrentTime) MOZ_OVERRIDE;
virtual void OnDecodeThreadStart() MOZ_OVERRIDE;
virtual void OnDecodeThreadFinish() MOZ_OVERRIDE;
private:
+ // Initializes mLayersBackendType if possible.
+ void InitLayersBackendType();
MP4SampleQueue& SampleQueue(mp4_demuxer::TrackType aTrack);
// Blocks until the demuxer produces an sample of specified type.
// Returns nullptr on error on EOS. Caller must delete sample.
mp4_demuxer::MP4Sample* PopSample(mp4_demuxer::TrackType aTrack);
bool Decode(mp4_demuxer::TrackType aTrack,
--- a/content/svg/content/src/SVGComponentTransferFunctionElement.h
+++ b/content/svg/content/src/SVGComponentTransferFunctionElement.h
@@ -28,26 +28,29 @@ class SVGComponentTransferFunctionElemen
{
protected:
SVGComponentTransferFunctionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGComponentTransferFunctionElementBase(aNodeInfo)
{
}
public:
+ typedef gfx::AttributeMap AttributeMap;
+
// interfaces:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID)
NS_DECL_ISUPPORTS_INHERITED
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual int32_t GetChannel() = 0;
- bool GenerateLookupTable(uint8_t* aTable);
+
+ AttributeMap ComputeAttributes();
// WebIDL
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE = 0;
already_AddRefed<SVGAnimatedEnumeration> Type();
already_AddRefed<DOMSVGAnimatedNumberList> TableValues();
already_AddRefed<SVGAnimatedNumber> Slope();
already_AddRefed<SVGAnimatedNumber> Intercept();
--- a/content/svg/content/src/SVGFEBlendElement.cpp
+++ b/content/svg/content/src/SVGFEBlendElement.cpp
@@ -4,16 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEBlendElement.h"
#include "mozilla/dom/SVGFEBlendElementBinding.h"
#include "nsSVGUtils.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEBlend)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEBlendElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEBlendElementBinding::Wrap(aCx, aScope, this);
}
@@ -63,70 +65,25 @@ SVGFEBlendElement::In2()
}
already_AddRefed<SVGAnimatedEnumeration>
SVGFEBlendElement::Mode()
{
return mEnumAttributes[MODE].ToDOMAnimatedEnum(this);
}
-nsresult
-SVGFEBlendElement::Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEBlendElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- CopyRect(aTarget, aSources[0], rect);
-
- uint8_t* sourceData = aSources[1]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- uint16_t mode = mEnumAttributes[MODE].GetAnimValue();
-
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- uint32_t targIndex = y * stride + 4 * x;
- uint32_t qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
- uint32_t qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
- for (int32_t i = std::min(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R);
- i <= std::max(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R); i++) {
- uint32_t ca = targetData[targIndex + i];
- uint32_t cb = sourceData[targIndex + i];
- uint32_t val;
- switch (mode) {
- case SVG_FEBLEND_MODE_NORMAL:
- val = (255 - qa) * cb + 255 * ca;
- break;
- case SVG_FEBLEND_MODE_MULTIPLY:
- val = ((255 - qa) * cb + (255 - qb + cb) * ca);
- break;
- case SVG_FEBLEND_MODE_SCREEN:
- val = 255 * (cb + ca) - ca * cb;
- break;
- case SVG_FEBLEND_MODE_DARKEN:
- val = std::min((255 - qa) * cb + 255 * ca,
- (255 - qb) * ca + 255 * cb);
- break;
- case SVG_FEBLEND_MODE_LIGHTEN:
- val = std::max((255 - qa) * cb + 255 * ca,
- (255 - qb) * ca + 255 * cb);
- break;
- default:
- return NS_ERROR_FAILURE;
- break;
- }
- val = std::min(val / 255, 255U);
- targetData[targIndex + i] = static_cast<uint8_t>(val);
- }
- uint32_t alpha = 255 * 255 - (255 - qa) * (255 - qb);
- FAST_DIVIDE_BY_255(targetData[targIndex + GFX_ARGB32_OFFSET_A], alpha);
- }
- }
- return NS_OK;
+ uint32_t mode = mEnumAttributes[MODE].GetAnimValue();
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eBlend);
+ descr.Attributes().Set(eBlendBlendmode, mode);
+ return descr;
}
bool
SVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/SVGFEBlendElement.h
+++ b/content/svg/content/src/SVGFEBlendElement.h
@@ -9,42 +9,35 @@
#include "nsSVGFilters.h"
#include "nsSVGEnum.h"
nsresult NS_NewSVGFEBlendElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
-static const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
-static const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
-static const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2;
-static const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
-static const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
-static const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
-
typedef nsSVGFE SVGFEBlendElementBase;
class SVGFEBlendElement : public SVGFEBlendElementBase
{
friend nsresult (::NS_NewSVGFEBlendElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFEBlendElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEBlendElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
--- a/content/svg/content/src/SVGFEColorMatrixElement.cpp
+++ b/content/svg/content/src/SVGFEColorMatrixElement.cpp
@@ -7,16 +7,18 @@
#include "mozilla/dom/SVGFEColorMatrixElement.h"
#include "mozilla/dom/SVGFEColorMatrixElementBinding.h"
#include "nsSVGUtils.h"
#define NUM_ENTRIES_IN_4x5_MATRIX 20
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEColorMatrix)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEColorMatrixElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEColorMatrixElementBinding::Wrap(aCx, aScope, this);
}
@@ -77,152 +79,45 @@ SVGFEColorMatrixElement::Values()
}
void
SVGFEColorMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsresult
-SVGFEColorMatrixElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEColorMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- uint8_t* sourceData = aSources[0]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
+ uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
const SVGNumberList &values = mNumberListAttributes[VALUES].GetAnimValue();
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eColorMatrix);
if (!mNumberListAttributes[VALUES].IsExplicitlySet() &&
(type == SVG_FECOLORMATRIX_TYPE_MATRIX ||
type == SVG_FECOLORMATRIX_TYPE_SATURATE ||
type == SVG_FECOLORMATRIX_TYPE_HUE_ROTATE)) {
- // identity matrix filter
- CopyRect(aTarget, aSources[0], rect);
- return NS_OK;
- }
-
- static const float identityMatrix[] =
- { 1, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 1, 0 };
-
- static const float luminanceToAlphaMatrix[] =
- { 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0.2125f, 0.7154f, 0.0721f, 0, 0 };
-
- float colorMatrix[NUM_ENTRIES_IN_4x5_MATRIX];
- float s, c;
-
- switch (type) {
- case SVG_FECOLORMATRIX_TYPE_MATRIX:
-
- if (values.Length() != NUM_ENTRIES_IN_4x5_MATRIX)
- return NS_ERROR_FAILURE;
-
- for(uint32_t j = 0; j < values.Length(); j++) {
- colorMatrix[j] = values[j];
- }
- break;
- case SVG_FECOLORMATRIX_TYPE_SATURATE:
-
- if (values.Length() != 1)
- return NS_ERROR_FAILURE;
-
- s = values[0];
-
- if (s > 1 || s < 0)
- return NS_ERROR_FAILURE;
-
- memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
- colorMatrix[0] = 0.213f + 0.787f * s;
- colorMatrix[1] = 0.715f - 0.715f * s;
- colorMatrix[2] = 0.072f - 0.072f * s;
-
- colorMatrix[5] = 0.213f - 0.213f * s;
- colorMatrix[6] = 0.715f + 0.285f * s;
- colorMatrix[7] = 0.072f - 0.072f * s;
-
- colorMatrix[10] = 0.213f - 0.213f * s;
- colorMatrix[11] = 0.715f - 0.715f * s;
- colorMatrix[12] = 0.072f + 0.928f * s;
-
- break;
-
- case SVG_FECOLORMATRIX_TYPE_HUE_ROTATE:
- {
- memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
- if (values.Length() != 1)
- return NS_ERROR_FAILURE;
-
- float hueRotateValue = values[0];
-
- c = static_cast<float>(cos(hueRotateValue * M_PI / 180));
- s = static_cast<float>(sin(hueRotateValue * M_PI / 180));
-
- memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
- colorMatrix[0] = 0.213f + 0.787f * c - 0.213f * s;
- colorMatrix[1] = 0.715f - 0.715f * c - 0.715f * s;
- colorMatrix[2] = 0.072f - 0.072f * c + 0.928f * s;
-
- colorMatrix[5] = 0.213f - 0.213f * c + 0.143f * s;
- colorMatrix[6] = 0.715f + 0.285f * c + 0.140f * s;
- colorMatrix[7] = 0.072f - 0.072f * c - 0.283f * s;
-
- colorMatrix[10] = 0.213f - 0.213f * c - 0.787f * s;
- colorMatrix[11] = 0.715f - 0.715f * c + 0.715f * s;
- colorMatrix[12] = 0.072f + 0.928f * c + 0.072f * s;
-
- break;
- }
-
- case SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA:
-
- memcpy(colorMatrix, luminanceToAlphaMatrix, sizeof(colorMatrix));
- break;
-
- default:
- return NS_ERROR_FAILURE;
- }
-
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- uint32_t targIndex = y * stride + 4 * x;
-
- float col[4];
- for (int i = 0, row = 0; i < 4; i++, row += 5) {
- col[i] =
- sourceData[targIndex + GFX_ARGB32_OFFSET_R] * colorMatrix[row + 0] +
- sourceData[targIndex + GFX_ARGB32_OFFSET_G] * colorMatrix[row + 1] +
- sourceData[targIndex + GFX_ARGB32_OFFSET_B] * colorMatrix[row + 2] +
- sourceData[targIndex + GFX_ARGB32_OFFSET_A] * colorMatrix[row + 3] +
- 255 * colorMatrix[row + 4];
- col[i] = clamped(col[i], 0.f, 255.f);
- }
- targetData[targIndex + GFX_ARGB32_OFFSET_R] =
- static_cast<uint8_t>(col[0]);
- targetData[targIndex + GFX_ARGB32_OFFSET_G] =
- static_cast<uint8_t>(col[1]);
- targetData[targIndex + GFX_ARGB32_OFFSET_B] =
- static_cast<uint8_t>(col[2]);
- targetData[targIndex + GFX_ARGB32_OFFSET_A] =
- static_cast<uint8_t>(col[3]);
+ descr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_MATRIX);
+ static const float identityMatrix[] =
+ { 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0 };
+ descr.Attributes().Set(eColorMatrixValues, identityMatrix, 20);
+ } else {
+ descr.Attributes().Set(eColorMatrixType, type);
+ if (values.Length()) {
+ descr.Attributes().Set(eColorMatrixValues, &values[0], values.Length());
+ } else {
+ descr.Attributes().Set(eColorMatrixValues, nullptr, 0);
}
}
- return NS_OK;
+ return descr;
}
bool
SVGFEColorMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEColorMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/SVGFEColorMatrixElement.h
+++ b/content/svg/content/src/SVGFEColorMatrixElement.h
@@ -13,54 +13,46 @@
nsresult NS_NewSVGFEColorMatrixElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
typedef nsSVGFE SVGFEColorMatrixElementBase;
-static const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
-static const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
-static const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2;
-static const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE = 3;
-static const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA = 4;
-
class SVGFEColorMatrixElement : public SVGFEColorMatrixElementBase
{
friend nsresult (::NS_NewSVGFEColorMatrixElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFEColorMatrixElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEColorMatrixElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedEnumeration> Type();
already_AddRefed<DOMSVGAnimatedNumberList> Values();
protected:
- virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE { return false; }
-
virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
enum { TYPE };
nsSVGEnum mEnumAttributes[1];
static nsSVGEnumMapping sTypeMap[];
static EnumInfo sEnumInfo[1];
--- a/content/svg/content/src/SVGFEComponentTransferElement.cpp
+++ b/content/svg/content/src/SVGFEComponentTransferElement.cpp
@@ -2,19 +2,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGComponentTransferFunctionElement.h"
#include "mozilla/dom/SVGFEComponentTransferElement.h"
#include "mozilla/dom/SVGFEComponentTransferElementBinding.h"
#include "nsSVGUtils.h"
+#include "mozilla/gfx/2D.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEComponentTransfer)
+using namespace mozilla::gfx;;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEComponentTransferElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEComponentTransferElementBinding::Wrap(aCx, aScope, this);
}
@@ -43,58 +46,54 @@ nsSVGElement::StringAttributesInfo
SVGFEComponentTransferElement::GetStringInfo()
{
return StringAttributesInfo(mStringAttributes, sStringInfo,
ArrayLength(sStringInfo));
}
//--------------------------------------------
-nsresult
-SVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEComponentTransferElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- uint8_t* sourceData = aSources[0]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
+ nsRefPtr<SVGComponentTransferFunctionElement> childForChannel[4];
- uint8_t tableR[256], tableG[256], tableB[256], tableA[256];
- for (int i=0; i<256; i++)
- tableR[i] = tableG[i] = tableB[i] = tableA[i] = i;
- uint8_t* tables[] = { tableR, tableG, tableB, tableA };
for (nsIContent* childContent = nsINode::GetFirstChild();
childContent;
childContent = childContent->GetNextSibling()) {
nsRefPtr<SVGComponentTransferFunctionElement> child;
CallQueryInterface(childContent,
(SVGComponentTransferFunctionElement**)getter_AddRefs(child));
if (child) {
- if (!child->GenerateLookupTable(tables[child->GetChannel()])) {
- return NS_ERROR_FAILURE;
- }
+ childForChannel[child->GetChannel()] = child;
}
}
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- int32_t targIndex = y * stride + x * 4;
- targetData[targIndex + GFX_ARGB32_OFFSET_B] =
- tableB[sourceData[targIndex + GFX_ARGB32_OFFSET_B]];
- targetData[targIndex + GFX_ARGB32_OFFSET_G] =
- tableG[sourceData[targIndex + GFX_ARGB32_OFFSET_G]];
- targetData[targIndex + GFX_ARGB32_OFFSET_R] =
- tableR[sourceData[targIndex + GFX_ARGB32_OFFSET_R]];
- targetData[targIndex + GFX_ARGB32_OFFSET_A] =
- tableA[sourceData[targIndex + GFX_ARGB32_OFFSET_A]];
+ static const AttributeName attributeNames[4] = {
+ eComponentTransferFunctionR,
+ eComponentTransferFunctionG,
+ eComponentTransferFunctionB,
+ eComponentTransferFunctionA
+ };
+
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eComponentTransfer);
+ for (int32_t i = 0; i < 4; i++) {
+ if (childForChannel[i]) {
+ descr.Attributes().Set(attributeNames[i], childForChannel[i]->ComputeAttributes());
+ } else {
+ AttributeMap functionAttributes;
+ functionAttributes.Set(eComponentTransferFunctionType,
+ (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
+ descr.Attributes().Set(attributeNames[i], functionAttributes);
}
}
- return NS_OK;
+ return descr;
}
bool
SVGFEComponentTransferElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEComponentTransferElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/SVGFEComponentTransferElement.h
+++ b/content/svg/content/src/SVGFEComponentTransferElement.h
@@ -24,34 +24,32 @@ protected:
SVGFEComponentTransferElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEComponentTransferElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
// nsIContent
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
protected:
- virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE { return false; }
-
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
};
} // namespace mozilla
--- a/content/svg/content/src/SVGFECompositeElement.cpp
+++ b/content/svg/content/src/SVGFECompositeElement.cpp
@@ -4,16 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFECompositeElement.h"
#include "mozilla/dom/SVGFECompositeElementBinding.h"
#include "gfxContext.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEComposite)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFECompositeElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFECompositeElementBinding::Wrap(aCx, aScope, this);
}
@@ -102,77 +104,32 @@ void
SVGFECompositeElement::SetK(float k1, float k2, float k3, float k4)
{
mNumberAttributes[ATTR_K1].SetBaseValue(k1, this);
mNumberAttributes[ATTR_K2].SetBaseValue(k2, this);
mNumberAttributes[ATTR_K3].SetBaseValue(k3, this);
mNumberAttributes[ATTR_K4].SetBaseValue(k4, this);
}
-nsresult
-SVGFECompositeElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFECompositeElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- uint16_t op = mEnumAttributes[OPERATOR].GetAnimValue();
-
- // Cairo does not support arithmetic operator
- if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
- float k1, k2, k3, k4;
- GetAnimatedNumberValues(&k1, &k2, &k3, &k4, nullptr);
-
- // Copy the first source image
- CopyRect(aTarget, aSources[0], rect);
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eComposite);
+ uint32_t op = mEnumAttributes[OPERATOR].GetAnimValue();
+ descr.Attributes().Set(eCompositeOperator, op);
- uint8_t* sourceData = aSources[1]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- // Blend in the second source image
- float k1Scaled = k1 / 255.0f;
- float k4Scaled = k4*255.0f;
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- uint32_t targIndex = y * stride + 4 * x;
- for (int32_t i = 0; i < 4; i++) {
- uint8_t i1 = targetData[targIndex + i];
- uint8_t i2 = sourceData[targIndex + i];
- float result = k1Scaled*i1*i2 + k2*i1 + k3*i2 + k4Scaled;
- targetData[targIndex + i] =
- static_cast<uint8_t>(clamped(result, 0.f, 255.f));
- }
- }
- }
- return NS_OK;
+ if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
+ float k[4];
+ GetAnimatedNumberValues(k, k+1, k+2, k+3, nullptr);
+ descr.Attributes().Set(eCompositeCoefficients, k, 4);
}
- // Cairo supports the operation we are trying to perform
-
- gfxContext ctx(aTarget->mImage);
- ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
- ctx.SetSource(aSources[1]->mImage);
- // Ensure rendering is limited to the filter primitive subregion
- ctx.Clip(aTarget->mFilterPrimitiveSubregion);
- ctx.Paint();
-
- if (op < SVG_FECOMPOSITE_OPERATOR_OVER || op > SVG_FECOMPOSITE_OPERATOR_XOR) {
- return NS_ERROR_FAILURE;
- }
- static const gfxContext::GraphicsOperator opMap[] = {
- gfxContext::OPERATOR_DEST,
- gfxContext::OPERATOR_OVER,
- gfxContext::OPERATOR_IN,
- gfxContext::OPERATOR_OUT,
- gfxContext::OPERATOR_ATOP,
- gfxContext::OPERATOR_XOR };
- ctx.SetOperator(opMap[op]);
- ctx.SetSource(aSources[0]->mImage);
- ctx.Paint();
- return NS_OK;
+ return descr;
}
bool
SVGFECompositeElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFECompositeElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
@@ -187,44 +144,16 @@ SVGFECompositeElement::AttributeAffectsR
void
SVGFECompositeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
}
-nsIntRect
-SVGFECompositeElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- uint16_t op = mEnumAttributes[OPERATOR].GetAnimValue();
-
- if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
- // "arithmetic" operator can produce non-zero alpha values even where
- // all input alphas are zero, so we can actually render outside the
- // union of the source bboxes.
- // XXX we could also check that k4 is nonzero and check for other
- // cases like k1/k2 or k1/k3 zero.
- return GetMaxRect();
- }
-
- if (op == SVG_FECOMPOSITE_OPERATOR_IN ||
- op == SVG_FECOMPOSITE_OPERATOR_ATOP) {
- // We will only draw where in2 has nonzero alpha, so it's a good
- // bounding box for us
- return aSourceBBoxes[1];
- }
-
- // The regular Porter-Duff operators always compute zero alpha values
- // where all sources have zero alpha, so the union of their bounding
- // boxes is also a bounding box for our rendering
- return SVGFECompositeElementBase::ComputeTargetBBox(aSourceBBoxes, aInstance);
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
SVGFECompositeElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
ArrayLength(sNumberInfo));
--- a/content/svg/content/src/SVGFECompositeElement.h
+++ b/content/svg/content/src/SVGFECompositeElement.h
@@ -11,50 +11,39 @@
#include "nsSVGNumber2.h"
nsresult NS_NewSVGFECompositeElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
-// Composite Operators
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5;
-static const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
-
typedef nsSVGFE SVGFECompositeElementBase;
class SVGFECompositeElement : public SVGFECompositeElementBase
{
friend nsresult (::NS_NewSVGFECompositeElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFECompositeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFECompositeElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedString> In2();
already_AddRefed<SVGAnimatedEnumeration> Operator();
--- a/content/svg/content/src/SVGFEConvolveMatrixElement.cpp
+++ b/content/svg/content/src/SVGFEConvolveMatrixElement.cpp
@@ -2,27 +2,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEConvolveMatrixElement.h"
#include "mozilla/dom/SVGFEConvolveMatrixElementBinding.h"
#include "DOMSVGAnimatedNumberList.h"
#include "nsSVGUtils.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEConvolveMatrix)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
-// Edge Mode Values
-static const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
-static const unsigned short SVG_EDGEMODE_WRAP = 2;
-static const unsigned short SVG_EDGEMODE_NONE = 3;
-
JSObject*
SVGFEConvolveMatrixElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEConvolveMatrixElementBinding::Wrap(aCx, aScope, this);
}
nsSVGElement::NumberInfo SVGFEConvolveMatrixElement::sNumberInfo[2] =
{
@@ -160,207 +158,94 @@ SVGFEConvolveMatrixElement::KernelUnitLe
}
void
SVGFEConvolveMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsIntRect
-SVGFEConvolveMatrixElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX A more precise box is possible when 'bias' is zero and 'edgeMode' is
- // 'none', but it requires analysis of 'kernelUnitLength', 'order' and
- // 'targetX/Y', so it's quite a lot of work. Don't do it for now.
- return GetMaxRect();
-}
-
-void
-SVGFEConvolveMatrixElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- // XXX Precise results are possible but we're going to skip that work
- // for now. Do nothing, which means the needed-box remains the
- // source's output bounding box.
-}
-
-nsIntRect
-SVGFEConvolveMatrixElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX Precise results are possible but we're going to skip that work
- // for now.
- return GetMaxRect();
-}
-
-static int32_t BoundInterval(int32_t aVal, int32_t aMax)
-{
- aVal = std::max(aVal, 0);
- return std::min(aVal, aMax - 1);
-}
-
-static int32_t WrapInterval(int32_t aVal, int32_t aMax)
-{
- aVal = aVal % aMax;
- return aVal < 0 ? aMax + aVal : aVal;
-}
-
-static void
-ConvolvePixel(const uint8_t *aSourceData,
- uint8_t *aTargetData,
- int32_t aWidth, int32_t aHeight,
- int32_t aStride,
- int32_t aX, int32_t aY,
- uint16_t aEdgeMode,
- const float *aKernel,
- float aDivisor, float aBias,
- bool aPreserveAlpha,
- int32_t aOrderX, int32_t aOrderY,
- int32_t aTargetX, int32_t aTargetY)
+FilterPrimitiveDescription
+SVGFEConvolveMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- float sum[4] = {0, 0, 0, 0};
- aBias *= 255;
- int32_t offsets[4] = {GFX_ARGB32_OFFSET_R,
- GFX_ARGB32_OFFSET_G,
- GFX_ARGB32_OFFSET_B,
- GFX_ARGB32_OFFSET_A } ;
- int32_t channels = aPreserveAlpha ? 3 : 4;
+ const FilterPrimitiveDescription failureDescription(FilterPrimitiveDescription::eNone);
- for (int32_t y = 0; y < aOrderY; y++) {
- int32_t sampleY = aY + y - aTargetY;
- bool overscanY = sampleY < 0 || sampleY >= aHeight;
- for (int32_t x = 0; x < aOrderX; x++) {
- int32_t sampleX = aX + x - aTargetX;
- bool overscanX = sampleX < 0 || sampleX >= aWidth;
- for (int32_t i = 0; i < channels; i++) {
- if (overscanY || overscanX) {
- switch (aEdgeMode) {
- case SVG_EDGEMODE_DUPLICATE:
- sum[i] +=
- aSourceData[BoundInterval(sampleY, aHeight) * aStride +
- BoundInterval(sampleX, aWidth) * 4 + offsets[i]] *
- aKernel[aOrderX * y + x];
- break;
- case SVG_EDGEMODE_WRAP:
- sum[i] +=
- aSourceData[WrapInterval(sampleY, aHeight) * aStride +
- WrapInterval(sampleX, aWidth) * 4 + offsets[i]] *
- aKernel[aOrderX * y + x];
- break;
- default:
- break;
- }
- } else {
- sum[i] +=
- aSourceData[sampleY * aStride + 4 * sampleX + offsets[i]] *
- aKernel[aOrderX * y + x];
- }
- }
- }
- }
- for (int32_t i = 0; i < channels; i++) {
- aTargetData[aY * aStride + 4 * aX + offsets[i]] =
- BoundInterval(static_cast<int32_t>(sum[i] / aDivisor + aBias), 256);
- }
- if (aPreserveAlpha) {
- aTargetData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A] =
- aSourceData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A];
- }
-}
-
-nsresult
-SVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
-{
const SVGNumberList &kernelMatrix =
mNumberListAttributes[KERNELMATRIX].GetAnimValue();
uint32_t kmLength = kernelMatrix.Length();
int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
if (orderX <= 0 || orderY <= 0 ||
static_cast<uint32_t>(orderX * orderY) != kmLength) {
- return NS_ERROR_FAILURE;
+ return failureDescription;
}
int32_t targetX, targetY;
GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
if (targetX < 0 || targetX >= orderX)
- return NS_ERROR_FAILURE;
+ return failureDescription;
} else {
targetX = orderX / 2;
}
if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
if (targetY < 0 || targetY >= orderY)
- return NS_ERROR_FAILURE;
+ return failureDescription;
} else {
targetY = orderY / 2;
}
if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
- return NS_ERROR_FAILURE;
+ return failureDescription;
const fallible_t fallible = fallible_t();
nsAutoArrayPtr<float> kernel(new (fallible) float[orderX * orderY]);
if (!kernel)
- return NS_ERROR_FAILURE;
+ return failureDescription;
for (uint32_t i = 0; i < kmLength; i++) {
kernel[kmLength - 1 - i] = kernelMatrix[i];
}
float divisor;
if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
divisor = mNumberAttributes[DIVISOR].GetAnimValue();
if (divisor == 0)
- return NS_ERROR_FAILURE;
+ return failureDescription;
} else {
divisor = kernel[0];
for (uint32_t i = 1; i < kmLength; i++)
divisor += kernel[i];
if (divisor == 0)
divisor = 1;
}
- ScaleInfo info = SetupScalingFilter(instance, aSources[0], aTarget, rect,
- &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
- if (!info.mTarget)
- return NS_ERROR_FAILURE;
-
- uint16_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
+ uint32_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
-
float bias = mNumberAttributes[BIAS].GetAnimValue();
- const nsIntRect& dataRect = info.mDataRect;
- int32_t stride = info.mSource->Stride();
- int32_t width = info.mSource->GetSize().width;
- int32_t height = info.mSource->GetSize().height;
- uint8_t *sourceData = info.mSource->Data();
- uint8_t *targetData = info.mTarget->Data();
+ Size kernelUnitLength =
+ GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
- for (int32_t y = dataRect.y; y < dataRect.YMost(); y++) {
- for (int32_t x = dataRect.x; x < dataRect.XMost(); x++) {
- ConvolvePixel(sourceData, targetData,
- width, height, stride,
- x, y,
- edgeMode, kernel, divisor, bias, preserveAlpha,
- orderX, orderY, targetX, targetY);
- }
- }
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eConvolveMatrix);
+ AttributeMap& atts = descr.Attributes();
+ atts.Set(eConvolveMatrixKernelSize, IntSize(orderX, orderY));
+ atts.Set(eConvolveMatrixKernelMatrix, &kernelMatrix[0], kmLength);
+ atts.Set(eConvolveMatrixDivisor, divisor);
+ atts.Set(eConvolveMatrixBias, bias);
+ atts.Set(eConvolveMatrixTarget, IntPoint(targetX, targetY));
+ atts.Set(eConvolveMatrixEdgeMode, edgeMode);
+ atts.Set(eConvolveMatrixKernelUnitLength, kernelUnitLength);
+ atts.Set(eConvolveMatrixPreserveAlpha, preserveAlpha);
- FinishScalingFilter(&info);
-
- return NS_OK;
+ return descr;
}
bool
SVGFEConvolveMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/SVGFEConvolveMatrixElement.h
+++ b/content/svg/content/src/SVGFEConvolveMatrixElement.h
@@ -34,31 +34,24 @@ protected:
SVGFEConvolveMatrixElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEConvolveMatrixElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
-
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedInteger> OrderX();
already_AddRefed<SVGAnimatedInteger> OrderY();
already_AddRefed<DOMSVGAnimatedNumberList> KernelMatrix();
@@ -67,20 +60,16 @@ public:
already_AddRefed<SVGAnimatedEnumeration> EdgeMode();
already_AddRefed<SVGAnimatedBoolean> PreserveAlpha();
already_AddRefed<SVGAnimatedNumber> Divisor();
already_AddRefed<SVGAnimatedNumber> Bias();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthX();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthY();
protected:
- virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE {
- return !mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
- }
-
virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
virtual IntegerAttributesInfo GetIntegerInfo() MOZ_OVERRIDE;
virtual IntegerPairAttributesInfo GetIntegerPairInfo() MOZ_OVERRIDE;
virtual BooleanAttributesInfo GetBooleanInfo() MOZ_OVERRIDE;
virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGFEDiffuseLightingElement.cpp
+++ b/content/svg/content/src/SVGFEDiffuseLightingElement.cpp
@@ -1,19 +1,22 @@
/* a*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFEDiffuseLightingElement.h"
#include "mozilla/dom/SVGFEDiffuseLightingElementBinding.h"
#include "nsSVGUtils.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEDiffuseLighting)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEDiffuseLightingElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEDiffuseLightingElementBinding::Wrap(aCx, aScope, this);
}
@@ -52,40 +55,31 @@ SVGFEDiffuseLightingElement::KernelUnitL
already_AddRefed<SVGAnimatedNumber>
SVGFEDiffuseLightingElement::KernelUnitLengthY()
{
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
nsSVGNumberPair::eSecond, this);
}
+FilterPrimitiveDescription
+SVGFEDiffuseLightingElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
+{
+ float diffuseConstant = mNumberAttributes[DIFFUSE_CONSTANT].GetAnimValue();
+
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eDiffuseLighting);
+ descr.Attributes().Set(eDiffuseLightingDiffuseConstant, diffuseConstant);
+ return AddLightingAttributes(descr, aInstance);
+}
+
bool
SVGFEDiffuseLightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEDiffuseLightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::diffuseConstant);
}
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-void
-SVGFEDiffuseLightingElement::LightPixel(const float *N, const float *L,
- nscolor color, uint8_t *targetData)
-{
- float diffuseNL =
- mNumberAttributes[DIFFUSE_CONSTANT].GetAnimValue() * DOT(N, L);
-
- if (diffuseNL < 0) diffuseNL = 0;
-
- targetData[GFX_ARGB32_OFFSET_B] =
- std::min(uint32_t(diffuseNL * NS_GET_B(color)), 255U);
- targetData[GFX_ARGB32_OFFSET_G] =
- std::min(uint32_t(diffuseNL * NS_GET_G(color)), 255U);
- targetData[GFX_ARGB32_OFFSET_R] =
- std::min(uint32_t(diffuseNL * NS_GET_R(color)), 255U);
- targetData[GFX_ARGB32_OFFSET_A] = 255;
-}
-
} // namespace dom
} // namespace mozilla
--- a/content/svg/content/src/SVGFEDiffuseLightingElement.h
+++ b/content/svg/content/src/SVGFEDiffuseLightingElement.h
@@ -24,30 +24,29 @@ protected:
SVGFEDiffuseLightingElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEDiffuseLightingElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedNumber> SurfaceScale();
already_AddRefed<SVGAnimatedNumber> DiffuseConstant();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthX();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthY();
-
-protected:
- virtual void LightPixel(const float *N, const float *L,
- nscolor color, uint8_t *targetData);
-
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGFEDiffuseLightingElement_h
--- a/content/svg/content/src/SVGFEDisplacementMapElement.cpp
+++ b/content/svg/content/src/SVGFEDisplacementMapElement.cpp
@@ -5,25 +5,21 @@
#include "mozilla/dom/SVGFEDisplacementMapElement.h"
#include "mozilla/dom/SVGFEDisplacementMapElementBinding.h"
#include "nsSVGFilterInstance.h"
#include "nsSVGUtils.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEDisplacementMap)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
-// Channel Selectors
-static const unsigned short SVG_CHANNEL_R = 1;
-static const unsigned short SVG_CHANNEL_G = 2;
-static const unsigned short SVG_CHANNEL_B = 3;
-static const unsigned short SVG_CHANNEL_A = 4;
-
JSObject*
SVGFEDisplacementMapElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEDisplacementMapElementBinding::Wrap(aCx, aScope, this);
}
nsSVGElement::NumberInfo SVGFEDisplacementMapElement::sNumberInfo[1] =
{
@@ -89,78 +85,30 @@ SVGFEDisplacementMapElement::XChannelSel
}
already_AddRefed<SVGAnimatedEnumeration>
SVGFEDisplacementMapElement::YChannelSelector()
{
return mEnumAttributes[CHANNEL_Y].ToDOMAnimatedEnum(this);
}
-nsresult
-SVGFEDisplacementMapElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEDisplacementMapElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- float scale = instance->GetPrimitiveNumber(SVGContentUtils::XY,
- &mNumberAttributes[SCALE]);
- if (scale == 0.0f) {
- CopyRect(aTarget, aSources[0], rect);
- return NS_OK;
- }
-
- int32_t width = instance->GetSurfaceWidth();
- int32_t height = instance->GetSurfaceHeight();
-
- uint8_t* sourceData = aSources[0]->mImage->Data();
- uint8_t* displacementData = aSources[1]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- static const uint8_t dummyData[4] = { 0, 0, 0, 0 };
-
- static const uint16_t channelMap[5] = {
- 0,
- GFX_ARGB32_OFFSET_R,
- GFX_ARGB32_OFFSET_G,
- GFX_ARGB32_OFFSET_B,
- GFX_ARGB32_OFFSET_A };
- uint16_t xChannel = channelMap[mEnumAttributes[CHANNEL_X].GetAnimValue()];
- uint16_t yChannel = channelMap[mEnumAttributes[CHANNEL_Y].GetAnimValue()];
-
- double scaleOver255 = scale / 255.0;
- double scaleAdjustment = 0.5 - 0.5 * scale;
-
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- uint32_t targIndex = y * stride + 4 * x;
- // At some point we might want to replace this with a bilinear sample.
- int32_t sourceX = x +
- NSToIntFloor(scaleOver255 * displacementData[targIndex + xChannel] +
- scaleAdjustment);
- int32_t sourceY = y +
- NSToIntFloor(scaleOver255 * displacementData[targIndex + yChannel] +
- scaleAdjustment);
-
- bool outOfBounds = sourceX < 0 || sourceX >= width ||
- sourceY < 0 || sourceY >= height;
- const uint8_t* data;
- int32_t multiplier;
- if (outOfBounds) {
- data = dummyData;
- multiplier = 0;
- } else {
- data = sourceData;
- multiplier = 1;
- }
- *(uint32_t*)(targetData + targIndex) =
- *(uint32_t*)(data + multiplier * (sourceY * stride + 4 * sourceX));
- }
- }
- return NS_OK;
+ float scale = aInstance->GetPrimitiveNumber(SVGContentUtils::XY,
+ &mNumberAttributes[SCALE]);
+ uint32_t xChannel = mEnumAttributes[CHANNEL_X].GetAnimValue();
+ uint32_t yChannel = mEnumAttributes[CHANNEL_Y].GetAnimValue();
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eDisplacementMap);
+ descr.Attributes().Set(eDisplacementMapScale, scale);
+ descr.Attributes().Set(eDisplacementMapXChannel, xChannel);
+ descr.Attributes().Set(eDisplacementMapYChannel, yChannel);
+ return descr;
}
bool
SVGFEDisplacementMapElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEDisplacementMapElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
@@ -173,48 +121,16 @@ SVGFEDisplacementMapElement::AttributeAf
void
SVGFEDisplacementMapElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
}
-nsIntRect
-SVGFEDisplacementMapElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX we could do something clever here involving analysis of 'scale'
- // to figure out the maximum displacement, and then return mIn1's bounds
- // adjusted for the maximum displacement
- return GetMaxRect();
-}
-
-void
-SVGFEDisplacementMapElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- // in2 contains the displacements, which we read for each target pixel
- aSourceBBoxes[1] = aTargetBBox;
- // XXX to figure out which parts of 'in' we might read, we could
- // do some analysis of 'scale' to figure out the maximum displacement.
- // For now, just leave aSourceBBoxes[0] alone, i.e. assume we use its
- // entire output bounding box.
- // If we change this, we need to change coordinate assumptions above
-}
-
-nsIntRect
-SVGFEDisplacementMapElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX we could do something clever here involving analysis of 'scale'
- // to figure out the maximum displacement
- return GetMaxRect();
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
SVGFEDisplacementMapElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
ArrayLength(sNumberInfo));
--- a/content/svg/content/src/SVGFEDisplacementMapElement.h
+++ b/content/svg/content/src/SVGFEDisplacementMapElement.h
@@ -25,58 +25,47 @@ protected:
SVGFEDisplacementMapElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEDisplacementMapElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
-
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedString> In2();
already_AddRefed<SVGAnimatedNumber> Scale();
already_AddRefed<SVGAnimatedEnumeration> XChannelSelector();
already_AddRefed<SVGAnimatedEnumeration> YChannelSelector();
protected:
- virtual bool OperatesOnSRGB(nsSVGFilterInstance* aInstance,
- int32_t aInput, Image* aImage) MOZ_OVERRIDE {
- switch (aInput) {
+ virtual bool OperatesOnSRGB(int32_t aInputIndex,
+ bool aInputIsAlreadySRGB) MOZ_OVERRIDE {
+ switch (aInputIndex) {
case 0:
- return aImage->mColorModel.mColorSpace == ColorModel::SRGB;
+ return aInputIsAlreadySRGB;
case 1:
- return SVGFEDisplacementMapElementBase::OperatesOnSRGB(aInstance,
- aInput, aImage);
+ return SVGFEDisplacementMapElementBase::OperatesOnSRGB(aInputIndex, aInputIsAlreadySRGB);
default:
- NS_ERROR("Will not give correct output color model");
+ NS_ERROR("Will not give correct color model");
return false;
}
}
- virtual bool OperatesOnPremultipledAlpha(int32_t aInput) MOZ_OVERRIDE {
- return !(aInput == 1);
- }
virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { SCALE };
nsSVGNumber2 mNumberAttributes[1];
static NumberInfo sNumberInfo[1];
--- a/content/svg/content/src/SVGFEDistantLightElement.cpp
+++ b/content/svg/content/src/SVGFEDistantLightElement.cpp
@@ -1,18 +1,21 @@
/* a*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFEDistantLightElement.h"
#include "mozilla/dom/SVGFEDistantLightElementBinding.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEDistantLight)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEDistantLightElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEDistantLightElementBinding::Wrap(aCx, aScope, this);
}
@@ -35,16 +38,29 @@ bool
SVGFEDistantLightElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::azimuth ||
aAttribute == nsGkAtoms::elevation);
}
+AttributeMap
+SVGFEDistantLightElement::ComputeLightAttributes(nsSVGFilterInstance* aInstance)
+{
+ float azimuth, elevation;
+ GetAnimatedNumberValues(&azimuth, &elevation, nullptr);
+
+ AttributeMap map;
+ map.Set(eLightType, (uint32_t)eLightTypeDistant);
+ map.Set(eDistantLightAzimuth, azimuth);
+ map.Set(eDistantLightElevation, elevation);
+ return map;
+}
+
already_AddRefed<SVGAnimatedNumber>
SVGFEDistantLightElement::Azimuth()
{
return mNumberAttributes[AZIMUTH].ToDOMAnimatedNumber(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEDistantLightElement::Elevation()
--- a/content/svg/content/src/SVGFEDistantLightElement.h
+++ b/content/svg/content/src/SVGFEDistantLightElement.h
@@ -4,37 +4,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGFEDistantLightElement_h
#define mozilla_dom_SVGFEDistantLightElement_h
#include "nsSVGFilters.h"
#include "nsSVGNumber2.h"
-typedef SVGFEUnstyledElement SVGFEDistantLightElementBase;
-
nsresult NS_NewSVGFEDistantLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
+typedef SVGFELightElement SVGFEDistantLightElementBase;
+
class SVGFEDistantLightElement : public SVGFEDistantLightElementBase
{
friend nsresult (::NS_NewSVGFEDistantLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFEDistantLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEDistantLightElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
+ virtual AttributeMap ComputeLightAttributes(nsSVGFilterInstance* aInstance) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedNumber> Azimuth();
already_AddRefed<SVGAnimatedNumber> Elevation();
--- a/content/svg/content/src/SVGFEFloodElement.cpp
+++ b/content/svg/content/src/SVGFEFloodElement.cpp
@@ -2,19 +2,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEFloodElement.h"
#include "mozilla/dom/SVGFEFloodElementBinding.h"
#include "gfxContext.h"
#include "gfxColor.h"
+#include "nsIFrame.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFlood)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEFloodElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEFloodElementBinding::Wrap(aCx, aScope, this);
}
@@ -24,44 +27,36 @@ nsSVGElement::StringInfo SVGFEFloodEleme
{ &nsGkAtoms::result, kNameSpaceID_None, true }
};
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFloodElement)
-nsresult
-SVGFEFloodElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect)
+FilterPrimitiveDescription
+SVGFEFloodElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eFlood);
nsIFrame* frame = GetPrimaryFrame();
- if (!frame) return NS_ERROR_FAILURE;
- nsStyleContext* style = frame->StyleContext();
-
- nscolor floodColor = style->StyleSVGReset()->mFloodColor;
- float floodOpacity = style->StyleSVGReset()->mFloodOpacity;
-
- gfxContext ctx(aTarget->mImage);
- ctx.SetColor(gfxRGBA(NS_GET_R(floodColor) / 255.0,
- NS_GET_G(floodColor) / 255.0,
- NS_GET_B(floodColor) / 255.0,
- NS_GET_A(floodColor) / 255.0 * floodOpacity));
- ctx.Rectangle(aTarget->mFilterPrimitiveSubregion);
- ctx.Fill();
- return NS_OK;
-}
-
-nsIntRect
-SVGFEFloodElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return GetMaxRect();
+ if (frame) {
+ nsStyleContext* style = frame->StyleContext();
+ nscolor floodColor = style->StyleSVGReset()->mFloodColor;
+ float floodOpacity = style->StyleSVGReset()->mFloodOpacity;
+ Color color(NS_GET_R(floodColor) / 255.0,
+ NS_GET_G(floodColor) / 255.0,
+ NS_GET_B(floodColor) / 255.0,
+ NS_GET_A(floodColor) / 255.0 * floodOpacity);
+ descr.Attributes().Set(eFloodColor, color);
+ } else {
+ descr.Attributes().Set(eFloodColor, Color());
+ }
+ return descr;
}
//----------------------------------------------------------------------
// nsIContent methods
NS_IMETHODIMP_(bool)
SVGFEFloodElement::IsAttributeMapped(const nsIAtom* name) const
{
--- a/content/svg/content/src/SVGFEFloodElement.h
+++ b/content/svg/content/src/SVGFEFloodElement.h
@@ -26,32 +26,29 @@ protected:
{
}
virtual JSObject* WrapNode(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
public:
virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
protected:
- virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
- int32_t, Image*) MOZ_OVERRIDE { return true; }
+ virtual bool ProducesSRGB() MOZ_OVERRIDE { return true; }
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { RESULT };
nsSVGString mStringAttributes[1];
static StringInfo sStringInfo[1];
};
--- a/content/svg/content/src/SVGFEGaussianBlurElement.cpp
+++ b/content/svg/content/src/SVGFEGaussianBlurElement.cpp
@@ -5,16 +5,18 @@
#include "mozilla/dom/SVGFEGaussianBlurElement.h"
#include "mozilla/dom/SVGFEGaussianBlurElementBinding.h"
#include "nsSVGFilterInstance.h"
#include "nsSVGUtils.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEGaussianBlur)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEGaussianBlurElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEGaussianBlurElementBinding::Wrap(aCx, aScope, this);
}
@@ -56,298 +58,38 @@ SVGFEGaussianBlurElement::StdDeviationY(
}
void
SVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviationY)
{
mNumberPairAttributes[STD_DEV].SetBaseValues(stdDeviationX, stdDeviationY, this);
}
-/**
- * We want to speed up 1/N integer divisions --- integer division is
- * often rather slow.
- * We know that our input numerators V are constrained to be <= 255*N,
- * so the result of dividing by N always fits in 8 bits.
- * So we can try approximating the division V/N as V*K/(2^24) (integer
- * division, 32-bit multiply). Dividing by 2^24 is a simple shift so it's
- * fast. The main problem is choosing a value for K; this function returns
- * K's value.
- *
- * If the result is correct for the extrema, V=0 and V=255*N, then we'll
- * be in good shape since both the original function and our approximation
- * are linear. V=0 always gives 0 in both cases, no problem there.
- * For V=255*N, let's choose the largest K that doesn't cause overflow
- * and ensure that it gives the right answer. The constraints are
- * (1) 255*N*K < 2^32
- * and (2) 255*N*K >= 255*(2^24)
- *
- * From (1) we find the best value of K is floor((2^32 - 1)/(255*N)).
- * (2) tells us when this will be valid:
- * N*floor((2^32 - 1)/(255*N)) >= 2^24
- * Now, floor(X) > X - 1, so (2) holds if
- * N*((2^32 - 1)/(255*N) - 1) >= 2^24
- * (2^32 - 1)/255 - 2^24 >= N
- * N <= 65793
- *
- * If all that math confuses you, this should convince you:
- * > perl -e 'for($N=1;(255*$N*int(0xFFFFFFFF/(255*$N)))>>24==255;++$N){}print"$N\n"'
- * 66052
- *
- * So this is fine for all reasonable values of N. For larger values of N
- * we may as well just use the same approximation and accept the fact that
- * the output channel values will be a little low.
- */
-static uint32_t ComputeScaledDivisor(uint32_t aDivisor)
+static const float kMaxStdDeviation = 500;
+
+FilterPrimitiveDescription
+SVGFEGaussianBlurElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- return UINT32_MAX/(255*aDivisor);
-}
-
-static void
-BoxBlur(const uint8_t *aInput, uint8_t *aOutput,
- int32_t aStrideMinor, int32_t aStartMinor, int32_t aEndMinor,
- int32_t aLeftLobe, int32_t aRightLobe, bool aAlphaOnly)
-{
- int32_t boxSize = aLeftLobe + aRightLobe + 1;
- uint32_t scaledDivisor = ComputeScaledDivisor(boxSize);
- uint32_t sums[4] = {0, 0, 0, 0};
-
- for (int32_t i=0; i < boxSize; i++) {
- int32_t pos = aStartMinor - aLeftLobe + i;
- pos = std::max(pos, aStartMinor);
- pos = std::min(pos, aEndMinor - 1);
-#define SUM(j) sums[j] += aInput[aStrideMinor*pos + j];
- SUM(0); SUM(1); SUM(2); SUM(3);
-#undef SUM
+ float stdX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
+ &mNumberPairAttributes[STD_DEV],
+ nsSVGNumberPair::eFirst);
+ float stdY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
+ &mNumberPairAttributes[STD_DEV],
+ nsSVGNumberPair::eSecond);
+ if (stdX < 0 || stdY < 0) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
- aOutput += aStrideMinor*aStartMinor;
- if (aStartMinor + boxSize <= aEndMinor) {
- const uint8_t *lastInput = aInput + aStartMinor*aStrideMinor;
- const uint8_t *nextInput = aInput + (aStartMinor + aRightLobe + 1)*aStrideMinor;
-#define OUTPUT(j) aOutput[j] = (sums[j]*scaledDivisor) >> 24;
-#define SUM(j) sums[j] += nextInput[j] - lastInput[j];
- // process pixels in B, G, R, A order because that's 0, 1, 2, 3 for x86
-#define OUTPUT_PIXEL() \
- if (!aAlphaOnly) { OUTPUT(GFX_ARGB32_OFFSET_B); \
- OUTPUT(GFX_ARGB32_OFFSET_G); \
- OUTPUT(GFX_ARGB32_OFFSET_R); } \
- OUTPUT(GFX_ARGB32_OFFSET_A);
-#define SUM_PIXEL() \
- if (!aAlphaOnly) { SUM(GFX_ARGB32_OFFSET_B); \
- SUM(GFX_ARGB32_OFFSET_G); \
- SUM(GFX_ARGB32_OFFSET_R); } \
- SUM(GFX_ARGB32_OFFSET_A);
- for (int32_t minor = aStartMinor;
- minor < aStartMinor + aLeftLobe;
- minor++) {
- OUTPUT_PIXEL();
- SUM_PIXEL();
- nextInput += aStrideMinor;
- aOutput += aStrideMinor;
- }
- for (int32_t minor = aStartMinor + aLeftLobe;
- minor < aEndMinor - aRightLobe - 1;
- minor++) {
- OUTPUT_PIXEL();
- SUM_PIXEL();
- lastInput += aStrideMinor;
- nextInput += aStrideMinor;
- aOutput += aStrideMinor;
- }
- // nextInput is now aInput + aEndMinor*aStrideMinor. Set it back to
- // aInput + (aEndMinor - 1)*aStrideMinor so we read the last pixel in every
- // iteration of the next loop.
- nextInput -= aStrideMinor;
- for (int32_t minor = aEndMinor - aRightLobe - 1; minor < aEndMinor; minor++) {
- OUTPUT_PIXEL();
- SUM_PIXEL();
- lastInput += aStrideMinor;
- aOutput += aStrideMinor;
-#undef SUM_PIXEL
-#undef SUM
- }
- } else {
- for (int32_t minor = aStartMinor; minor < aEndMinor; minor++) {
- int32_t tmp = minor - aLeftLobe;
- int32_t last = std::max(tmp, aStartMinor);
- int32_t next = std::min(tmp + int32_t(boxSize), aEndMinor - 1);
-
- OUTPUT_PIXEL();
-#define SUM(j) sums[j] += aInput[aStrideMinor*next + j] - \
- aInput[aStrideMinor*last + j];
- if (!aAlphaOnly) { SUM(GFX_ARGB32_OFFSET_B);
- SUM(GFX_ARGB32_OFFSET_G);
- SUM(GFX_ARGB32_OFFSET_R); }
- SUM(GFX_ARGB32_OFFSET_A);
- aOutput += aStrideMinor;
-#undef SUM
-#undef OUTPUT_PIXEL
-#undef OUTPUT
- }
- }
-}
-
-static uint32_t
-GetBlurBoxSize(double aStdDev)
-{
- NS_ASSERTION(aStdDev >= 0, "Negative standard deviations not allowed");
-
- double size = aStdDev*3*sqrt(2*M_PI)/4;
- // Doing super-large blurs accurately isn't very important.
- uint32_t max = 1024;
- if (size > max)
- return max;
- return uint32_t(floor(size + 0.5));
-}
-
-nsresult
-SVGFEGaussianBlurElement::GetDXY(uint32_t *aDX, uint32_t *aDY,
- const nsSVGFilterInstance& aInstance)
-{
- float stdX = aInstance.GetPrimitiveNumber(SVGContentUtils::X,
- &mNumberPairAttributes[STD_DEV],
- nsSVGNumberPair::eFirst);
- float stdY = aInstance.GetPrimitiveNumber(SVGContentUtils::Y,
- &mNumberPairAttributes[STD_DEV],
- nsSVGNumberPair::eSecond);
- if (stdX < 0 || stdY < 0)
- return NS_ERROR_FAILURE;
-
- // If the box size is greater than twice the temporary surface size
- // in an axis, then each pixel will be set to the average of all the
- // other pixel values.
- *aDX = GetBlurBoxSize(stdX);
- *aDY = GetBlurBoxSize(stdY);
- return NS_OK;
-}
-
-static bool
-AreAllColorChannelsZero(const nsSVGFE::Image* aTarget)
-{
- return aTarget->mConstantColorChannels &&
- aTarget->mImage->GetDataSize() >= 4 &&
- (*reinterpret_cast<uint32_t*>(aTarget->mImage->Data()) & 0x00FFFFFF) == 0;
-}
-
-void
-SVGFEGaussianBlurElement::GaussianBlur(const Image* aSource,
- const Image* aTarget,
- const nsIntRect& aDataRect,
- uint32_t aDX, uint32_t aDY)
-{
- NS_ASSERTION(nsIntRect(0, 0, aTarget->mImage->Width(), aTarget->mImage->Height()).Contains(aDataRect),
- "aDataRect out of bounds");
-
- const fallible_t fallible = fallible_t();
- nsAutoArrayPtr<uint8_t> tmp(new (fallible) uint8_t[aTarget->mImage->GetDataSize()]);
- if (!tmp)
- return;
- memset(tmp, 0, aTarget->mImage->GetDataSize());
-
- bool alphaOnly = AreAllColorChannelsZero(aTarget);
-
- const uint8_t* sourceData = aSource->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- if (aDX == 0) {
- CopyDataRect(tmp, sourceData, stride, aDataRect);
- } else {
- int32_t longLobe = aDX/2;
- int32_t shortLobe = (aDX & 1) ? longLobe : longLobe - 1;
- for (int32_t major = aDataRect.y; major < aDataRect.YMost(); ++major) {
- int32_t ms = major*stride;
- BoxBlur(sourceData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, shortLobe, alphaOnly);
- BoxBlur(tmp + ms, targetData + ms, 4, aDataRect.x, aDataRect.XMost(), shortLobe, longLobe, alphaOnly);
- BoxBlur(targetData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, longLobe, alphaOnly);
- }
- }
-
- if (aDY == 0) {
- CopyDataRect(targetData, tmp, stride, aDataRect);
- } else {
- int32_t longLobe = aDY/2;
- int32_t shortLobe = (aDY & 1) ? longLobe : longLobe - 1;
- for (int32_t major = aDataRect.x; major < aDataRect.XMost(); ++major) {
- int32_t ms = major*4;
- BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, shortLobe, alphaOnly);
- BoxBlur(targetData + ms, tmp + ms, stride, aDataRect.y, aDataRect.YMost(), shortLobe, longLobe, alphaOnly);
- BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, longLobe, alphaOnly);
- }
- }
-}
-
-static void
-InflateRectForBlurDXY(nsIntRect* aRect, uint32_t aDX, uint32_t aDY)
-{
- aRect->Inflate(3*(aDX/2), 3*(aDY/2));
-}
-
-static void
-ClearRect(gfxImageSurface* aSurface, int32_t aX, int32_t aY,
- int32_t aXMost, int32_t aYMost)
-{
- NS_ASSERTION(aX <= aXMost && aY <= aYMost, "Invalid rectangle");
- NS_ASSERTION(aX >= 0 && aY >= 0 && aXMost <= aSurface->Width() && aYMost <= aSurface->Height(),
- "Rectangle out of bounds");
-
- if (aX == aXMost || aY == aYMost)
- return;
- for (int32_t y = aY; y < aYMost; ++y) {
- memset(aSurface->Data() + aSurface->Stride()*y + aX*4, 0, (aXMost - aX)*4);
- }
-}
-
-// Clip aTarget's image to its filter primitive subregion.
-// aModifiedRect contains all the pixels which might not be RGBA(0,0,0,0),
-// it's relative to the surface data.
-static void
-ClipTarget(nsSVGFilterInstance* aInstance, const nsSVGFE::Image* aTarget,
- const nsIntRect& aModifiedRect)
-{
- nsIntPoint surfaceTopLeft = aInstance->GetSurfaceRect().TopLeft();
-
- NS_ASSERTION(aInstance->GetSurfaceRect().Contains(aModifiedRect + surfaceTopLeft),
- "Modified data area overflows the surface?");
-
- nsIntRect clip = aModifiedRect;
- nsSVGUtils::ClipToGfxRect(&clip,
- aTarget->mFilterPrimitiveSubregion - gfxPoint(surfaceTopLeft.x, surfaceTopLeft.y));
-
- ClearRect(aTarget->mImage, aModifiedRect.x, aModifiedRect.y, aModifiedRect.XMost(), clip.y);
- ClearRect(aTarget->mImage, aModifiedRect.x, clip.y, clip.x, clip.YMost());
- ClearRect(aTarget->mImage, clip.XMost(), clip.y, aModifiedRect.XMost(), clip.YMost());
- ClearRect(aTarget->mImage, aModifiedRect.x, clip.YMost(), aModifiedRect.XMost(), aModifiedRect.YMost());
-}
-
-static void
-ClipComputationRectToSurface(nsSVGFilterInstance* aInstance,
- nsIntRect* aDataRect)
-{
- aDataRect->IntersectRect(*aDataRect,
- nsIntRect(nsIntPoint(0, 0), aInstance->GetSurfaceRect().Size()));
-}
-
-nsresult
-SVGFEGaussianBlurElement::Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
-{
- uint32_t dx, dy;
- nsresult rv = GetDXY(&dx, &dy, *aInstance);
- if (NS_FAILED(rv))
- return rv;
-
- nsIntRect computationRect = rect;
- InflateRectForBlurDXY(&computationRect, dx, dy);
- ClipComputationRectToSurface(aInstance, &computationRect);
- GaussianBlur(aSources[0], aTarget, computationRect, dx, dy);
- ClipTarget(aInstance, aTarget, computationRect);
- return NS_OK;
+ stdX = std::min(stdX, kMaxStdDeviation);
+ stdY = std::min(stdY, kMaxStdDeviation);
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eGaussianBlur);
+ descr.Attributes().Set(eGaussianBlurStdDeviation, Size(stdX, stdY));
+ return descr;
}
bool
SVGFEGaussianBlurElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEGaussianBlurElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
@@ -356,50 +98,16 @@ SVGFEGaussianBlurElement::AttributeAffec
}
void
SVGFEGaussianBlurElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsIntRect
-SVGFEGaussianBlurElement::InflateRectForBlur(const nsIntRect& aRect,
- const nsSVGFilterInstance& aInstance)
-{
- uint32_t dX, dY;
- nsresult rv = GetDXY(&dX, &dY, aInstance);
- nsIntRect result = aRect;
- if (NS_SUCCEEDED(rv)) {
- InflateRectForBlurDXY(&result, dX, dY);
- }
- return result;
-}
-
-nsIntRect
-SVGFEGaussianBlurElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return InflateRectForBlur(aSourceBBoxes[0], aInstance);
-}
-
-void
-SVGFEGaussianBlurElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- aSourceBBoxes[0] = InflateRectForBlur(aTargetBBox, aInstance);
-}
-
-nsIntRect
-SVGFEGaussianBlurElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return InflateRectForBlur(aSourceChangeBoxes[0], aInstance);
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberPairAttributesInfo
SVGFEGaussianBlurElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
ArrayLength(sNumberPairInfo));
--- a/content/svg/content/src/SVGFEGaussianBlurElement.h
+++ b/content/svg/content/src/SVGFEGaussianBlurElement.h
@@ -26,31 +26,24 @@ protected:
SVGFEGaussianBlurElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEGaussianBlurElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo >& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
-
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedNumber> StdDeviationX();
already_AddRefed<SVGAnimatedNumber> StdDeviationY();
void SetStdDeviation(float stdDeviationX, float stdDeviationY);
@@ -61,22 +54,14 @@ protected:
enum { STD_DEV };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
-
-private:
- nsresult GetDXY(uint32_t *aDX, uint32_t *aDY, const nsSVGFilterInstance& aInstance);
- nsIntRect InflateRectForBlur(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
-
- void GaussianBlur(const Image *aSource, const Image *aTarget,
- const nsIntRect& aDataRect,
- uint32_t aDX, uint32_t aDY);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGFEGaussianBlurElement_h
--- a/content/svg/content/src/SVGFEImageElement.cpp
+++ b/content/svg/content/src/SVGFEImageElement.cpp
@@ -7,19 +7,22 @@
#include "mozilla/dom/SVGFEImageElementBinding.h"
#include "mozilla/dom/SVGFilterElement.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
#include "nsNetUtil.h"
#include "imgIContainer.h"
+#include "gfx2DGlue.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEImage)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEImageElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEImageElementBinding::Wrap(aCx, aScope, this);
}
@@ -182,91 +185,82 @@ already_AddRefed<SVGAnimatedString>
SVGFEImageElement::Href()
{
return mStringAttributes[HREF].ToDOMAnimatedString(this);
}
//----------------------------------------------------------------------
// nsIDOMSVGFEImageElement methods
-nsresult
-SVGFEImageElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
nsIFrame* frame = GetPrimaryFrame();
- if (!frame) return NS_ERROR_FAILURE;
+ if (!frame) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
+ }
nsCOMPtr<imgIRequest> currentRequest;
GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(currentRequest));
nsCOMPtr<imgIContainer> imageContainer;
- if (currentRequest)
+ if (currentRequest) {
currentRequest->GetImage(getter_AddRefs(imageContainer));
+ }
nsRefPtr<gfxASurface> currentFrame;
- if (imageContainer)
+ if (imageContainer) {
imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(currentFrame));
-
- // We need to wrap the surface in a pattern to have somewhere to set the
- // graphics filter.
- nsRefPtr<gfxPattern> thebesPattern;
- if (currentFrame)
- thebesPattern = new gfxPattern(currentFrame);
-
- if (thebesPattern) {
- thebesPattern->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
-
- int32_t nativeWidth, nativeHeight;
- imageContainer->GetWidth(&nativeWidth);
- imageContainer->GetHeight(&nativeHeight);
+ }
- const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
-
- gfxMatrix viewBoxTM =
- SVGContentUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
- 0,0, nativeWidth, nativeHeight,
- mPreserveAspectRatio);
-
- gfxMatrix xyTM = gfxMatrix().Translate(gfxPoint(filterSubregion.X(), filterSubregion.Y()));
-
- gfxMatrix TM = viewBoxTM * xyTM;
-
- nsRefPtr<gfxContext> ctx = new gfxContext(aTarget->mImage);
- nsSVGUtils::CompositePatternMatrix(ctx, thebesPattern, TM, nativeWidth, nativeHeight, 1.0);
+ if (!currentFrame) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
- return NS_OK;
+ IntSize nativeSize;
+ imageContainer->GetWidth(&nativeSize.width);
+ imageContainer->GetHeight(&nativeSize.height);
+
+ gfxMatrix viewBoxTM =
+ SVGContentUtils::GetViewBoxTransform(aFilterSubregion.width, aFilterSubregion.height,
+ 0, 0, nativeSize.width, nativeSize.height,
+ mPreserveAspectRatio);
+ Matrix xyTM = Matrix().Translate(aFilterSubregion.x, aFilterSubregion.y);
+ Matrix TM = ToMatrix(viewBoxTM) * xyTM;
+
+ Filter filter = ToFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
+
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eImage);
+ descr.Attributes().Set(eImageFilter, (uint32_t)filter);
+ descr.Attributes().Set(eImageTransform, TM);
+
+ // Append the image to aInputImages and store its index in the description.
+ size_t imageIndex = aInputImages.Length();
+ aInputImages.AppendElement(currentFrame);
+ descr.Attributes().Set(eImageInputIndex, (uint32_t)imageIndex);
+
+ return descr;
}
bool
SVGFEImageElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
// nsGkAtoms::href is deliberately omitted as the frame has special
// handling to load the image
return SVGFEImageElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::preserveAspectRatio);
}
-nsIntRect
-SVGFEImageElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX can do better here ... we could check what we know of the source
- // image bounds and compute an accurate bounding box for the filter
- // primitive result.
- return GetMaxRect();
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
SVGFEImageElement::PreserveAspectRatio()
{
nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
--- a/content/svg/content/src/SVGFEImageElement.h
+++ b/content/svg/content/src/SVGFEImageElement.h
@@ -2,16 +2,17 @@
/* 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_SVGFEImageElement_h
#define mozilla_dom_SVGFEImageElement_h
#include "nsSVGFilters.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
class SVGFEImageFrame;
nsresult NS_NewSVGFEImageElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
@@ -32,25 +33,23 @@ protected:
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
// nsIContent
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
@@ -70,18 +69,17 @@ public:
private:
// Invalidate users of the filter containing this element.
void Invalidate();
nsresult LoadSVGImage(bool aForce, bool aNotify);
protected:
- virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
- int32_t, Image*) MOZ_OVERRIDE { return true; }
+ virtual bool ProducesSRGB() MOZ_OVERRIDE { return true; }
virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { RESULT, HREF };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
--- a/content/svg/content/src/SVGFEMergeElement.cpp
+++ b/content/svg/content/src/SVGFEMergeElement.cpp
@@ -1,50 +1,43 @@
/* -*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFEMergeElement.h"
#include "mozilla/dom/SVGFEMergeElementBinding.h"
#include "mozilla/dom/SVGFEMergeNodeElement.h"
-#include "gfxContext.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEMerge)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEMergeElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEMergeElementBinding::Wrap(aCx, aScope, this);
}
nsSVGElement::StringInfo SVGFEMergeElement::sStringInfo[1] =
{
{ &nsGkAtoms::result, kNameSpaceID_None, true }
};
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEMergeElement)
-nsresult
-SVGFEMergeElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEMergeElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- gfxContext ctx(aTarget->mImage);
- ctx.Clip(aTarget->mFilterPrimitiveSubregion);
-
- for (uint32_t i = 0; i < aSources.Length(); i++) {
- ctx.SetSource(aSources[i]->mImage);
- ctx.Paint();
- }
- return NS_OK;
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eMerge);
}
void
SVGFEMergeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
for (nsIContent* child = nsINode::GetFirstChild();
child;
child = child->GetNextSibling()) {
--- a/content/svg/content/src/SVGFEMergeElement.h
+++ b/content/svg/content/src/SVGFEMergeElement.h
@@ -24,20 +24,20 @@ protected:
SVGFEMergeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEMergeElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
// nsIContent
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
protected:
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGFEMorphologyElement.cpp
+++ b/content/svg/content/src/SVGFEMorphologyElement.cpp
@@ -4,29 +4,27 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEMorphologyElement.h"
#include "mozilla/dom/SVGFEMorphologyElementBinding.h"
#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEMorphology)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEMorphologyElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEMorphologyElementBinding::Wrap(aCx, aScope, this);
}
-// Morphology Operators
-static const unsigned short SVG_OPERATOR_ERODE = 1;
-static const unsigned short SVG_OPERATOR_DILATE = 2;
-
nsSVGElement::NumberPairInfo SVGFEMorphologyElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::radius, 0, 0 }
};
nsSVGEnumMapping SVGFEMorphologyElement::sOperatorMap[] = {
{&nsGkAtoms::erode, SVG_OPERATOR_ERODE},
{&nsGkAtoms::dilate, SVG_OPERATOR_DILATE},
@@ -88,48 +86,16 @@ SVGFEMorphologyElement::SetRadius(float
}
void
SVGFEMorphologyElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsIntRect
-SVGFEMorphologyElement::InflateRect(const nsIntRect& aRect,
- const nsSVGFilterInstance& aInstance)
-{
- int32_t rx, ry;
- GetRXY(&rx, &ry, aInstance);
- nsIntRect result = aRect;
- result.Inflate(std::max(0, rx), std::max(0, ry));
- return result;
-}
-
-nsIntRect
-SVGFEMorphologyElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return InflateRect(aSourceBBoxes[0], aInstance);
-}
-
-void
-SVGFEMorphologyElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- aSourceBBoxes[0] = InflateRect(aTargetBBox, aInstance);
-}
-
-nsIntRect
-SVGFEMorphologyElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return InflateRect(aSourceChangeBoxes[0], aInstance);
-}
-
#define MORPHOLOGY_EPSILON 0.0001
void
SVGFEMorphologyElement::GetRXY(int32_t *aRX, int32_t *aRY,
const nsSVGFilterInstance& aInstance)
{
// Subtract an epsilon here because we don't want a value that's just
// slightly larger than an integer to round up to the next integer; it's
@@ -140,101 +106,28 @@ SVGFEMorphologyElement::GetRXY(int32_t *
nsSVGNumberPair::eFirst) -
MORPHOLOGY_EPSILON);
*aRY = NSToIntCeil(aInstance.GetPrimitiveNumber(SVGContentUtils::Y,
&mNumberPairAttributes[RADIUS],
nsSVGNumberPair::eSecond) -
MORPHOLOGY_EPSILON);
}
-template<uint32_t Operator>
-static void
-DoMorphology(nsSVGFilterInstance* instance,
- uint8_t* sourceData,
- uint8_t* targetData,
- int32_t stride,
- const nsIntRect& rect,
- int32_t rx,
- int32_t ry)
-{
- static_assert(Operator == SVG_OPERATOR_ERODE ||
- Operator == SVG_OPERATOR_DILATE,
- "unexpected morphology operator");
-
- volatile uint8_t extrema[4]; // RGBA magnitude of extrema
-
- // Scan the kernel for each pixel to determine max/min RGBA values.
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- int32_t startY = std::max(0, y - ry);
- // We need to read pixels not just in 'rect', which is limited to
- // the dirty part of our filter primitive subregion, but all pixels in
- // the given radii from the source surface, so use the surface size here.
- int32_t endY = std::min(y + ry, instance->GetSurfaceHeight() - 1);
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- int32_t startX = std::max(0, x - rx);
- int32_t endX = std::min(x + rx, instance->GetSurfaceWidth() - 1);
- int32_t targIndex = y * stride + 4 * x;
-
- for (int32_t i = 0; i < 4; i++) {
- extrema[i] = sourceData[targIndex + i];
- }
- for (int32_t y1 = startY; y1 <= endY; y1++) {
- for (int32_t x1 = startX; x1 <= endX; x1++) {
- for (int32_t i = 0; i < 4; i++) {
- uint8_t pixel = sourceData[y1 * stride + 4 * x1 + i];
- if (Operator == SVG_OPERATOR_ERODE) {
- extrema[i] -= (extrema[i] - pixel) & -(extrema[i] > pixel);
- } else {
- extrema[i] -= (extrema[i] - pixel) & -(extrema[i] < pixel);
- }
- }
- }
- }
- targetData[targIndex ] = extrema[0];
- targetData[targIndex+1] = extrema[1];
- targetData[targIndex+2] = extrema[2];
- targetData[targIndex+3] = extrema[3];
- }
- }
-}
-
-nsresult
-SVGFEMorphologyElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEMorphologyElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
int32_t rx, ry;
- GetRXY(&rx, &ry, *instance);
-
- if (rx < 0 || ry < 0) {
- // XXX SVGContentUtils::ReportToConsole()
- return NS_OK;
- }
- if (rx == 0 && ry == 0) {
- return NS_OK;
- }
-
- // Clamp radii to prevent completely insane values:
- rx = std::min(rx, 100000);
- ry = std::min(ry, 100000);
-
- uint8_t* sourceData = aSources[0]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- int32_t stride = aTarget->mImage->Stride();
-
- if (mEnumAttributes[OPERATOR].GetAnimValue() == SVG_OPERATOR_ERODE) {
- DoMorphology<SVG_OPERATOR_ERODE>(instance, sourceData, targetData, stride,
- rect, rx, ry);
- } else {
- DoMorphology<SVG_OPERATOR_DILATE>(instance, sourceData, targetData, stride,
- rect, rx, ry);
- }
-
- return NS_OK;
+ GetRXY(&rx, &ry, *aInstance);
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eMorphology);
+ descr.Attributes().Set(eMorphologyRadii, Size(rx, ry));
+ descr.Attributes().Set(eMorphologyOperator,
+ (uint32_t)mEnumAttributes[OPERATOR].GetAnimValue());
+ return descr;
}
bool
SVGFEMorphologyElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEMorphologyElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/SVGFEMorphologyElement.h
+++ b/content/svg/content/src/SVGFEMorphologyElement.h
@@ -27,43 +27,36 @@ protected:
SVGFEMorphologyElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEMorphologyElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedEnumeration> Operator();
already_AddRefed<SVGAnimatedNumber> RadiusX();
already_AddRefed<SVGAnimatedNumber> RadiusY();
void SetRadius(float rx, float ry);
protected:
void GetRXY(int32_t *aRX, int32_t *aRY, const nsSVGFilterInstance& aInstance);
- nsIntRect InflateRect(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { RADIUS };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
--- a/content/svg/content/src/SVGFEOffsetElement.cpp
+++ b/content/svg/content/src/SVGFEOffsetElement.cpp
@@ -5,16 +5,18 @@
#include "mozilla/dom/SVGFEOffsetElement.h"
#include "mozilla/dom/SVGFEOffsetElementBinding.h"
#include "nsSVGFilterInstance.h"
#include "gfxContext.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEOffset)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEOffsetElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEOffsetElementBinding::Wrap(aCx, aScope, this);
}
@@ -62,33 +64,25 @@ nsIntPoint
SVGFEOffsetElement::GetOffset(const nsSVGFilterInstance& aInstance)
{
return nsIntPoint(int32_t(aInstance.GetPrimitiveNumber(
SVGContentUtils::X, &mNumberAttributes[DX])),
int32_t(aInstance.GetPrimitiveNumber(
SVGContentUtils::Y, &mNumberAttributes[DY])));
}
-nsresult
-SVGFEOffsetElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFEOffsetElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- nsIntPoint offset = GetOffset(*instance);
-
- gfxContext ctx(aTarget->mImage);
- ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
- // Ensure rendering is limited to the filter primitive subregion
- ctx.Clip(aTarget->mFilterPrimitiveSubregion);
- ctx.Translate(gfxPoint(offset.x, offset.y));
- ctx.SetSource(aSources[0]->mImage);
- ctx.Paint();
-
- return NS_OK;
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eOffset);
+ nsIntPoint offset = GetOffset(*aInstance);
+ descr.Attributes().Set(eOffsetOffset, IntPoint(offset.x, offset.y));
+ return descr;
}
bool
SVGFEOffsetElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEOffsetElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
@@ -98,37 +92,16 @@ SVGFEOffsetElement::AttributeAffectsRend
}
void
SVGFEOffsetElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsIntRect
-SVGFEOffsetElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return aSourceBBoxes[0] + GetOffset(aInstance);
-}
-
-nsIntRect
-SVGFEOffsetElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return aSourceChangeBoxes[0] + GetOffset(aInstance);
-}
-
-void
-SVGFEOffsetElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- aSourceBBoxes[0] = aTargetBBox - GetOffset(aInstance);
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
SVGFEOffsetElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
ArrayLength(sNumberInfo));
--- a/content/svg/content/src/SVGFEOffsetElement.h
+++ b/content/svg/content/src/SVGFEOffsetElement.h
@@ -26,30 +26,24 @@ protected:
SVGFEOffsetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEOffsetElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedNumber> Dx();
already_AddRefed<SVGAnimatedNumber> Dy();
--- a/content/svg/content/src/SVGFEPointLightElement.cpp
+++ b/content/svg/content/src/SVGFEPointLightElement.cpp
@@ -1,18 +1,21 @@
/* -*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFEPointLightElement.h"
#include "mozilla/dom/SVGFEPointLightElementBinding.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEPointLight)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFEPointLightElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEPointLightElementBinding::Wrap(aCx, aScope, this);
}
@@ -39,16 +42,28 @@ SVGFEPointLightElement::AttributeAffects
return aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::z);
}
//----------------------------------------------------------------------
+AttributeMap
+SVGFEPointLightElement::ComputeLightAttributes(nsSVGFilterInstance* aInstance)
+{
+ Point3D lightPos;
+ GetAnimatedNumberValues(&lightPos.x, &lightPos.y, &lightPos.z, nullptr);
+
+ AttributeMap map;
+ map.Set(eLightType, (uint32_t)eLightTypePoint);
+ map.Set(ePointLightPosition, aInstance->ConvertLocation(lightPos));
+ return map;
+}
+
already_AddRefed<SVGAnimatedNumber>
SVGFEPointLightElement::X()
{
return mNumberAttributes[ATTR_X].ToDOMAnimatedNumber(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEPointLightElement::Y()
--- a/content/svg/content/src/SVGFEPointLightElement.h
+++ b/content/svg/content/src/SVGFEPointLightElement.h
@@ -4,37 +4,38 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGFEPointLightElement_h
#define mozilla_dom_SVGFEPointLightElement_h
#include "nsSVGFilters.h"
#include "nsSVGNumber2.h"
-typedef SVGFEUnstyledElement SVGFEPointLightElementBase;
-
nsresult NS_NewSVGFEPointLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
+typedef SVGFELightElement SVGFEPointLightElementBase;
+
class SVGFEPointLightElement : public SVGFEPointLightElementBase
{
friend nsresult (::NS_NewSVGFEPointLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFEPointLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEPointLightElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
public:
+ virtual AttributeMap ComputeLightAttributes(nsSVGFilterInstance* aInstance) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedNumber> X();
already_AddRefed<SVGAnimatedNumber> Y();
--- a/content/svg/content/src/SVGFESpecularLightingElement.cpp
+++ b/content/svg/content/src/SVGFESpecularLightingElement.cpp
@@ -1,19 +1,22 @@
/* a*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFESpecularLightingElement.h"
#include "mozilla/dom/SVGFESpecularLightingElementBinding.h"
#include "nsSVGUtils.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FESpecularLighting)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFESpecularLightingElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFESpecularLightingElementBinding::Wrap(aCx, aScope, this);
}
@@ -59,68 +62,39 @@ SVGFESpecularLightingElement::KernelUnit
{
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
nsSVGNumberPair::eSecond, this);
}
//----------------------------------------------------------------------
// nsSVGElement methods
-nsresult
-SVGFESpecularLightingElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFESpecularLightingElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
float specularExponent = mNumberAttributes[SPECULAR_EXPONENT].GetAnimValue();
+ float specularConstant = mNumberAttributes[SPECULAR_CONSTANT].GetAnimValue();
// specification defined range (15.22)
- if (specularExponent < 1 || specularExponent > 128)
- return NS_ERROR_FAILURE;
+ if (specularExponent < 1 || specularExponent > 128) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
+ }
- return SVGFESpecularLightingElementBase::Filter(instance, aSources, aTarget, rect);
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eSpecularLighting);
+ descr.Attributes().Set(eSpecularLightingSpecularConstant, specularConstant);
+ descr.Attributes().Set(eSpecularLightingSpecularExponent, specularExponent);
+ return AddLightingAttributes(descr, aInstance);
}
bool
SVGFESpecularLightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFESpecularLightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::specularConstant ||
aAttribute == nsGkAtoms::specularExponent));
}
-void
-SVGFESpecularLightingElement::LightPixel(const float *N, const float *L,
- nscolor color, uint8_t *targetData)
-{
- float H[3];
- H[0] = L[0];
- H[1] = L[1];
- H[2] = L[2] + 1;
- NORMALIZE(H);
-
- float kS = mNumberAttributes[SPECULAR_CONSTANT].GetAnimValue();
- float dotNH = DOT(N, H);
-
- bool invalid = dotNH <= 0 || kS <= 0;
- kS *= invalid ? 0 : 1;
- uint8_t minAlpha = invalid ? 255 : 0;
-
- float specularNH =
- kS * pow(dotNH, mNumberAttributes[SPECULAR_EXPONENT].GetAnimValue());
-
- targetData[GFX_ARGB32_OFFSET_B] =
- std::min(uint32_t(specularNH * NS_GET_B(color)), 255U);
- targetData[GFX_ARGB32_OFFSET_G] =
- std::min(uint32_t(specularNH * NS_GET_G(color)), 255U);
- targetData[GFX_ARGB32_OFFSET_R] =
- std::min(uint32_t(specularNH * NS_GET_R(color)), 255U);
-
- targetData[GFX_ARGB32_OFFSET_A] =
- std::max(minAlpha, std::max(targetData[GFX_ARGB32_OFFSET_B],
- std::max(targetData[GFX_ARGB32_OFFSET_G],
- targetData[GFX_ARGB32_OFFSET_R])));
-}
-
} // namespace dom
} // namespace mozilla
--- a/content/svg/content/src/SVGFESpecularLightingElement.h
+++ b/content/svg/content/src/SVGFESpecularLightingElement.h
@@ -28,33 +28,28 @@ protected:
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect);
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedNumber> SurfaceScale();
already_AddRefed<SVGAnimatedNumber> SpecularConstant();
already_AddRefed<SVGAnimatedNumber> SpecularExponent();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthX();
already_AddRefed<SVGAnimatedNumber> KernelUnitLengthY();
-
-protected:
- virtual void LightPixel(const float *N, const float *L,
- nscolor color, uint8_t *targetData);
-
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGFESpecularLightingElement_h
--- a/content/svg/content/src/SVGFESpotLightElement.cpp
+++ b/content/svg/content/src/SVGFESpotLightElement.cpp
@@ -1,18 +1,21 @@
/* a*- Mode: C++; 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/. */
#include "mozilla/dom/SVGFESpotLightElement.h"
#include "mozilla/dom/SVGFESpotLightElementBinding.h"
+#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FESpotLight)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFESpotLightElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFESpotLightElementBinding::Wrap(aCx, aScope, this);
}
@@ -49,16 +52,38 @@ SVGFESpotLightElement::AttributeAffectsR
aAttribute == nsGkAtoms::pointsAtY ||
aAttribute == nsGkAtoms::pointsAtZ ||
aAttribute == nsGkAtoms::specularExponent ||
aAttribute == nsGkAtoms::limitingConeAngle);
}
//----------------------------------------------------------------------
+AttributeMap
+SVGFESpotLightElement::ComputeLightAttributes(nsSVGFilterInstance* aInstance)
+{
+ Point3D lightPos, pointsAt;
+ float specularExponent, limitingConeAngle;
+ GetAnimatedNumberValues(&lightPos.x, &lightPos.y, &lightPos.z,
+ &pointsAt.x, &pointsAt.y, &pointsAt.z,
+ &specularExponent, &limitingConeAngle,
+ nullptr);
+ if (!mNumberAttributes[SVGFESpotLightElement::LIMITING_CONE_ANGLE].IsExplicitlySet()) {
+ limitingConeAngle = 90;
+ }
+
+ AttributeMap map;
+ map.Set(eLightType, (uint32_t)eLightTypeSpot);
+ map.Set(eSpotLightPosition, aInstance->ConvertLocation(lightPos));
+ map.Set(eSpotLightPointsAt, aInstance->ConvertLocation(pointsAt));
+ map.Set(eSpotLightFocus, specularExponent);
+ map.Set(eSpotLightLimitingConeAngle, limitingConeAngle);
+ return map;
+}
+
already_AddRefed<SVGAnimatedNumber>
SVGFESpotLightElement::X()
{
return mNumberAttributes[ATTR_X].ToDOMAnimatedNumber(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFESpotLightElement::Y()
--- a/content/svg/content/src/SVGFESpotLightElement.h
+++ b/content/svg/content/src/SVGFESpotLightElement.h
@@ -4,40 +4,39 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGFESpotLightElement_h
#define mozilla_dom_SVGFESpotLightElement_h
#include "nsSVGFilters.h"
#include "nsSVGNumber2.h"
-class nsSVGFELightingElement;
-
nsresult NS_NewSVGFESpotLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
-typedef SVGFEUnstyledElement SVGFESpotLightElementBase;
+typedef SVGFELightElement SVGFESpotLightElementBase;
class SVGFESpotLightElement : public SVGFESpotLightElementBase
{
friend nsresult (::NS_NewSVGFESpotLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
friend class ::nsSVGFELightingElement;
protected:
SVGFESpotLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFESpotLightElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
+ virtual AttributeMap ComputeLightAttributes(nsSVGFilterInstance* aInstance) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedNumber> X();
already_AddRefed<SVGAnimatedNumber> Y();
--- a/content/svg/content/src/SVGFETileElement.cpp
+++ b/content/svg/content/src/SVGFETileElement.cpp
@@ -5,16 +5,18 @@
#include "mozilla/dom/SVGFETileElement.h"
#include "mozilla/dom/SVGFETileElementBinding.h"
#include "nsSVGFilterInstance.h"
#include "gfxUtils.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FETile)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
JSObject*
SVGFETileElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return SVGFETileElementBinding::Wrap(aCx, aScope, this);
}
@@ -38,378 +40,25 @@ SVGFETileElement::In1()
}
void
SVGFETileElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-nsIntRect
-SVGFETileElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return GetMaxRect();
-}
-
-void
-SVGFETileElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- // Just assume we need the entire source bounding box, so do nothing.
-}
-
-nsIntRect
-SVGFETileElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return GetMaxRect();
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
-/*
- * This function computes the size of partial match on either side of the tile.
- * eg: If we are talking about the X-axis direction, then it computes, the
- * size of the tile that would be copied to the lesser X-axis side (usually
- * left), the higher X-axis side (usualy right) and the centre.
- * This is needed because often, the tile doesn't exactly align to the target
- * region and is partially copied on the edges. This function computes the
- * dimensions of the partially copied regions in one axis.
- *
- * OUTPUT:
- * aLesserSidePartialMatchSize: The size of the partial match on the lesser
- * side of the axis being considered.
- * eg: for X-axis, usually left side and
- * for Y-axis, usually top
- * aHigherSidePartialMatchSize: The size of the partial match on the higher
- * side of the axis being considered.
- * eg: for X-axis, usually right side and
- * for Y-axis, usually bottom
- * aCentreSize: The size of the target area where the tile is copied in full.
- * This lies between the lesser and higher side partial matches.
- * (the partially matched areas may be of zero width)
- *
- * INPUT:
- * aLesserTargetExtent: Edge of the target area on the axis being considered
- * on the lesser side. (eg: usually left on the X-axis)
- * aTargetSize: Size of the target area on the axis being considered (eg:
- * usually width for X-axis)
- * aLesserTileExtent: Edge of the tile on the axis being considered on the
- * lesser side.
- * aTileSize: Size of the tile on the axis being considered.
- */
-static inline void
-ComputePartialTileExtents(int32_t *aLesserSidePartialMatchSize,
- int32_t *aHigherSidePartialMatchSize,
- int32_t *aCentreSize,
- int32_t aLesserTargetExtent,
- int32_t aTargetSize,
- int32_t aLesserTileExtent,
- int32_t aTileSize)
-{
- int32_t targetExtentMost = aLesserTargetExtent + aTargetSize;
- int32_t tileExtentMost = aLesserTileExtent + aTileSize;
-
- int32_t lesserSidePartialMatchSize;
- if (aLesserTileExtent < aLesserTargetExtent) {
- lesserSidePartialMatchSize = tileExtentMost - aLesserTargetExtent;
- } else {
- lesserSidePartialMatchSize = (aLesserTileExtent - aLesserTargetExtent) %
- aTileSize;
- }
-
- int32_t higherSidePartialMatchSize;
- if (lesserSidePartialMatchSize > aTargetSize) {
- lesserSidePartialMatchSize = aTargetSize;
- higherSidePartialMatchSize = 0;
- } else if (tileExtentMost > targetExtentMost) {
- higherSidePartialMatchSize = targetExtentMost - aLesserTileExtent;
- } else {
- higherSidePartialMatchSize = (targetExtentMost - tileExtentMost) %
- aTileSize;
- }
-
- if (lesserSidePartialMatchSize + higherSidePartialMatchSize >
- aTargetSize) {
- higherSidePartialMatchSize = aTargetSize - lesserSidePartialMatchSize;
- }
-
- /*
- * To understand the conditon below, let us consider the X-Axis:
- * Lesser side is left and the Higher side is right.
- * This implies:
- * aTargetSize is rect.width.
- * lesserSidePartialMatchSize would mean leftPartialTileWidth.
- * higherSidePartialMatchSize would mean rightPartialTileWidth.
- *
- * leftPartialTileWidth == rect.width only happens when the tile entirely
- * overlaps with the target area in the X-axis and exceeds its bounds by at
- * least one pixel on the lower X-Axis side.
- *
- * leftPartialTileWidth + rightPartialTileWidth == rect.width only happens
- * when the tile overlaps the target area in such a way that the edge of the
- * tile on the higher X-Axis side cuts through the target area and there is no
- * space for a complete tile in the X-Axis in the target area on either side
- * of that edge. In this scenario, centre will be of zero width and the
- * partial widths on left and right will add up to the width of the rect. In
- * case the tile is bigger than the rect in the X-axis, it will get clipped
- * and remain equal to rect.width.
- *
- * Therefore, those two conditions are separate cases which lead to centre
- * being of zero width.
- *
- * The condition below is the same logic as above expressed independent of
- * the axis in consideration.
- */
-
- int32_t centreSize;
- if (lesserSidePartialMatchSize == aTargetSize ||
- lesserSidePartialMatchSize + higherSidePartialMatchSize ==
- aTargetSize) {
- centreSize = 0;
- } else {
- centreSize = aTargetSize -
- (lesserSidePartialMatchSize + higherSidePartialMatchSize);
- }
-
- *aLesserSidePartialMatchSize = lesserSidePartialMatchSize;
- *aHigherSidePartialMatchSize = higherSidePartialMatchSize;
- *aCentreSize = centreSize;
-}
-
-static inline void
-TilePixels(uint8_t *aTargetData,
- const uint8_t *aSourceData,
- const nsIntRect &targetRegion,
- const nsIntRect &aTile,
- uint32_t aStride)
-{
- if (targetRegion.IsEmpty()) {
- return;
- }
-
- uint32_t tileRowCopyMemSize = aTile.width * 4;
- uint32_t numTimesToCopyTileRows = targetRegion.width / aTile.width;
-
- uint8_t *targetFirstRowOffset = aTargetData + 4 * targetRegion.x;
- const uint8_t *tileFirstRowOffset = aSourceData + 4 * aTile.x;
-
- int32_t tileYOffset = 0;
- for (int32_t targetY = targetRegion.y;
- targetY < targetRegion.YMost();
- ++targetY) {
- uint8_t *targetRowOffset = targetFirstRowOffset + aStride * targetY;
- const uint8_t *tileRowOffset = tileFirstRowOffset +
- aStride * (aTile.y + tileYOffset);
-
- for (uint32_t i = 0; i < numTimesToCopyTileRows; ++i) {
- memcpy(targetRowOffset + i * tileRowCopyMemSize,
- tileRowOffset,
- tileRowCopyMemSize);
- }
-
- tileYOffset = (tileYOffset + 1) % aTile.height;
- }
-}
-
-nsresult
-SVGFETileElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFETileElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- // XXX This code depends on the surface rect containing the filter
- // primitive subregion. ComputeTargetBBox, ComputeNeededSourceBBoxes
- // and ComputeChangeBBox are all pessimal, so that will normally be OK,
- // but nothing clips mFilterPrimitiveSubregion so this should be changed.
-
- nsIntRect tile;
- bool res = gfxUtils::GfxRectToIntRect(aSources[0]->mFilterPrimitiveSubregion,
- &tile);
-
- NS_ENSURE_TRUE(res, NS_ERROR_FAILURE); // asserts on failure (not
- if (tile.IsEmpty())
- return NS_OK;
-
- const nsIntRect &surfaceRect = instance->GetSurfaceRect();
- if (!tile.Intersects(surfaceRect)) {
- // nothing to draw
- return NS_OK;
- }
-
- // clip tile
- tile = tile.Intersect(surfaceRect);
-
- // Get it into surface space
- tile -= surfaceRect.TopLeft();
-
- uint8_t* sourceData = aSources[0]->mImage->Data();
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- /*
- * priority: left before right before centre
- * and
- * top before bottom before centre
- *
- * eg: If we have a target area which is 1.5 times the width of a tile,
- * then, based on alignment, we get:
- * 'left and right'
- * or
- * 'left and centre'
- *
- */
-
- int32_t leftPartialTileWidth;
- int32_t rightPartialTileWidth;
- int32_t centreWidth;
- ComputePartialTileExtents(&leftPartialTileWidth,
- &rightPartialTileWidth,
- ¢reWidth,
- rect.x,
- rect.width,
- tile.x,
- tile.width);
-
- int32_t topPartialTileHeight;
- int32_t bottomPartialTileHeight;
- int32_t centreHeight;
- ComputePartialTileExtents(&topPartialTileHeight,
- &bottomPartialTileHeight,
- ¢reHeight,
- rect.y,
- rect.height,
- tile.y,
- tile.height);
-
- /* We have nine regions of the target area which have to be tiled differetly:
- *
- * Top Left, Top Middle, Top Right,
- * Left Middle, Centre, Right Middle,
- * Bottom Left, Bottom Middle, Bottom Right
- *
- * + Centre is tiled by repeating the tiled image in full.
- * + Top Left, Top Middle and Top Right:
- * Some of the rows from the top of the tile will be clipped here.
- * + Bottom Left, Bottom Middle and Bottom Right:
- * Some of the rows from the bottom of the tile will be clipped here.
- * + Top Left, Left Middle and Bottom left:
- * Some of the columns from the Left of the tile will be clipped here.
- * + Top Right, Right Middle and Bottom Right:
- * Some of the columns from the right of the tile will be clipped here.
- *
- * If the sizes and positions of the target and tile are such that the tile
- * aligns exactly on any (or all) of the edges, then some (or all) of the
- * regions above (except Centre) will be zero sized.
- */
-
- nsIntRect targetRects[] = {
- // Top Left
- nsIntRect(rect.x, rect.y, leftPartialTileWidth, topPartialTileHeight),
- // Top Middle
- nsIntRect(rect.x + leftPartialTileWidth,
- rect.y,
- centreWidth,
- topPartialTileHeight),
- // Top Right
- nsIntRect(rect.XMost() - rightPartialTileWidth,
- rect.y,
- rightPartialTileWidth,
- topPartialTileHeight),
- // Left Middle
- nsIntRect(rect.x,
- rect.y + topPartialTileHeight,
- leftPartialTileWidth,
- centreHeight),
- // Centre
- nsIntRect(rect.x + leftPartialTileWidth,
- rect.y + topPartialTileHeight,
- centreWidth,
- centreHeight),
- // Right Middle
- nsIntRect(rect.XMost() - rightPartialTileWidth,
- rect.y + topPartialTileHeight,
- rightPartialTileWidth,
- centreHeight),
- // Bottom Left
- nsIntRect(rect.x,
- rect.YMost() - bottomPartialTileHeight,
- leftPartialTileWidth,
- bottomPartialTileHeight),
- // Bottom Middle
- nsIntRect(rect.x + leftPartialTileWidth,
- rect.YMost() - bottomPartialTileHeight,
- centreWidth,
- bottomPartialTileHeight),
- // Bottom Right
- nsIntRect(rect.XMost() - rightPartialTileWidth,
- rect.YMost() - bottomPartialTileHeight,
- rightPartialTileWidth,
- bottomPartialTileHeight)
- };
-
- nsIntRect tileRects[] = {
- // Top Left
- nsIntRect(tile.XMost() - leftPartialTileWidth,
- tile.YMost() - topPartialTileHeight,
- leftPartialTileWidth,
- topPartialTileHeight),
- // Top Middle
- nsIntRect(tile.x,
- tile.YMost() - topPartialTileHeight,
- tile.width,
- topPartialTileHeight),
- // Top Right
- nsIntRect(tile.x,
- tile.YMost() - topPartialTileHeight,
- rightPartialTileWidth,
- topPartialTileHeight),
- // Left Middle
- nsIntRect(tile.XMost() - leftPartialTileWidth,
- tile.y,
- leftPartialTileWidth,
- tile.height),
- // Centre
- nsIntRect(tile.x,
- tile.y,
- tile.width,
- tile.height),
- // Right Middle
- nsIntRect(tile.x,
- tile.y,
- rightPartialTileWidth,
- tile.height),
- // Bottom Left
- nsIntRect(tile.XMost() - leftPartialTileWidth,
- tile.y,
- leftPartialTileWidth,
- bottomPartialTileHeight),
- // Bottom Middle
- nsIntRect(tile.x,
- tile.y,
- tile.width,
- bottomPartialTileHeight),
- // Bottom Right
- nsIntRect(tile.x,
- tile.y,
- rightPartialTileWidth,
- bottomPartialTileHeight)
- };
-
- for (uint32_t i = 0; i < ArrayLength(targetRects); ++i) {
- TilePixels(targetData,
- sourceData,
- targetRects[i],
- tileRects[i],
- stride);
- }
-
- return NS_OK;
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eTile);
}
bool
SVGFETileElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFETileElementBase::AttributeAffectsRendering(aNameSpaceID,
aAttribute) ||
--- a/content/svg/content/src/SVGFETileElement.h
+++ b/content/svg/content/src/SVGFETileElement.h
@@ -26,30 +26,24 @@ protected:
{
}
virtual JSObject* WrapNode(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
public:
virtual bool SubregionIsUnionOfRegions() { return false; }
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
protected:
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGFETurbulenceElement.cpp
+++ b/content/svg/content/src/SVGFETurbulenceElement.cpp
@@ -5,23 +5,21 @@
#include "mozilla/dom/SVGFETurbulenceElement.h"
#include "mozilla/dom/SVGFETurbulenceElementBinding.h"
#include "nsSVGFilterInstance.h"
#include "nsSVGUtils.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FETurbulence)
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace dom {
-// Turbulence Types
-static const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
-static const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2;
-
// Stitch Options
static const unsigned short SVG_STITCHTYPE_STITCH = 1;
static const unsigned short SVG_STITCHTYPE_NOSTITCH = 2;
static const int32_t MAX_OCTAVES = 10;
JSObject*
SVGFETurbulenceElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
@@ -115,278 +113,66 @@ SVGFETurbulenceElement::StitchTiles()
}
already_AddRefed<SVGAnimatedEnumeration>
SVGFETurbulenceElement::Type()
{
return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
}
-nsresult
-SVGFETurbulenceElement::Filter(nsSVGFilterInstance* instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
+FilterPrimitiveDescription
+SVGFETurbulenceElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages)
{
- uint8_t* targetData = aTarget->mImage->Data();
- uint32_t stride = aTarget->mImage->Stride();
-
- nsIntRect filterSubregion(int32_t(aTarget->mFilterPrimitiveSubregion.X()),
- int32_t(aTarget->mFilterPrimitiveSubregion.Y()),
- int32_t(aTarget->mFilterPrimitiveSubregion.Width()),
- int32_t(aTarget->mFilterPrimitiveSubregion.Height()));
-
float fX = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eFirst);
float fY = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eSecond);
float seed = mNumberAttributes[OCTAVES].GetAnimValue();
- int32_t octaves = std::min(mIntegerAttributes[OCTAVES].GetAnimValue(), MAX_OCTAVES);
- uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
+ uint32_t octaves = clamped(mIntegerAttributes[OCTAVES].GetAnimValue(), 0, MAX_OCTAVES);
+ uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
uint16_t stitch = mEnumAttributes[STITCHTILES].GetAnimValue();
- InitSeed((int32_t)seed);
-
- // XXXroc this makes absolutely no sense to me.
- float filterX = instance->GetFilterRegion().X();
- float filterY = instance->GetFilterRegion().Y();
- float filterWidth = instance->GetFilterRegion().Width();
- float filterHeight = instance->GetFilterRegion().Height();
-
- bool doStitch = false;
- if (stitch == SVG_STITCHTYPE_STITCH) {
- doStitch = true;
-
- float lowFreq, hiFreq;
-
- lowFreq = floor(filterWidth * fX) / filterWidth;
- hiFreq = ceil(filterWidth * fX) / filterWidth;
- if (fX / lowFreq < hiFreq / fX)
- fX = lowFreq;
- else
- fX = hiFreq;
-
- lowFreq = floor(filterHeight * fY) / filterHeight;
- hiFreq = ceil(filterHeight * fY) / filterHeight;
- if (fY / lowFreq < hiFreq / fY)
- fY = lowFreq;
- else
- fY = hiFreq;
- }
- for (int32_t y = rect.y; y < rect.YMost(); y++) {
- for (int32_t x = rect.x; x < rect.XMost(); x++) {
- int32_t targIndex = y * stride + x * 4;
- double point[2];
- point[0] = filterX + (filterWidth * (x + instance->GetSurfaceRect().x)) / (filterSubregion.width - 1);
- point[1] = filterY + (filterHeight * (y + instance->GetSurfaceRect().y)) / (filterSubregion.height - 1);
-
- float col[4];
- if (type == SVG_TURBULENCE_TYPE_TURBULENCE) {
- for (int i = 0; i < 4; i++)
- col[i] = Turbulence(i, point, fX, fY, octaves, false,
- doStitch, filterX, filterY, filterWidth, filterHeight) * 255;
- } else {
- for (int i = 0; i < 4; i++)
- col[i] = (Turbulence(i, point, fX, fY, octaves, true,
- doStitch, filterX, filterY, filterWidth, filterHeight) * 255 + 255) / 2;
- }
- for (int i = 0; i < 4; i++) {
- col[i] = std::min(col[i], 255.f);
- col[i] = std::max(col[i], 0.f);
- }
-
- uint8_t r, g, b, a;
- a = uint8_t(col[3]);
- FAST_DIVIDE_BY_255(r, unsigned(col[0]) * a);
- FAST_DIVIDE_BY_255(g, unsigned(col[1]) * a);
- FAST_DIVIDE_BY_255(b, unsigned(col[2]) * a);
-
- targetData[targIndex + GFX_ARGB32_OFFSET_B] = b;
- targetData[targIndex + GFX_ARGB32_OFFSET_G] = g;
- targetData[targIndex + GFX_ARGB32_OFFSET_R] = r;
- targetData[targIndex + GFX_ARGB32_OFFSET_A] = a;
- }
+ if (fX == 0 || fY == 0) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
- return NS_OK;
+ // We interpret the base frequency as relative to user space units. In other
+ // words, we consider one turbulence base period to be 1 / fX user space
+ // units wide and 1 / fY user space units high. We do not scale the frequency
+ // depending on the filter primitive region.
+ gfxRect firstPeriodInUserSpace(0, 0, 1 / fX, 1 / fY);
+ gfxMatrix m = aInstance->GetUserSpaceToFilterSpaceTransform();
+ gfxRect firstPeriodInFilterSpace = m.TransformBounds(firstPeriodInUserSpace);
+ Size frequencyInFilterSpace(1 / firstPeriodInFilterSpace.width,
+ 1 / firstPeriodInFilterSpace.height);
+ gfxPoint offset = firstPeriodInFilterSpace.TopLeft();
+
+ FilterPrimitiveDescription descr(FilterPrimitiveDescription::eTurbulence);
+ descr.Attributes().Set(eTurbulenceOffset, IntPoint(offset.x, offset.y));
+ descr.Attributes().Set(eTurbulenceBaseFrequency, frequencyInFilterSpace);
+ descr.Attributes().Set(eTurbulenceSeed, seed);
+ descr.Attributes().Set(eTurbulenceNumOctaves, octaves);
+ descr.Attributes().Set(eTurbulenceStitchable, stitch == SVG_STITCHTYPE_STITCH);
+ descr.Attributes().Set(eTurbulenceType, type);
+ return descr;
}
bool
SVGFETurbulenceElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFETurbulenceElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::seed ||
aAttribute == nsGkAtoms::baseFrequency ||
aAttribute == nsGkAtoms::numOctaves ||
aAttribute == nsGkAtoms::type ||
aAttribute == nsGkAtoms::stitchTiles));
}
-void
-SVGFETurbulenceElement::InitSeed(int32_t aSeed)
-{
- double s;
- int i, j, k;
- aSeed = SetupSeed(aSeed);
- for (k = 0; k < 4; k++) {
- for (i = 0; i < sBSize; i++) {
- mLatticeSelector[i] = i;
- for (j = 0; j < 2; j++) {
- mGradient[k][i][j] =
- (double) (((aSeed =
- Random(aSeed)) % (sBSize + sBSize)) - sBSize) / sBSize;
- }
- s = double (sqrt
- (mGradient[k][i][0] * mGradient[k][i][0] +
- mGradient[k][i][1] * mGradient[k][i][1]));
- mGradient[k][i][0] /= s;
- mGradient[k][i][1] /= s;
- }
- }
- while (--i) {
- k = mLatticeSelector[i];
- mLatticeSelector[i] = mLatticeSelector[j =
- (aSeed =
- Random(aSeed)) % sBSize];
- mLatticeSelector[j] = k;
- }
- for (i = 0; i < sBSize + 2; i++) {
- mLatticeSelector[sBSize + i] = mLatticeSelector[i];
- for (k = 0; k < 4; k++)
- for (j = 0; j < 2; j++)
- mGradient[k][sBSize + i][j] = mGradient[k][i][j];
- }
-}
-
-#define S_CURVE(t) ( t * t * (3. - 2. * t) )
-#define LERP(t, a, b) ( a + t * (b - a) )
-double
-SVGFETurbulenceElement::Noise2(int aColorChannel, double aVec[2],
- StitchInfo *aStitchInfo)
-{
- int bx0, bx1, by0, by1, b00, b10, b01, b11;
- double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
- long i, j;
- t = aVec[0] + sPerlinN;
- bx0 = (int) t;
- bx1 = bx0 + 1;
- rx0 = t - (int) t;
- rx1 = rx0 - 1.0f;
- t = aVec[1] + sPerlinN;
- by0 = (int) t;
- by1 = by0 + 1;
- ry0 = t - (int) t;
- ry1 = ry0 - 1.0f;
- // If stitching, adjust lattice points accordingly.
- if (aStitchInfo != nullptr) {
- if (bx0 >= aStitchInfo->mWrapX)
- bx0 -= aStitchInfo->mWidth;
- if (bx1 >= aStitchInfo->mWrapX)
- bx1 -= aStitchInfo->mWidth;
- if (by0 >= aStitchInfo->mWrapY)
- by0 -= aStitchInfo->mHeight;
- if (by1 >= aStitchInfo->mWrapY)
- by1 -= aStitchInfo->mHeight;
- }
- bx0 &= sBM;
- bx1 &= sBM;
- by0 &= sBM;
- by1 &= sBM;
- i = mLatticeSelector[bx0];
- j = mLatticeSelector[bx1];
- b00 = mLatticeSelector[i + by0];
- b10 = mLatticeSelector[j + by0];
- b01 = mLatticeSelector[i + by1];
- b11 = mLatticeSelector[j + by1];
- sx = double (S_CURVE(rx0));
- sy = double (S_CURVE(ry0));
- q = mGradient[aColorChannel][b00];
- u = rx0 * q[0] + ry0 * q[1];
- q = mGradient[aColorChannel][b10];
- v = rx1 * q[0] + ry0 * q[1];
- a = LERP(sx, u, v);
- q = mGradient[aColorChannel][b01];
- u = rx0 * q[0] + ry1 * q[1];
- q = mGradient[aColorChannel][b11];
- v = rx1 * q[0] + ry1 * q[1];
- b = LERP(sx, u, v);
- return LERP(sy, a, b);
-}
-#undef S_CURVE
-#undef LERP
-
-double
-SVGFETurbulenceElement::Turbulence(int aColorChannel, double* aPoint,
- double aBaseFreqX, double aBaseFreqY,
- int aNumOctaves, bool aFractalSum,
- bool aDoStitching,
- double aTileX, double aTileY,
- double aTileWidth, double aTileHeight)
-{
- StitchInfo stitch;
- StitchInfo *stitchInfo = nullptr; // Not stitching when nullptr.
- // Adjust the base frequencies if necessary for stitching.
- if (aDoStitching) {
- // When stitching tiled turbulence, the frequencies must be adjusted
- // so that the tile borders will be continuous.
- if (aBaseFreqX != 0.0) {
- double loFreq = double (floor(aTileWidth * aBaseFreqX)) / aTileWidth;
- double hiFreq = double (ceil(aTileWidth * aBaseFreqX)) / aTileWidth;
- if (aBaseFreqX / loFreq < hiFreq / aBaseFreqX)
- aBaseFreqX = loFreq;
- else
- aBaseFreqX = hiFreq;
- }
- if (aBaseFreqY != 0.0) {
- double loFreq = double (floor(aTileHeight * aBaseFreqY)) / aTileHeight;
- double hiFreq = double (ceil(aTileHeight * aBaseFreqY)) / aTileHeight;
- if (aBaseFreqY / loFreq < hiFreq / aBaseFreqY)
- aBaseFreqY = loFreq;
- else
- aBaseFreqY = hiFreq;
- }
- // Set up initial stitch values.
- stitchInfo = &stitch;
- stitch.mWidth = int (aTileWidth * aBaseFreqX + 0.5f);
- stitch.mWrapX = int (aTileX * aBaseFreqX + sPerlinN + stitch.mWidth);
- stitch.mHeight = int (aTileHeight * aBaseFreqY + 0.5f);
- stitch.mWrapY = int (aTileY * aBaseFreqY + sPerlinN + stitch.mHeight);
- }
- double sum = 0.0f;
- double vec[2];
- vec[0] = aPoint[0] * aBaseFreqX;
- vec[1] = aPoint[1] * aBaseFreqY;
- double ratio = 1;
- for (int octave = 0; octave < aNumOctaves; octave++) {
- if (aFractalSum)
- sum += double (Noise2(aColorChannel, vec, stitchInfo) / ratio);
- else
- sum += double (fabs(Noise2(aColorChannel, vec, stitchInfo)) / ratio);
- vec[0] *= 2;
- vec[1] *= 2;
- ratio *= 2;
- if (stitchInfo != nullptr) {
- // Update stitch values. Subtracting sPerlinN before the multiplication
- // and adding it afterward simplifies to subtracting it once.
- stitch.mWidth *= 2;
- stitch.mWrapX = 2 * stitch.mWrapX - sPerlinN;
- stitch.mHeight *= 2;
- stitch.mWrapY = 2 * stitch.mWrapY - sPerlinN;
- }
- }
- return sum;
-}
-
-nsIntRect
-SVGFETurbulenceElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- return GetMaxRect();
-}
-
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
SVGFETurbulenceElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
ArrayLength(sNumberInfo));
--- a/content/svg/content/src/SVGFETurbulenceElement.h
+++ b/content/svg/content/src/SVGFETurbulenceElement.h
@@ -30,25 +30,23 @@ protected:
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedNumber> BaseFrequencyX();
already_AddRefed<SVGAnimatedNumber> BaseFrequencyY();
already_AddRefed<SVGAnimatedInteger> NumOctaves();
already_AddRefed<SVGAnimatedNumber> Seed();
@@ -78,75 +76,14 @@ protected:
nsSVGEnum mEnumAttributes[2];
static nsSVGEnumMapping sTypeMap[];
static nsSVGEnumMapping sStitchTilesMap[];
static EnumInfo sEnumInfo[2];
enum { RESULT };
nsSVGString mStringAttributes[1];
static StringInfo sStringInfo[1];
-
-private:
-
- /* The turbulence calculation code is an adapted version of what
- appears in the SVG 1.1 specification:
- http://www.w3.org/TR/SVG11/filters.html#feTurbulence
- */
-
- /* Produces results in the range [1, 2**31 - 2].
- Algorithm is: r = (a * r) mod m
- where a = 16807 and m = 2**31 - 1 = 2147483647
- See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
- To test: the algorithm should produce the result 1043618065
- as the 10,000th generated number if the original seed is 1.
- */
-#define RAND_M 2147483647 /* 2**31 - 1 */
-#define RAND_A 16807 /* 7**5; primitive root of m */
-#define RAND_Q 127773 /* m / a */
-#define RAND_R 2836 /* m % a */
-
- int32_t SetupSeed(int32_t aSeed) {
- if (aSeed <= 0)
- aSeed = -(aSeed % (RAND_M - 1)) + 1;
- if (aSeed > RAND_M - 1)
- aSeed = RAND_M - 1;
- return aSeed;
- }
-
- uint32_t Random(uint32_t aSeed) {
- int32_t result = RAND_A * (aSeed % RAND_Q) - RAND_R * (aSeed / RAND_Q);
- if (result <= 0)
- result += RAND_M;
- return result;
- }
-#undef RAND_M
-#undef RAND_A
-#undef RAND_Q
-#undef RAND_R
-
- const static int sBSize = 0x100;
- const static int sBM = 0xff;
- const static int sPerlinN = 0x1000;
- const static int sNP = 12; /* 2^PerlinN */
- const static int sNM = 0xfff;
-
- int32_t mLatticeSelector[sBSize + sBSize + 2];
- double mGradient[4][sBSize + sBSize + 2][2];
- struct StitchInfo {
- int mWidth; // How much to subtract to wrap for stitching.
- int mHeight;
- int mWrapX; // Minimum value to wrap.
- int mWrapY;
- };
-
- void InitSeed(int32_t aSeed);
- double Noise2(int aColorChannel, double aVec[2], StitchInfo *aStitchInfo);
- double
- Turbulence(int aColorChannel, double *aPoint, double aBaseFreqX,
- double aBaseFreqY, int aNumOctaves, bool aFractalSum,
- bool aDoStitching, double aTileX, double aTileY,
- double aTileWidth, double aTileHeight);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGFETurbulenceElement_h
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -44,43 +44,17 @@
#if defined(XP_WIN)
// Prevent Windows redefining LoadImage
#undef LoadImage
#endif
using namespace mozilla;
using namespace mozilla::dom;
-
-static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
-static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
-static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
-static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
-static const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
-
-void
-CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
- const nsIntRect& aDataRect)
-{
- for (int32_t y = aDataRect.y; y < aDataRect.YMost(); y++) {
- memcpy(aDest + y * aStride + 4 * aDataRect.x,
- aSrc + y * aStride + 4 * aDataRect.x,
- 4 * aDataRect.width);
- }
-}
-
-static void
-CopyAndScaleDeviceOffset(const gfxImageSurface *aImage, gfxImageSurface *aResult,
- gfxFloat kernelX, gfxFloat kernelY)
-{
- gfxPoint deviceOffset = aImage->GetDeviceOffset();
- deviceOffset.x /= kernelX;
- deviceOffset.y /= kernelY;
- aResult->SetDeviceOffset(deviceOffset);
-}
+using namespace mozilla::gfx;
//--------------------Filter Element Base Class-----------------------
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
{
{ &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
{ &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
{ &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
@@ -101,140 +75,16 @@ NS_INTERFACE_MAP_BEGIN(nsSVGFE)
if ( aIID.Equals(NS_GET_IID(nsSVGFE)) )
foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
else
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBase)
//----------------------------------------------------------------------
// Implementation
-nsSVGFE::ScaleInfo
-nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
- const Image *aSource, const Image *aTarget,
- const nsIntRect& aDataRect,
- nsSVGNumberPair *aKernelUnitLength)
-{
- ScaleInfo result;
- result.mRescaling = aKernelUnitLength->IsExplicitlySet();
- if (!result.mRescaling) {
- result.mSource = aSource->mImage;
- result.mTarget = aTarget->mImage;
- result.mDataRect = aDataRect;
- return result;
- }
-
- gfxFloat kernelX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
- aKernelUnitLength,
- nsSVGNumberPair::eFirst);
- gfxFloat kernelY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
- aKernelUnitLength,
- nsSVGNumberPair::eSecond);
- if (kernelX <= 0 || kernelY <= 0)
- return result;
-
- bool overflow = false;
- gfxIntSize scaledSize =
- nsSVGUtils::ConvertToSurfaceSize(gfxSize(aTarget->mImage->Width() / kernelX,
- aTarget->mImage->Height() / kernelY),
- &overflow);
- // If the requested size based on the kernel unit is too big, we
- // need to bail because the effect is pixel size dependent. Also
- // need to check if we ended up with a negative size (arithmetic
- // overflow) or zero size (large kernel unit)
- if (overflow || scaledSize.width <= 0 || scaledSize.height <= 0)
- return result;
-
- gfxRect r(aDataRect.x, aDataRect.y, aDataRect.width, aDataRect.height);
- r.Scale(1 / kernelX, 1 / kernelY);
- r.RoundOut();
- if (!gfxUtils::GfxRectToIntRect(r, &result.mDataRect))
- return result;
-
- // Rounding in the code above can mean that result.mDataRect is not contained
- // within the bounds of the surfaces that we're about to create. We must
- // clamp to these bounds to prevent out-of-bounds reads and writes:
- result.mDataRect.IntersectRect(result.mDataRect,
- nsIntRect(nsIntPoint(), scaledSize));
-
- result.mSource = new gfxImageSurface(scaledSize,
- gfxImageFormatARGB32);
- result.mTarget = new gfxImageSurface(scaledSize,
- gfxImageFormatARGB32);
- if (!result.mSource || result.mSource->CairoStatus() ||
- !result.mTarget || result.mTarget->CairoStatus()) {
- result.mSource = nullptr;
- result.mTarget = nullptr;
- return result;
- }
-
- CopyAndScaleDeviceOffset(aSource->mImage, result.mSource, kernelX, kernelY);
- CopyAndScaleDeviceOffset(aTarget->mImage, result.mTarget, kernelX, kernelY);
-
- result.mRealTarget = aTarget->mImage;
-
- gfxContext ctx(result.mSource);
- ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
- ctx.Scale(double(scaledSize.width) / aTarget->mImage->Width(),
- double(scaledSize.height) / aTarget->mImage->Height());
- ctx.SetSource(aSource->mImage);
- ctx.Paint();
-
- // mTarget was already cleared when it was created
-
- return result;
-}
-
-void
-nsSVGFE::FinishScalingFilter(ScaleInfo *aScaleInfo)
-{
- if (!aScaleInfo->mRescaling)
- return;
-
- gfxIntSize scaledSize = aScaleInfo->mTarget->GetSize();
-
- gfxContext ctx(aScaleInfo->mRealTarget);
- ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
- ctx.Scale(double(aScaleInfo->mRealTarget->Width()) / scaledSize.width,
- double(aScaleInfo->mRealTarget->Height()) / scaledSize.height);
- ctx.SetSource(aScaleInfo->mTarget);
- ctx.Paint();
-}
-
-nsIntRect
-nsSVGFE::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- nsIntRect r;
- for (uint32_t i = 0; i < aSourceBBoxes.Length(); ++i) {
- r.UnionRect(r, aSourceBBoxes[i]);
- }
- return r;
-}
-
-void
-nsSVGFE::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- for (uint32_t i = 0; i < aSourceBBoxes.Length(); ++i) {
- aSourceBBoxes[i] = aTargetBBox;
- }
-}
-
-nsIntRect
-nsSVGFE::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- nsIntRect r;
- for (uint32_t i = 0; i < aSourceChangeBoxes.Length(); ++i) {
- r.UnionRect(r, aSourceChangeBoxes[i]);
- }
- return r;
-}
-
void
nsSVGFE::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
}
bool
nsSVGFE::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
@@ -289,25 +139,54 @@ nsSVGFE::IsAttributeMapped(const nsIAtom
return FindAttributeDependence(name, map) ||
nsSVGFEBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
// nsSVGElement methods
+
+bool
+nsSVGFE::StyleIsSetToSRGB()
+{
+ nsIFrame* frame = GetPrimaryFrame();
+ if (!frame) return false;
+
+ nsStyleContext* style = frame->StyleContext();
+ return style->StyleSVG()->mColorInterpolationFilters ==
+ NS_STYLE_COLOR_INTERPOLATION_SRGB;
+}
+
/* virtual */ bool
nsSVGFE::HasValidDimensions() const
{
return (!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
+Size
+nsSVGFE::GetKernelUnitLength(nsSVGFilterInstance* aInstance,
+ nsSVGNumberPair *aKernelUnitLength)
+{
+ if (!aKernelUnitLength->IsExplicitlySet()) {
+ return Size(1, 1);
+ }
+
+ float kernelX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
+ aKernelUnitLength,
+ nsSVGNumberPair::eFirst);
+ float kernelY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
+ aKernelUnitLength,
+ nsSVGNumberPair::eSecond);
+ return Size(kernelX, kernelY);
+}
+
nsSVGElement::LengthAttributesInfo
nsSVGFE::GetLengthInfo()
{
return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
ArrayLength(sLengthInfo));
}
namespace mozilla {
@@ -423,94 +302,41 @@ SVGComponentTransferFunctionElement::Exp
}
already_AddRefed<SVGAnimatedNumber>
SVGComponentTransferFunctionElement::Offset()
{
return mNumberAttributes[OFFSET].ToDOMAnimatedNumber(this);
}
-bool
-SVGComponentTransferFunctionElement::GenerateLookupTable(uint8_t *aTable)
+AttributeMap
+SVGComponentTransferFunctionElement::ComputeAttributes()
{
- uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
+ uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
float slope, intercept, amplitude, exponent, offset;
GetAnimatedNumberValues(&slope, &intercept, &litude,
&exponent, &offset, nullptr);
const SVGNumberList &tableValues =
mNumberListAttributes[TABLEVALUES].GetAnimValue();
- uint32_t tvLength = tableValues.Length();
- uint32_t i;
-
- switch (type) {
- case SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
- {
- if (tableValues.Length() < 2)
- return false;
-
- for (i = 0; i < 256; i++) {
- uint32_t k = (i * (tvLength - 1)) / 255;
- float v1 = tableValues[k];
- float v2 = tableValues[std::min(k + 1, tvLength - 1)];
- int32_t val =
- int32_t(255 * (v1 + (i/255.0f - k/float(tvLength-1))*(tvLength - 1)*(v2 - v1)));
- val = std::min(255, val);
- val = std::max(0, val);
- aTable[i] = val;
- }
- break;
+ AttributeMap map;
+ map.Set(eComponentTransferFunctionType, type);
+ map.Set(eComponentTransferFunctionSlope, slope);
+ map.Set(eComponentTransferFunctionIntercept, intercept);
+ map.Set(eComponentTransferFunctionAmplitude, amplitude);
+ map.Set(eComponentTransferFunctionExponent, exponent);
+ map.Set(eComponentTransferFunctionOffset, offset);
+ if (tableValues.Length()) {
+ map.Set(eComponentTransferFunctionTableValues, &tableValues[0], tableValues.Length());
+ } else {
+ map.Set(eComponentTransferFunctionTableValues, nullptr, 0);
}
-
- case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
- {
- if (tableValues.Length() < 1)
- return false;
-
- for (i = 0; i < 256; i++) {
- uint32_t k = (i * tvLength) / 255;
- k = std::min(k, tvLength - 1);
- float v = tableValues[k];
- int32_t val = int32_t(255 * v);
- val = std::min(255, val);
- val = std::max(0, val);
- aTable[i] = val;
- }
- break;
- }
-
- case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
- {
- for (i = 0; i < 256; i++) {
- int32_t val = int32_t(slope * i + 255 * intercept);
- val = std::min(255, val);
- val = std::max(0, val);
- aTable[i] = val;
- }
- break;
- }
-
- case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
- {
- for (i = 0; i < 256; i++) {
- int32_t val = int32_t(255 * (amplitude * pow(i / 255.0f, exponent) + offset));
- val = std::min(255, val);
- val = std::max(0, val);
- aTable[i] = val;
- }
- break;
- }
-
- case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY:
- default:
- break;
- }
- return true;
+ return map;
}
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberListAttributesInfo
SVGComponentTransferFunctionElement::GetNumberListInfo()
{
@@ -644,280 +470,60 @@ nsSVGFELightingElement::IsAttributeMappe
}
void
nsSVGFELightingElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
-void
-nsSVGFELightingElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
- // XXX lighting can depend on more than the target area, because
- // of the kernels it uses. We could compute something precise here
- // but just leave it and assume we use the entire source bounding box.
-}
-
-nsIntRect
-nsSVGFELightingElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance)
-{
- // XXX be conservative for now
- return GetMaxRect();
-}
-
-static int32_t
-Convolve3x3(const uint8_t *index, int32_t stride,
- const int8_t kernel[3][3]
-#ifdef DEBUG
- , const uint8_t *minData, const uint8_t *maxData
-#endif // DEBUG
-)
-{
- int32_t sum = 0;
- for (int32_t y = 0; y < 3; y++) {
- for (int32_t x = 0; x < 3; x++) {
- int8_t k = kernel[y][x];
- if (k) {
- const uint8_t *valPtr = index + (4 * (x - 1) + stride * (y - 1));
- NS_ASSERTION(valPtr >= minData, "out of bounds read (before buffer)");
- NS_ASSERTION(valPtr < maxData, "out of bounds read (after buffer)");
- sum += k * (*valPtr);
- }
- }
- }
- return sum;
-}
-
-static void
-GenerateNormal(float *N, const uint8_t *data, int32_t stride,
- int32_t surfaceWidth, int32_t surfaceHeight,
- int32_t x, int32_t y, float surfaceScale)
+AttributeMap
+nsSVGFELightingElement::ComputeLightAttributes(nsSVGFilterInstance* aInstance)
{
- // See this for source of constants:
- // http://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement
- static const int8_t Kx[3][3][3][3] =
- { { { { 0, 0, 0}, { 0, -2, 2}, { 0, -1, 1} },
- { { 0, 0, 0}, {-2, 0, 2}, {-1, 0, 1} },
- { { 0, 0, 0}, {-2, 2, 0}, {-1, 1, 0} } },
- { { { 0, -1, 1}, { 0, -2, 2}, { 0, -1, 1} },
- { { -1, 0, 1}, {-2, 0, 2}, {-1, 0, 1} },
- { { -1, 1, 0}, {-2, 2, 0}, {-1, 1, 0} } },
- { { { 0, -1, 1}, { 0, -2, 2}, { 0, 0, 0} },
- { { -1, 0, 1}, {-2, 0, 2}, { 0, 0, 0} },
- { { -1, 1, 0}, {-2, 2, 0}, { 0, 0, 0} } } };
- static const int8_t Ky[3][3][3][3] =
- { { { { 0, 0, 0}, { 0, -2, -1}, { 0, 2, 1} },
- { { 0, 0, 0}, {-1, -2, -1}, { 1, 2, 1} },
- { { 0, 0, 0}, {-1, -2, 1}, { 1, 2, 0} } },
- { { { 0, -2, -1}, { 0, 0, 0}, { 0, 2, 1} },
- { { -1, -2, -1}, { 0, 0, 0}, { 1, 2, 1} },
- { { -1, -2, 0}, { 0, 0, 0}, { 1, 2, 0} } },
- { { { 0, -2, -1}, { 0, 2, 1}, { 0, 0, 0} },
- { { -1, -2, -1}, { 1, 2, 1}, { 0, 0, 0} },
- { { -1, -2, 0}, { 1, 2, 0}, { 0, 0, 0} } } };
- static const float FACTORx[3][3] =
- { { 2.0f / 3.0f, 1.0f / 3.0f, 2.0f / 3.0f },
- { 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 2.0f },
- { 2.0f / 3.0f, 1.0f / 3.0f, 2.0f / 3.0f } };
- static const float FACTORy[3][3] =
- { { 2.0f / 3.0f, 1.0f / 2.0f, 2.0f / 3.0f },
- { 1.0f / 3.0f, 1.0f / 4.0f, 1.0f / 3.0f },
- { 2.0f / 3.0f, 1.0f / 2.0f, 2.0f / 3.0f } };
-
- // degenerate cases
- if (surfaceWidth == 1 || surfaceHeight == 1) {
- // just return a unit vector pointing towards the viewer
- N[0] = 0;
- N[1] = 0;
- N[2] = 255;
- return;
- }
-
- int8_t xflag, yflag;
- if (x == 0) {
- xflag = 0;
- } else if (x == surfaceWidth - 1) {
- xflag = 2;
- } else {
- xflag = 1;
- }
- if (y == 0) {
- yflag = 0;
- } else if (y == surfaceHeight - 1) {
- yflag = 2;
- } else {
- yflag = 1;
- }
-
- const uint8_t *index = data + y * stride + 4 * x + GFX_ARGB32_OFFSET_A;
-
-#ifdef DEBUG
- // For sanity-checking, to be sure we're not reading outside source buffer:
- const uint8_t* minData = data;
- const uint8_t* maxData = minData + (surfaceHeight * surfaceWidth * stride);
-
- // We'll sanity-check each value we read inside of Convolve3x3, but we
- // might as well ensure we're passing it a valid pointer to start with, too:
- NS_ASSERTION(index >= minData, "index points before buffer start");
- NS_ASSERTION(index < maxData, "index points after buffer end");
-#endif // DEBUG
-
- N[0] = -surfaceScale * FACTORx[yflag][xflag] *
- Convolve3x3(index, stride, Kx[yflag][xflag]
-#ifdef DEBUG
- , minData, maxData
-#endif // DEBUG
- );
-
- N[1] = -surfaceScale * FACTORy[yflag][xflag] *
- Convolve3x3(index, stride, Ky[yflag][xflag]
-#ifdef DEBUG
- , minData, maxData
-#endif // DEBUG
- );
- N[2] = 255;
- NORMALIZE(N);
-}
-
-nsresult
-nsSVGFELightingElement::Filter(nsSVGFilterInstance *instance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& rect)
-{
- ScaleInfo info = SetupScalingFilter(instance, aSources[0], aTarget, rect,
- &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
- if (!info.mTarget)
- return NS_ERROR_FAILURE;
-
- SVGFEDistantLightElement* distantLight = nullptr;
- SVGFEPointLightElement* pointLight = nullptr;
- SVGFESpotLightElement* spotLight = nullptr;
-
- nsIFrame* frame = GetPrimaryFrame();
- if (!frame) return NS_ERROR_FAILURE;
- nsStyleContext* style = frame->StyleContext();
-
- nscolor lightColor = style->StyleSVGReset()->mLightingColor;
-
// find specified light
for (nsCOMPtr<nsIContent> child = nsINode::GetFirstChild();
child;
child = child->GetNextSibling()) {
- distantLight = child->IsSVG(nsGkAtoms::feDistantLight) ?
- static_cast<SVGFEDistantLightElement*>(child.get()) : nullptr;
- pointLight = child->IsSVG(nsGkAtoms::fePointLight) ?
- static_cast<SVGFEPointLightElement*>(child.get()) : nullptr;
- spotLight = child->IsSVG(nsGkAtoms::feSpotLight) ?
- static_cast<SVGFESpotLightElement*>(child.get()) : nullptr;
- if (distantLight || pointLight || spotLight)
- break;
- }
-
- if (!distantLight && !pointLight && !spotLight)
- return NS_ERROR_FAILURE;
-
- const float radPerDeg = static_cast<float>(M_PI/180.0);
-
- float L[3];
- if (distantLight) {
- float azimuth, elevation;
- distantLight->GetAnimatedNumberValues(&azimuth,
- &elevation,
- nullptr);
- L[0] = cos(azimuth * radPerDeg) * cos(elevation * radPerDeg);
- L[1] = sin(azimuth * radPerDeg) * cos(elevation * radPerDeg);
- L[2] = sin(elevation * radPerDeg);
- }
- float lightPos[3], pointsAt[3], specularExponent;
- float cosConeAngle = 0;
- if (pointLight) {
- pointLight->GetAnimatedNumberValues(lightPos,
- lightPos + 1,
- lightPos + 2,
- nullptr);
- instance->ConvertLocation(lightPos);
- }
- if (spotLight) {
- float limitingConeAngle;
- spotLight->GetAnimatedNumberValues(lightPos,
- lightPos + 1,
- lightPos + 2,
- pointsAt,
- pointsAt + 1,
- pointsAt + 2,
- &specularExponent,
- &limitingConeAngle,
- nullptr);
- instance->ConvertLocation(lightPos);
- instance->ConvertLocation(pointsAt);
-
- if (spotLight->mNumberAttributes[SVGFESpotLightElement::LIMITING_CONE_ANGLE].
- IsExplicitlySet()) {
- cosConeAngle = std::max<double>(cos(limitingConeAngle * radPerDeg), 0.0);
+ if (child->IsSVG(nsGkAtoms::feDistantLight) ||
+ child->IsSVG(nsGkAtoms::fePointLight) ||
+ child->IsSVG(nsGkAtoms::feSpotLight)) {
+ return static_cast<SVGFELightElement*>(child.get())->ComputeLightAttributes(aInstance);
}
}
- float surfaceScale = mNumberAttributes[SURFACE_SCALE].GetAnimValue();
-
- const nsIntRect& dataRect = info.mDataRect;
- int32_t stride = info.mSource->Stride();
- uint8_t *sourceData = info.mSource->Data();
- uint8_t *targetData = info.mTarget->Data();
- int32_t surfaceWidth = info.mSource->Width();
- int32_t surfaceHeight = info.mSource->Height();
-
- for (int32_t y = dataRect.y; y < dataRect.YMost(); y++) {
- for (int32_t x = dataRect.x; x < dataRect.XMost(); x++) {
- int32_t index = y * stride + x * 4;
-
- float N[3];
- GenerateNormal(N, sourceData, stride, surfaceWidth, surfaceHeight,
- x, y, surfaceScale);
-
- if (pointLight || spotLight) {
- gfxPoint pt = instance->FilterSpaceToUserSpace(
- gfxPoint(x + instance->GetSurfaceRect().x,
- y + instance->GetSurfaceRect().y));
- float Z = surfaceScale * sourceData[index + GFX_ARGB32_OFFSET_A] / 255;
+ AttributeMap map;
+ map.Set(eLightType, (uint32_t)eLightTypeNone);
+ return map;
+}
- L[0] = lightPos[0] - pt.x;
- L[1] = lightPos[1] - pt.y;
- L[2] = lightPos[2] - Z;
- NORMALIZE(L);
- }
-
- nscolor color;
-
- if (spotLight) {
- float S[3];
- S[0] = pointsAt[0] - lightPos[0];
- S[1] = pointsAt[1] - lightPos[1];
- S[2] = pointsAt[2] - lightPos[2];
- NORMALIZE(S);
- float dot = -DOT(L, S);
- float tmp = pow(dot, specularExponent);
- if (dot < cosConeAngle) tmp = 0;
- color = NS_RGB(uint8_t(NS_GET_R(lightColor) * tmp),
- uint8_t(NS_GET_G(lightColor) * tmp),
- uint8_t(NS_GET_B(lightColor) * tmp));
- } else {
- color = lightColor;
- }
-
- LightPixel(N, L, color, targetData + index);
- }
+FilterPrimitiveDescription
+nsSVGFELightingElement::AddLightingAttributes(FilterPrimitiveDescription aDescription,
+ nsSVGFilterInstance* aInstance)
+{
+ nsIFrame* frame = GetPrimaryFrame();
+ if (!frame) {
+ return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
- FinishScalingFilter(&info);
+ nsStyleContext* style = frame->StyleContext();
+ nscolor lightColor = style->StyleSVGReset()->mLightingColor;
+ Color color(NS_GET_R(lightColor) / 255.0f,
+ NS_GET_G(lightColor) / 255.0f,
+ NS_GET_B(lightColor) / 255.0f,
+ 1.0f);
+ float surfaceScale = mNumberAttributes[SURFACE_SCALE].GetAnimValue();
+ Size kernelUnitLength =
+ GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
- return NS_OK;
+ FilterPrimitiveDescription& descr = aDescription;
+ descr.Attributes().Set(eLightingLight, ComputeLightAttributes(aInstance));
+ descr.Attributes().Set(eLightingSurfaceScale, surfaceScale);
+ descr.Attributes().Set(eLightingKernelUnitLength, kernelUnitLength);
+ descr.Attributes().Set(eLightingColor, color);
+ return descr;
}
bool
nsSVGFELightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return nsSVGFELightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
--- a/content/svg/content/src/nsSVGFilters.h
+++ b/content/svg/content/src/nsSVGFilters.h
@@ -2,42 +2,29 @@
/* 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 __NS_SVGFILTERSELEMENT_H__
#define __NS_SVGFILTERSELEMENT_H__
#include "mozilla/Attributes.h"
-#include "gfxImageSurface.h"
-#include "gfxRect.h"
-#include "nsIFrame.h"
#include "nsImageLoadingContent.h"
#include "nsSVGLength2.h"
#include "nsSVGString.h"
#include "nsSVGElement.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
#include "nsSVGNumber2.h"
#include "nsSVGNumberPair.h"
+#include "FilterSupport.h"
+#include "gfxASurface.h"
class nsSVGFilterInstance;
class nsSVGFilterResource;
class nsSVGNumberPair;
-inline float DOT(const float* a, const float* b) {
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
-}
-
-inline void NORMALIZE(float* vec) {
- float norm = sqrt(DOT(vec, vec));
- vec[0] /= norm;
- vec[1] /= norm;
- vec[2] /= norm;
-}
-
struct nsSVGStringInfo {
nsSVGStringInfo(const nsSVGString* aString,
nsSVGElement *aElement) :
mString(aString), mElement(aElement) {}
const nsSVGString* mString;
nsSVGElement* mElement;
};
@@ -52,83 +39,38 @@ typedef nsSVGElement nsSVGFEBase;
* Base class for filter primitive elements
* Children of those elements e.g. feMergeNode
* derive from SVGFEUnstyledElement instead
*/
class nsSVGFE : public nsSVGFEBase
{
friend class nsSVGFilterInstance;
-public:
- class ColorModel {
- public:
- enum ColorSpace { SRGB, LINEAR_RGB };
- enum AlphaChannel { UNPREMULTIPLIED, PREMULTIPLIED };
+protected:
+ typedef mozilla::gfx::Size Size;
+ typedef mozilla::gfx::IntRect IntRect;
+ typedef mozilla::gfx::ColorSpace ColorSpace;
+ typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
- ColorModel(ColorSpace aColorSpace, AlphaChannel aAlphaChannel) :
- mColorSpace(aColorSpace), mAlphaChannel(aAlphaChannel) {}
- ColorModel() :
- mColorSpace(SRGB), mAlphaChannel(PREMULTIPLIED) {}
- bool operator==(const ColorModel& aOther) const {
- return mColorSpace == aOther.mColorSpace &&
- mAlphaChannel == aOther.mAlphaChannel;
- }
- ColorSpace mColorSpace;
- AlphaChannel mAlphaChannel;
- };
-
- struct Image {
- // The device offset of mImage makes it relative to filter space
- nsRefPtr<gfxImageSurface> mImage;
- // The filter primitive subregion bounding this image, in filter space
- gfxRect mFilterPrimitiveSubregion;
- ColorModel mColorModel;
- // When true, the RGB values are the same for all pixels in mImage
- bool mConstantColorChannels;
-
- Image() : mConstantColorChannels(false) {}
- };
-
-protected:
nsSVGFE(already_AddRefed<nsINodeInfo> aNodeInfo) : nsSVGFEBase(aNodeInfo) {}
- struct ScaleInfo {
- nsRefPtr<gfxImageSurface> mRealTarget;
- nsRefPtr<gfxImageSurface> mSource;
- nsRefPtr<gfxImageSurface> mTarget;
- nsIntRect mDataRect; // rect in mSource and mTarget to operate on
- bool mRescaling;
- };
+public:
+ typedef mozilla::gfx::AttributeMap AttributeMap;
- ScaleInfo SetupScalingFilter(nsSVGFilterInstance *aInstance,
- const Image *aSource,
- const Image *aTarget,
- const nsIntRect& aDataRect,
- nsSVGNumberPair *aUnit);
-
- void FinishScalingFilter(ScaleInfo *aScaleInfo);
-
-public:
- ColorModel
- GetInputColorModel(nsSVGFilterInstance* aInstance, int32_t aInputIndex,
- Image* aImage) {
- return ColorModel(
- (OperatesOnSRGB(aInstance, aInputIndex, aImage) ?
- ColorModel::SRGB : ColorModel::LINEAR_RGB),
- (OperatesOnPremultipledAlpha(aInputIndex) ?
- ColorModel::PREMULTIPLIED : ColorModel::UNPREMULTIPLIED));
+ ColorSpace
+ GetInputColorSpace(int32_t aInputIndex, ColorSpace aUnchangedInputColorSpace) {
+ return OperatesOnSRGB(aInputIndex, aUnchangedInputColorSpace == mozilla::gfx::SRGB) ?
+ mozilla::gfx::SRGB : mozilla::gfx::LINEAR_RGB;
}
- ColorModel
- GetOutputColorModel(nsSVGFilterInstance* aInstance) {
- return ColorModel(
- (OperatesOnSRGB(aInstance, -1, nullptr) ?
- ColorModel::SRGB : ColorModel::LINEAR_RGB),
- (OperatesOnPremultipledAlpha(-1) ?
- ColorModel::PREMULTIPLIED : ColorModel::UNPREMULTIPLIED));
+ // This is only called for filter primitives without inputs. For primitives
+ // with inputs, the output color model is the same as of the first input.
+ ColorSpace
+ GetOutputColorSpace() {
+ return ProducesSRGB() ? mozilla::gfx::SRGB : mozilla::gfx::LINEAR_RGB;
}
// See http://www.w3.org/TR/SVG/filters.html#FilterPrimitiveSubRegion
virtual bool SubregionIsUnionOfRegions() { return true; }
NS_DECLARE_STATIC_IID_ACCESSOR(NS_SVG_FE_CID)
// interfaces:
@@ -144,55 +86,21 @@ public:
bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE
{ return !(aFlags & ~(eCONTENT | eFILTER)); }
virtual nsSVGString& GetResultImageName() = 0;
// Return a list of all image names used as sources. Default is to
// return no sources.
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
- // Compute the bounding box of the filter output. The default is just the
- // union of the source bounding boxes. The caller is
- // responsible for clipping this to the filter primitive subregion, so
- // if the filter fills its filter primitive subregion, it can just
- // return GetMaxRect() here.
- // The source bounding boxes are ordered corresponding to GetSourceImageNames.
- virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
- const nsSVGFilterInstance& aInstance);
- // Given a bounding box for what we need to compute in the target,
- // compute which regions of the inputs are needed. On input
- // aSourceBBoxes contains the bounding box of what's rendered by
- // each source; this function should change those boxes to indicate
- // which region of the source's output it needs.
- // The default implementation sets all the source bboxes to the
- // target bbox.
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
- // Given the bounding boxes for the pixels that have changed in the inputs,
- // compute the bounding box of the changes in this primitive's output.
- // The result will be clipped by the caller to the result of ComputeTargetBBox
- // since there's no way anything outside that can change.
- // The default implementation returns the union of the source change boxes.
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance);
-
- // Perform the actual filter operation.
- // We guarantee that every mImage from aSources and aTarget has the
- // same width, height, stride and device offset.
- // aTarget is already filled in. This function just needs to fill in the
- // pixels of aTarget->mImage (which have already been cleared).
- // @param aDataRect the destination rectangle that needs to be painted,
- // relative to aTarget's surface data. This is the intersection of the
- // filter primitive subregion for this filter element and the
- // temporary surface area. Output need not be clipped to this rect but
- // it must be clipped to aTarget->mFilterPrimitiveSubregion.
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) = 0;
+
+ virtual FilterPrimitiveDescription
+ GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
+ const IntRect& aFilterSubregion,
+ nsTArray<nsRefPtr<gfxASurface> >& aInputImages) = 0;
// returns true if changes to the attribute should cause us to
// repaint the filter
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const;
static nsIntRect GetMaxRect() {
// Try to avoid overflow errors dealing with this rect. It will
@@ -205,34 +113,31 @@ public:
// WebIDL
already_AddRefed<mozilla::dom::SVGAnimatedLength> X();
already_AddRefed<mozilla::dom::SVGAnimatedLength> Y();
already_AddRefed<mozilla::dom::SVGAnimatedLength> Width();
already_AddRefed<mozilla::dom::SVGAnimatedLength> Height();
already_AddRefed<mozilla::dom::SVGAnimatedString> Result();
protected:
- virtual bool OperatesOnPremultipledAlpha(int32_t) { return true; }
+ virtual bool OperatesOnSRGB(int32_t aInputIndex, bool aInputIsAlreadySRGB) {
+ return StyleIsSetToSRGB();
+ }
- // Called either with aInputIndex >=0 in which case this is
- // testing whether the input 'aInputIndex' should be SRGB, or
- // if aInputIndex is -1 returns true if the output will be SRGB
- virtual bool OperatesOnSRGB(nsSVGFilterInstance* aInstance,
- int32_t aInputIndex, Image* aImage) {
- nsIFrame* frame = GetPrimaryFrame();
- if (!frame) return false;
+ // Only called for filter primitives without inputs.
+ virtual bool ProducesSRGB() { return StyleIsSetToSRGB(); }
- nsStyleContext* style = frame->StyleContext();
- return style->StyleSVG()->mColorInterpolationFilters ==
- NS_STYLE_COLOR_INTERPOLATION_SRGB;
- }
+ bool StyleIsSetToSRGB();
// nsSVGElement specializations:
virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+ Size GetKernelUnitLength(nsSVGFilterInstance* aInstance,
+ nsSVGNumberPair *aKernelUnitLength);
+
enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
nsSVGLength2 mLengthAttributes[4];
static LengthInfo sLengthInfo[4];
};
typedef nsSVGElement SVGFEUnstyledElementBase;
class SVGFEUnstyledElement : public SVGFEUnstyledElementBase
@@ -259,68 +164,65 @@ class nsSVGFELightingElement : public ns
protected:
nsSVGFELightingElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsSVGFELightingElementBase(aNodeInfo) {}
public:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
- virtual nsresult Filter(nsSVGFilterInstance* aInstance,
- const nsTArray<const Image*>& aSources,
- const Image* aTarget,
- const nsIntRect& aDataRect) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
- // XXX shouldn't we have ComputeTargetBBox here, since the output can
- // extend beyond the bounds of the inputs thanks to the convolution kernel?
- virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
- nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
- virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
- const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
-
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFELightingElementBase::)
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
protected:
- virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
- int32_t, Image*) MOZ_OVERRIDE { return true; }
- virtual void
- LightPixel(const float *N, const float *L,
- nscolor color, uint8_t *targetData) = 0;
+ virtual bool OperatesOnSRGB(int32_t aInputIndex,
+ bool aInputIsAlreadySRGB) MOZ_OVERRIDE { return true; }
virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
+ AttributeMap ComputeLightAttributes(nsSVGFilterInstance* aInstance);
+
+ FilterPrimitiveDescription
+ AddLightingAttributes(FilterPrimitiveDescription aDescription,
+ nsSVGFilterInstance* aInstance);
+
enum { SURFACE_SCALE, DIFFUSE_CONSTANT, SPECULAR_CONSTANT, SPECULAR_EXPONENT };
nsSVGNumber2 mNumberAttributes[4];
static NumberInfo sNumberInfo[4];
enum { KERNEL_UNIT_LENGTH };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
};
-void
-CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
- const nsIntRect& aDataRect);
+namespace mozilla {
+namespace dom {
-inline void
-CopyRect(const nsSVGFE::Image* aDest, const nsSVGFE::Image* aSrc, const nsIntRect& aDataRect)
+typedef SVGFEUnstyledElement SVGFELightElementBase;
+
+class SVGFELightElement : public SVGFELightElementBase
{
- NS_ASSERTION(aDest->mImage->Stride() == aSrc->mImage->Stride(), "stride mismatch");
- NS_ASSERTION(aDest->mImage->GetSize() == aSrc->mImage->GetSize(), "size mismatch");
- NS_ASSERTION(nsIntRect(0, 0, aDest->mImage->Width(), aDest->mImage->Height()).Contains(aDataRect),
- "aDataRect out of bounds");
+protected:
+ SVGFELightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+ : SVGFELightElementBase(aNodeInfo) {}
- CopyDataRect(aDest->mImage->Data(), aSrc->mImage->Data(),
- aSrc->mImage->Stride(), aDataRect);
+public:
+ typedef gfx::AttributeMap AttributeMap;
+
+ virtual AttributeMap
+ ComputeLightAttributes(nsSVGFilterInstance* aInstance) = 0;
+};
+
+}
}
#endif
--- a/content/xbl/src/XBLChildrenElement.h
+++ b/content/xbl/src/XBLChildrenElement.h
@@ -68,21 +68,16 @@ public:
// only insert in the innermost insertion point.
//NS_ASSERTION(mInsertedChildren.Contains(aChild),
// "Removing child that's not there");
mInsertedChildren.RemoveElement(aChild);
}
void ClearInsertedChildren()
{
- mInsertedChildren.Clear();
- }
-
- void ClearInsertedChildrenAndInsertionParents()
- {
for (uint32_t c = 0; c < mInsertedChildren.Length(); ++c) {
mInsertedChildren[c]->SetXBLInsertionParent(nullptr);
}
mInsertedChildren.Clear();
}
void MaybeSetupDefaultContent()
{
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -1085,17 +1085,17 @@ nsBindingManager::ContentRemoved(nsIDocu
parent = newParent;
} while (parent);
}
void
nsBindingManager::ClearInsertionPointsRecursively(nsIContent* aContent)
{
if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
- static_cast<XBLChildrenElement*>(aContent)->ClearInsertedChildrenAndInsertionParents();
+ static_cast<XBLChildrenElement*>(aContent)->ClearInsertedChildren();
}
for (nsIContent* child = aContent->GetFirstChild(); child;
child = child->GetNextSibling()) {
ClearInsertionPointsRecursively(child);
}
}
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -323,17 +323,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
nsRefPtr<EventHandlerNonNull> handlerCallback =
new EventHandlerNonNull(bound);
nsEventHandler eventHandler(handlerCallback);
// Execute it.
nsCOMPtr<nsIJSEventListener> eventListener;
- rv = NS_NewJSEventListener(nullptr, globalObject,
+ rv = NS_NewJSEventListener(globalObject,
scriptTarget, onEventAtom,
eventHandler,
getter_AddRefs(eventListener));
NS_ENSURE_SUCCESS(rv, rv);
// Handle the event.
eventListener->HandleEvent(aEvent);
eventListener->Disconnect();
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -11,17 +11,16 @@
#include "nsIDOMKeyEvent.h"
#include "nsXBLService.h"
#include "nsIServiceManager.h"
#include "nsGkAtoms.h"
#include "nsXBLDocumentInfo.h"
#include "nsIDOMElement.h"
#include "nsINativeKeyBindings.h"
#include "nsIController.h"
-#include "nsIControllers.h"
#include "nsFocusManager.h"
#include "nsPIWindowRoot.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsContentUtils.h"
#include "nsXBLPrototypeBinding.h"
#include "nsPIDOMWindow.h"
#include "nsIDocShell.h"
@@ -282,23 +281,23 @@ GetEditorKeyBindings()
}
return sNativeEditorBindings;
}
static void
DoCommandCallback(const char *aCommand, void *aData)
{
- nsIControllers *controllers = static_cast<nsIControllers*>(aData);
- if (!controllers) {
+ nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(static_cast<EventTarget*>(aData));
+ if (!root) {
return;
}
nsCOMPtr<nsIController> controller;
- controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
+ root->GetControllerForCommand(aCommand, getter_AddRefs(controller));
if (!controller) {
return;
}
bool commandEnabled;
nsresult rv = controller->IsCommandEnabled(aCommand, &commandEnabled);
NS_ENSURE_SUCCESS_VOID(rv);
if (commandEnabled) {
@@ -348,43 +347,36 @@ nsXBLWindowKeyHandler::WalkHandlers(nsID
if (prevent) {
return NS_OK;
}
// XXX Shouldn't we prefer the native key binding rather than our key
// bindings? I.e., should we call WalkHandlersInternal() after this
// block?
if (isEditor && GetEditorKeyBindings()) {
- // get the DOM window we're attached to
- nsCOMPtr<nsIControllers> controllers;
- nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(mTarget);
- if (root) {
- root->GetControllers(getter_AddRefs(controllers));
- }
-
WidgetKeyboardEvent* keyEvent =
aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
MOZ_ASSERT(keyEvent,
"DOM key event's internal event must be WidgetKeyboardEvent");
bool handled = false;
switch (keyEvent->message) {
case NS_KEY_PRESS:
handled = sNativeEditorBindings->KeyPress(*keyEvent,
DoCommandCallback,
- controllers);
+ mTarget);
break;
case NS_KEY_UP:
handled = sNativeEditorBindings->KeyUp(*keyEvent,
DoCommandCallback,
- controllers);
+ mTarget);
break;
case NS_KEY_DOWN:
handled = sNativeEditorBindings->KeyDown(*keyEvent,
DoCommandCallback,
- controllers);
+ mTarget);
break;
default:
MOZ_CRASH("Unknown key message");
}
if (handled)
aKeyEvent->PreventDefault();
--- a/content/xul/content/src/moz.build
+++ b/content/xul/content/src/moz.build
@@ -2,17 +2,17 @@
# 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/.
if CONFIG['MOZ_XUL']:
MSVC_ENABLE_PGO = True
- SOURCES += [
+ UNIFIED_SOURCES += [
'nsXULContextMenuBuilder.cpp',
'nsXULElement.cpp',
'nsXULPopupListener.cpp',
]
FAIL_ON_WARNINGS = True
LOCAL_INCLUDES += [
--- a/content/xul/document/src/moz.build
+++ b/content/xul/document/src/moz.build
@@ -1,20 +1,20 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# 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/.
-SOURCES += [
+UNIFIED_SOURCES += [
'nsXULControllers.cpp',
]
if CONFIG['MOZ_XUL']:
- SOURCES += [
+ UNIFIED_SOURCES += [
'nsXULCommandDispatcher.cpp',
'nsXULContentSink.cpp',
'nsXULPrototypeCache.cpp',
'nsXULPrototypeDocument.cpp',
'XULDocument.cpp',
]
FAIL_ON_WARNINGS = True
--- a/content/xul/document/src/nsXULCommandDispatcher.cpp
+++ b/content/xul/document/src/nsXULCommandDispatcher.cpp
@@ -33,28 +33,28 @@
#include "nsEventDispatcher.h"
#include "nsDOMClassInfoID.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
#ifdef PR_LOGGING
-static PRLogModuleInfo* gLog;
+static PRLogModuleInfo* gCommandLog;
#endif
////////////////////////////////////////////////////////////////////////
nsXULCommandDispatcher::nsXULCommandDispatcher(nsIDocument* aDocument)
: mDocument(aDocument), mUpdaters(nullptr)
{
#ifdef PR_LOGGING
- if (! gLog)
- gLog = PR_NewLogModule("nsXULCommandDispatcher");
+ if (! gCommandLog)
+ gCommandLog = PR_NewLogModule("nsXULCommandDispatcher");
#endif
}
nsXULCommandDispatcher::~nsXULCommandDispatcher()
{
Disconnect();
}
@@ -269,23 +269,23 @@ nsXULCommandDispatcher::AddCommandUpdate
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
#ifdef DEBUG
- if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
+ if (PR_LOG_TEST(gCommandLog, PR_LOG_NOTICE)) {
nsAutoCString eventsC, targetsC, aeventsC, atargetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
CopyUTF16toUTF8(aEvents, aeventsC);
CopyUTF16toUTF8(aTargets, atargetsC);
- PR_LOG(gLog, PR_LOG_NOTICE,
+ PR_LOG(gCommandLog, PR_LOG_NOTICE,
("xulcmd[%p] replace %p(events=%s targets=%s) with (events=%s targets=%s)",
this, aElement,
eventsC.get(),
targetsC.get(),
aeventsC.get(),
atargetsC.get()));
}
#endif
@@ -297,22 +297,22 @@ nsXULCommandDispatcher::AddCommandUpdate
updater->mTargets = aTargets;
return NS_OK;
}
link = &(updater->mNext);
updater = updater->mNext;
}
#ifdef DEBUG
- if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
+ if (PR_LOG_TEST(gCommandLog, PR_LOG_NOTICE)) {
nsAutoCString aeventsC, atargetsC;
CopyUTF16toUTF8(aEvents, aeventsC);
CopyUTF16toUTF8(aTargets, atargetsC);
- PR_LOG(gLog, PR_LOG_NOTICE,
+ PR_LOG(gCommandLog, PR_LOG_NOTICE,
("xulcmd[%p] add %p(events=%s targets=%s)",
this, aElement,
aeventsC.get(),
atargetsC.get()));
}
#endif
// If we get here, this is a new updater. Append it to the list.
@@ -332,21 +332,21 @@ nsXULCommandDispatcher::RemoveCommandUpd
return NS_ERROR_NULL_POINTER;
Updater* updater = mUpdaters;
Updater** link = &mUpdaters;
while (updater) {
if (updater->mElement == aElement) {
#ifdef DEBUG
- if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
+ if (PR_LOG_TEST(gCommandLog, PR_LOG_NOTICE)) {
nsAutoCString eventsC, targetsC;
eventsC.AssignWithConversion(updater->mEvents);
targetsC.AssignWithConversion(updater->mTargets);
- PR_LOG(gLog, PR_LOG_NOTICE,
+ PR_LOG(gCommandLog, PR_LOG_NOTICE,
("xulcmd[%p] remove %p(events=%s targets=%s)",
this, aElement,
eventsC.get(),
targetsC.get()));
}
#endif
*link = updater->mNext;
@@ -398,20 +398,20 @@ nsXULCommandDispatcher::UpdateCommands(c
nsCOMPtr<nsIDocument> document = content->GetDocument();
NS_ASSERTION(document != nullptr, "element has no document");
if (! document)
continue;
#ifdef DEBUG
- if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
+ if (PR_LOG_TEST(gCommandLog, PR_LOG_NOTICE)) {
nsAutoCString aeventnameC;
CopyUTF16toUTF8(aEventName, aeventnameC);
- PR_LOG(gLog, PR_LOG_NOTICE,
+ PR_LOG(gCommandLog, PR_LOG_NOTICE,
("xulcmd[%p] update %p event=%s",
this, content,
aeventnameC.get()));
}
#endif
nsCOMPtr<nsIPresShell> shell = document->GetShell();
if (shell) {
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -53,17 +53,17 @@
#include "nsContentUtils.h"
#include "nsAttrName.h"
#include "nsXMLContentSink.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
#include "nsContentTypeParser.h"
#ifdef PR_LOGGING
-static PRLogModuleInfo* gLog;
+static PRLogModuleInfo* gContentSinkLog;
#endif
//----------------------------------------------------------------------
XULContentSinkImpl::ContextStack::ContextStack()
: mTop(nullptr), mDepth(0)
{
}
@@ -164,18 +164,18 @@ XULContentSinkImpl::XULContentSinkImpl()
mTextLength(0),
mTextSize(0),
mConstrainSize(true),
mState(eInProlog),
mParser(nullptr)
{
#ifdef PR_LOGGING
- if (! gLog)
- gLog = PR_NewLogModule("nsXULContentSink");
+ if (! gContentSinkLog)
+ gContentSinkLog = PR_NewLogModule("nsXULContentSink");
#endif
}
XULContentSinkImpl::~XULContentSinkImpl()
{
NS_IF_RELEASE(mParser); // XXX should've been released by now, unless error.
@@ -491,17 +491,17 @@ XULContentSinkImpl::HandleStartElement(c
break;
case eInDocumentElement:
rv = OpenTag(aAtts, aAttsCount, aLineNumber, nodeInfo);
break;
case eInEpilog:
case eInScript:
- PR_LOG(gLog, PR_LOG_WARNING,
+ PR_LOG(gContentSinkLog, PR_LOG_WARNING,
("xul: warning: unexpected tags in epilog at line %d",
aLineNumber));
rv = NS_ERROR_UNEXPECTED; // XXX
break;
}
// Set the ID attribute atom on the node info object for this node
if (aIndex != -1 && NS_SUCCEEDED(rv)) {
@@ -754,32 +754,32 @@ XULContentSinkImpl::OpenRoot(const PRUni
NS_ASSERTION(mState == eInProlog, "how'd we get here?");
if (mState != eInProlog)
return NS_ERROR_UNEXPECTED;
nsresult rv;
if (aNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XHTML) ||
aNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XUL)) {
- PR_LOG(gLog, PR_LOG_ERROR,
+ PR_LOG(gContentSinkLog, PR_LOG_ERROR,
("xul: script tag not allowed as root content element"));
return NS_ERROR_UNEXPECTED;
}
// Create the element
nsXULPrototypeElement* element;
rv = CreateElement(aNodeInfo, &element);
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
- if (PR_LOG_TEST(gLog, PR_LOG_ERROR)) {
+ if (PR_LOG_TEST(gContentSinkLog, PR_LOG_ERROR)) {
nsAutoString anodeC;
aNodeInfo->GetName(anodeC);
- PR_LOG(gLog, PR_LOG_ERROR,
+ PR_LOG(gContentSinkLog, PR_LOG_ERROR,
("xul: unable to create element '%s' at line %d",
NS_ConvertUTF16toUTF8(anodeC).get(),
-1)); // XXX pass in line number
}
#endif
return rv;
}
@@ -809,20 +809,20 @@ XULContentSinkImpl::OpenTag(const PRUnic
nsresult rv;
// Create the element
nsXULPrototypeElement* element;
rv = CreateElement(aNodeInfo, &element);
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
- if (PR_LOG_TEST(gLog, PR_LOG_ERROR)) {
+ if (PR_LOG_TEST(gContentSinkLog, PR_LOG_ERROR)) {
nsAutoString anodeC;
aNodeInfo->GetName(anodeC);
- PR_LOG(gLog, PR_LOG_ERROR,
+ PR_LOG(gContentSinkLog, PR_LOG_ERROR,
("xul: unable to create element '%s' at line %d",
NS_ConvertUTF16toUTF8(anodeC).get(),
aLineNumber));
}
#endif
return rv;
}
@@ -1029,25 +1029,25 @@ XULContentSinkImpl::AddAttributes(const
rv = NormalizeAttributeString(aAttributes[i * 2], attrs[i].mName);
NS_ENSURE_SUCCESS(rv, rv);
rv = aElement->SetAttrAt(i, nsDependentString(aAttributes[i * 2 + 1]),
mDocumentURL);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef PR_LOGGING
- if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
+ if (PR_LOG_TEST(gContentSinkLog, PR_LOG_DEBUG)) {
nsAutoString extraWhiteSpace;
int32_t cnt = mContextStack.Depth();
while (--cnt >= 0)
extraWhiteSpace.AppendLiteral(" ");
nsAutoString qnameC,valueC;
qnameC.Assign(aAttributes[0]);
valueC.Assign(aAttributes[1]);
- PR_LOG(gLog, PR_LOG_DEBUG,
+ PR_LOG(gContentSinkLog, PR_LOG_DEBUG,
("xul: %.5d. %s %s=%s",
-1, // XXX pass in line number
NS_ConvertUTF16toUTF8(extraWhiteSpace).get(),
NS_ConvertUTF16toUTF8(qnameC).get(),
NS_ConvertUTF16toUTF8(valueC).get()));
}
#endif
}
--- a/db/sqlite3/src/Makefile.in
+++ b/db/sqlite3/src/Makefile.in
@@ -41,78 +41,21 @@ MODULE_OPTIMIZE_FLAGS = -O2
endif
# Force /O2 optimisation on Windows because using the default /O1 causes
# crashes with MSVC2005 and PGO. See bug 719584.
ifeq ($(OS_ARCH),WINNT)
MODULE_OPTIMIZE_FLAGS = -O2
endif
-# -DSQLITE_SECURE_DELETE=1 will cause SQLITE to 0-fill delete data so we
-# don't have to vacuum to make sure the data is not visible in the file.
-# -DSQLITE_ENABLE_FTS3=1 enables the full-text index module.
-# -DSQLITE_CORE=1 statically links that module into the SQLite library.
-# -DSQLITE_DEFAULT_PAGE_SIZE=32768 and SQLITE_MAX_DEFAULT_PAGE_SIZE=32768
-# increases the page size from 1k, see bug 416330. It must be kept in sync with
-# the value of PREF_TS_PAGESIZE_DEFAULT in mozStorageService.cpp. The value can
-# be overridden on a per-platform basis through the use of the PREF_TS_PAGESIZE
-# hidden preference. If that preference is missing or invalid then this value
-# will be used.
-# -DSQLITE_MAX_SCHEMA_RETRY increases the times SQLite may try to reparse
-# statements when the schema changes. This is important when supporting lots of
-# concurrent connections, especially when they use shared cache.
-# Note: Be sure to update the configure.in checks when these change!
-DEFINES = \
- -DSQLITE_SECURE_DELETE=1 \
- -DSQLITE_THREADSAFE=1 \
- -DSQLITE_CORE=1 \
- -DSQLITE_ENABLE_FTS3=1 \
- -DSQLITE_ENABLE_UNLOCK_NOTIFY=1 \
- -DSQLITE_DEFAULT_PAGE_SIZE=32768 \
- -DSQLITE_MAX_DEFAULT_PAGE_SIZE=32768 \
- -DSQLITE_MAX_SCHEMA_RETRY=25 \
- $(NULL)
-
-# -DSQLITE_ENABLE_LOCKING_STYLE=1 to help with AFP folders
-ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
-DEFINES += -DSQLITE_ENABLE_LOCKING_STYLE=1
-endif
-
-# Turn on SQLite's assertions in debug builds.
-ifdef MOZ_DEBUG
-DEFINES += -DSQLITE_DEBUG=1
-endif
-
# disable PGO for Sun Studio
ifdef SOLARIS_SUNPRO_CC
NO_PROFILE_GUIDED_OPTIMIZE = 1
endif
-ifeq ($(OS_ARCH),OS2)
-ifdef MOZ_OS2_HIGH_MEMORY
-DEFINES += -DOS2_HIGH_MEMORY
-endif
-endif
-
-ifeq ($(OS_TARGET),Android)
-# default to user readable only to fit Android security model
-DEFINES += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600
-endif
-
-# Force using malloc_usable_size when building with jemalloc because _msize
-# causes assertions on Win64. See bug 719579.
-ifeq ($(OS_ARCH),WINNT)
-ifdef MOZ_MEMORY
-DEFINES += \
- -DHAVE_MALLOC_USABLE_SIZE \
- -DSQLITE_WITHOUT_MSIZE \
- $(NULL)
-endif
-endif
-
include $(topsrcdir)/config/rules.mk
# next line allows use of MOZ_OBJDIR in .mozconfig with older gcc on BeOS, maybe others
LOCAL_INCLUDES += -I$(srcdir)
ifeq ($(OS_ARCH),OS2)
ADD_TO_DEF_FILE = $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) \
$(srcdir)/sqlite.def | sed -e '1,/^EXPORTS$$/ d' -e 's,sqlite3,_\0,' \
--- a/db/sqlite3/src/moz.build
+++ b/db/sqlite3/src/moz.build
@@ -14,8 +14,51 @@ LIBRARY_NAME = 'mozsqlite3'
SOURCES += [
'sqlite3.c',
]
if CONFIG['MOZ_FOLD_LIBS']:
FORCE_STATIC_LIB = True
else:
FORCE_SHARED_LIB = True
+
+# -DSQLITE_SECURE_DELETE=1 will cause SQLITE to 0-fill delete data so we
+# don't have to vacuum to make sure the data is not visible in the file.
+# -DSQLITE_ENABLE_FTS3=1 enables the full-text index module.
+# -DSQLITE_CORE=1 statically links that module into the SQLite library.
+# -DSQLITE_DEFAULT_PAGE_SIZE=32768 and SQLITE_MAX_DEFAULT_PAGE_SIZE=32768
+# increases the page size from 1k, see bug 416330. It must be kept in sync with
+# the value of PREF_TS_PAGESIZE_DEFAULT in mozStorageService.cpp. The value can
+# be overridden on a per-platform basis through the use of the PREF_TS_PAGESIZE
+# hidden preference. If that preference is missing or invalid then this value
+# will be used.
+# -DSQLITE_MAX_SCHEMA_RETRY increases the times SQLite may try to reparse
+# statements when the schema changes. This is important when supporting lots of
+# concurrent connections, especially when they use shared cache.
+# Note: Be sure to update the configure.in checks when these change!
+for var in ('SQLITE_SECURE_DELETE', 'SQLITE_THREADSAFE', 'SQLITE_CORE',
+ 'SQLITE_ENABLE_FTS3', 'SQLITE_ENABLE_UNLOCK_NOTIFY'):
+ DEFINES[var] = 1
+
+DEFINES['SQLITE_DEFAULT_PAGE_SIZE'] = 32768
+DEFINES['SQLITE_MAX_DEFAULT_PAGE_SIZE'] = 32768
+DEFINES['SQLITE_MAX_SCHEMA_RETRY'] = 25
+
+# -DSQLITE_ENABLE_LOCKING_STYLE=1 to help with AFP folders
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ DEFINES['SQLITE_ENABLE_LOCKING_STYLE'] = 1
+
+# Turn on SQLite's assertions in debug builds.
+if CONFIG['MOZ_DEBUG']:
+ DEFINES['SQLITE_DEBUG'] = 1
+
+if CONFIG['OS_ARCH'] == 'OS2' and CONFIG['MOZ_OS2_HIGH_MEMORY']:
+ DEFINES['OS2_HIGH_MEMORY'] = True
+
+if CONFIG['OS_TARGET'] == 'Android':
+ # default to user readable only to fit Android security model
+ DEFINES['SQLITE_DEFAULT_FILE_PERMISSIONS'] = '0600'
+
+# Force using malloc_usable_size when building with jemalloc because _msize
+# causes assertions on Win64. See bug 719579.
+if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_MEMORY']:
+ DEFINES['HAVE_MALLOC_USABLE_SIZE'] = True
+ DEFINES['SQLITE_WITHOUT_MSIZE'] = True
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -1,22 +1,10 @@
# 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/.
-ifdef MOZ_JSDEBUGGER
-DEFINES += -DMOZ_JSDEBUGGER
-endif
-
-ifdef MOZ_B2G_RIL
-DEFINES += -DMOZ_B2G_RIL
-endif
-
-ifdef MOZ_B2G_FM
-DEFINES += -DMOZ_B2G_FM
-endif
-
include $(topsrcdir)/config/rules.mk
ifdef MOZ_X11
CXXFLAGS += $(TK_CFLAGS)
LDFLAGS += $(TK_LIBS)
endif
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -159,8 +159,11 @@ include('/ipc/chromium/chromium-config.m
FINAL_LIBRARY = 'gklayout'
LOCAL_INCLUDES += [
'/js/xpconnect/src',
'/js/xpconnect/wrappers',
'/xpcom/ds',
]
+for var in ('MOZ_JSDEBUGGER', 'MOZ_B2G_RIL', 'MOZ_B2G_FM'):
+ if CONFIG[var]:
+ DEFINES[var] = True
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1,15 +1,15 @@
/* -*- Mode: C++; 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/. */
#include "mozilla/layers/CompositorParent.h"
-#include "mozilla/layers/PLayerTransactionChild.h"
+#include "mozilla/layers/LayerTransactionChild.h"
#include "nsPresContext.h"
#include "nsDOMClassInfoID.h"
#include "nsError.h"
#include "nsIDOMEvent.h"
#include "nsDOMWindowUtils.h"
#include "nsQueryContentEventResult.h"
#include "CompositionStringSynthesizer.h"
#include "nsGlobalWindow.h"
@@ -78,16 +78,17 @@
#include "nsWidgetsCID.h"
#include "FrameLayerBuilder.h"
#include "nsDisplayList.h"
#include "nsROCSSPrimitiveValue.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIInterfaceRequestorUtils.h"
#include "GeckoProfiler.h"
+#include "mozilla/Preferences.h"
#ifdef XP_WIN
#undef GetClassName
#endif
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layers;
@@ -1476,42 +1477,48 @@ nsDOMWindowUtils::SuppressEventHandling(
doc->SuppressEventHandling();
} else {
doc->UnsuppressEventHandlingAndFireEvents(true);
}
return NS_OK;
}
-NS_IMETHODIMP
-nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
-{
+static nsresult
+getScrollXYAppUnits(nsWeakPtr mWindow, bool aFlushLayout, nsPoint& aScrollPos) {
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
NS_ENSURE_STATE(doc);
if (aFlushLayout) {
doc->FlushPendingNotifications(Flush_Layout);
}
- nsPoint scrollPos(0,0);
nsIPresShell *presShell = doc->GetShell();
if (presShell) {
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
if (sf) {
- scrollPos = sf->GetScrollPosition();
+ aScrollPos = sf->GetScrollPosition();
}
}
-
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
+{
+ nsPoint scrollPos(0,0);
+ nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
+ NS_ENSURE_SUCCESS(rv, rv);
*aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
*aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::ScrollToCSSPixelsApproximate(float aX, float aY, bool* aRetVal)
@@ -1526,16 +1533,28 @@ nsDOMWindowUtils::ScrollToCSSPixelsAppro
if (aRetVal) {
*aRetVal = (sf != nullptr);
}
return NS_OK;
}
NS_IMETHODIMP
+nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
+{
+ nsPoint scrollPos(0,0);
+ nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
+ NS_ENSURE_SUCCESS(rv, rv);
+ *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
+ *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
int32_t* aHeight)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
*aWidth = 0;
@@ -2237,60 +2256,55 @@ nsDOMWindowUtils::StartFrameTimeRecordin
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
- *startIndex = mgr->StartFrameTimeRecording();
+ const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
+ const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
+ uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
+ bufferSize = std::min(bufferSize, kRecordingMaxSize);
+ bufferSize = std::max(bufferSize, kRecordingMinSize);
+ *startIndex = mgr->StartFrameTimeRecording(bufferSize);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
- float **paintTimes,
uint32_t *frameCount,
float **frameIntervals)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(frameCount);
NS_ENSURE_ARG_POINTER(frameIntervals);
- NS_ENSURE_ARG_POINTER(paintTimes);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
nsTArray<float> tmpFrameIntervals;
- nsTArray<float> tmpPaintTimes;
- mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals, tmpPaintTimes);
+ mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
*frameCount = tmpFrameIntervals.Length();
*frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float*));
- *paintTimes = (float*)nsMemory::Alloc(*frameCount * sizeof(float*));
/* copy over the frame intervals and paint times into the arrays we just allocated */
for (uint32_t i = 0; i < *frameCount; i++) {
(*frameIntervals)[i] = tmpFrameIntervals[i];
-#ifndef MOZ_WIDGET_GONK
- (*paintTimes)[i] = tmpPaintTimes[i];
-#else
- // Waiting for bug 830475 to work on B2G.
- (*paintTimes)[i] = 0;
-#endif
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::BeginTabSwitch()
{
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -65,17 +65,17 @@ nsHistory::WrapObject(JSContext* aCx, JS
{
return HistoryBinding::Wrap(aCx, aScope, this);
}
uint32_t
nsHistory::GetLength(ErrorResult& aRv) const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
- if (!win || !win->IsCurrentInnerWindow()) {
+ if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return 0;
}
// Get session History from docshell
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
if (!sHistory) {
@@ -101,17 +101,17 @@ nsHistory::GetState(JSContext* aCx, Erro
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
}
- if (!win->IsCurrentInnerWindow()) {
+ if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return JS::UndefinedValue();
}
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(win->GetExtantDoc());
if (!doc) {
@@ -141,17 +141,17 @@ nsHistory::GetState(JSContext* aCx, Erro
return JS::UndefinedValue();
}
void
nsHistory::Go(int32_t aDelta, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
- if (!win || !win->IsCurrentInnerWindow()) {
+ if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
if (!aDelta) {
nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(GetDocShell()));
@@ -197,17 +197,17 @@ nsHistory::Go(int32_t aDelta, ErrorResul
// from GotoIndex() can lead to exceptions and a possible leak
// of history length
}
void
nsHistory::Back(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
- if (!win || !win->IsCurrentInnerWindow()) {
+ if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
@@ -218,17 +218,17 @@ nsHistory::Back(ErrorResult& aRv)
webNav->GoBack();
}
void
nsHistory::Forward(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
- if (!win || !win->IsCurrentInnerWindow()) {
+ if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
@@ -263,17 +263,17 @@ nsHistory::PushOrReplaceState(JSContext*
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
- if (!win->IsCurrentInnerWindow()) {
+ if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
// Check that PushState hasn't been pref'ed off.
if (!Preferences::GetBool(aReplace ? sAllowReplaceStatePrefStr :
sAllowPushStatePrefStr, false)) {
--- a/dom/base/nsIJSEventListener.h
+++ b/dom/base/nsIJSEventListener.h
@@ -9,18 +9,18 @@
#include "nsIScriptContext.h"
#include "xpcpublic.h"
#include "nsIDOMEventListener.h"
#include "nsIAtom.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/EventHandlerBinding.h"
#define NS_IJSEVENTLISTENER_IID \
-{ 0x92f9212b, 0xa6aa, 0x4867, \
- { 0x93, 0x8a, 0x56, 0xbe, 0x17, 0x67, 0x4f, 0xd4 } }
+{ 0x5077b12a, 0x5a1f, 0x4583, \
+ { 0xbb, 0xa7, 0x78, 0x84, 0x94, 0x0e, 0x5e, 0xff } }
class nsEventHandler
{
public:
typedef mozilla::dom::EventHandlerNonNull EventHandlerNonNull;
typedef mozilla::dom::OnBeforeUnloadEventHandlerNonNull
OnBeforeUnloadEventHandlerNonNull;
typedef mozilla::dom::OnErrorEventHandlerNonNull OnErrorEventHandlerNonNull;
@@ -167,32 +167,25 @@ private:
//
// Note, mTarget is a raw pointer and the owner of the nsIJSEventListener object
// is expected to call Disconnect()!
class nsIJSEventListener : public nsIDOMEventListener
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSEVENTLISTENER_IID)
- nsIJSEventListener(nsIScriptContext* aContext, JSObject* aScopeObject,
+ nsIJSEventListener(JSObject* aScopeObject,
nsISupports *aTarget, nsIAtom* aType,
const nsEventHandler& aHandler)
- : mContext(aContext), mScopeObject(aScopeObject), mEventName(aType),
- mHandler(aHandler)
+ : mScopeObject(aScopeObject), mEventName(aType), mHandler(aHandler)
{
nsCOMPtr<nsISupports> base = do_QueryInterface(aTarget);
mTarget = base.get();
}
- // Can return null if we already have a handler.
- nsIScriptContext *GetEventContext() const
- {
- return mContext;
- }
-
nsISupports *GetEventTarget() const
{
return mTarget;
}
void Disconnect()
{
mTarget = nullptr;
@@ -221,21 +214,20 @@ public:
nsIAtom* EventName() const
{
return mEventName;
}
// Set a handler for this event listener. The handler must already
// be bound to the right target.
- void SetHandler(const nsEventHandler& aHandler, nsIScriptContext* aContext,
+ void SetHandler(const nsEventHandler& aHandler,
JS::Handle<JSObject*> aScopeObject)
{
mHandler.SetHandler(aHandler);
- mContext = aContext;
UpdateScopeObject(aScopeObject);
}
void SetHandler(mozilla::dom::EventHandlerNonNull* aHandler)
{
mHandler.SetHandler(aHandler);
}
void SetHandler(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
{
@@ -247,17 +239,16 @@ public:
}
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return 0;
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
- // - mContext
// - mTarget
//
// The following members are not measured:
// - mScopeObject: because they're measured by the JS memory
// reporters
// - mHandler: may be shared with others
// - mEventName: shared with others
}
@@ -272,26 +263,24 @@ protected:
{
NS_ASSERTION(!mTarget, "Should have called Disconnect()!");
}
// Update our mScopeObject; we have to make sure we properly handle
// the hold/drop stuff, so have to do it in nsJSEventListener.
virtual void UpdateScopeObject(JS::Handle<JSObject*> aScopeObject) = 0;
- nsCOMPtr<nsIScriptContext> mContext;
JS::Heap<JSObject*> mScopeObject;
nsISupports* mTarget;
nsCOMPtr<nsIAtom> mEventName;
nsEventHandler mHandler;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSEventListener, NS_IJSEVENTLISTENER_IID)
/* factory function. aHandler must already be bound to aTarget.
aContext is allowed to be null if aHandler is already set up.
*/
-nsresult NS_NewJSEventListener(nsIScriptContext *aContext,
- JSObject* aScopeObject, nsISupports* aTarget,
+nsresult NS_NewJSEventListener(JSObject* aScopeObject, nsISupports* aTarget,
nsIAtom* aType, const nsEventHandler& aHandler,
nsIJSEventListener **aReturn);
#endif // nsIJSEventListener_h__
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -331,16 +331,27 @@ public:
// window of that outer. Only call this on inner windows.
bool IsCurrentInnerWindow() const
{
MOZ_ASSERT(IsInnerWindow(),
"It doesn't make sense to call this on outer windows.");
return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
}
+ // Returns true if the document of this window is the active document. This
+ // is not identical to IsCurrentInnerWindow() because document.open() will
+ // keep the same document active but create a new window.
+ bool HasActiveDocument()
+ {
+ return IsCurrentInnerWindow() ||
+ (GetOuterWindow() &&
+ GetOuterWindow()->GetCurrentInnerWindow() &&
+ GetOuterWindow()->GetCurrentInnerWindow()->GetDoc() == mDoc);
+ }
+
bool IsOuterWindow() const
{
return !IsInnerWindow();
}
virtual bool WouldReuseInnerWindow(nsIDocument *aNewDocument) = 0;
/**
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -444,23 +444,16 @@ ReportGhostWindowsEnumerator(nsUint64Has
if (NS_FAILED(rv) && NS_SUCCEEDED(data->rv)) {
data->rv = rv;
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
-nsWindowMemoryReporter::GetName(nsACString &aName)
-{
- aName.AssignLiteral("window-objects");
- return NS_OK;
-}
-
-NS_IMETHODIMP
nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure)
{
nsGlobalWindow::WindowByIdTable* windowsById =
nsGlobalWindow::GetWindowsTable();
NS_ENSURE_TRUE(windowsById, NS_OK);
// Hold on to every window in memory so that window objects can't be
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -13,16 +13,17 @@ support-files =
[test_document.all_unqualified.html]
[test_domcursor.html]
[test_domrequest.html]
[test_e4x_for_each.html]
[test_error.html]
[test_gsp-qualified.html]
[test_gsp-quirks.html]
[test_gsp-standards.html]
+[test_history_document_open.html]
[test_innersize_scrollport.html]
[test_messageChannel.html]
[test_messageChannel_cloning.html]
[test_messageChannel_pingpong.html]
[test_messageChannel_post.html]
[test_messageChannel_pref.html]
[test_messageChannel_start.html]
[test_messageChannel_transferable.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_history_document_open.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=943418
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 943418</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 943418 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function continueTest(f) {
+ // Make sure we're the entry script so errors get reported here
+ setTimeout(finishTest, 0, f);
+ }
+
+ function finishTest(f) {
+ f();
+ ok(true, "Got here");
+ SimpleTest.finish();
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=943418">Mozilla Bug 943418</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe src="data:text/html,<script>function f() { history.length; } window.onload = function() { var f = window.f; document.open(); document.close(); parent.continueTest(f); }</script>" </script>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -161,17 +161,17 @@ CallbackObject::CallSetup::ShouldRethrow
}
CallbackObject::CallSetup::~CallSetup()
{
// First things first: if we have a JSContext, report any pending
// errors on it, unless we were told to re-throw them.
if (mCx) {
bool dealtWithPendingException = false;
- if (mExceptionHandling == eRethrowContentExceptions ||
+ if ((mCompartment && mExceptionHandling == eRethrowContentExceptions) ||
mExceptionHandling == eRethrowExceptions) {
// Restore the old context options
JS::ContextOptionsRef(mCx) = mSavedJSContextOptions;
mErrorResult.MightThrowJSException();
if (JS_IsExceptionPending(mCx)) {
JS::Rooted<JS::Value> exn(mCx);
if (JS_GetPendingException(mCx, &exn) &&
ShouldRethrowException(exn)) {
--- a/dom/bluetooth/Makefile.in
+++ b/dom/bluetooth/Makefile.in
@@ -14,30 +14,22 @@
VPATH += $(srcdir)/ipc
ifneq (,$(MOZ_B2G_BT))
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
ifdef MOZ_B2G_BT_BLUEZ
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS)
-DEFINES += -DMOZ_B2G_BT_BLUEZ
-else
-ifdef MOZ_B2G_BT_BLUEDROID
-DEFINES += -DMOZ_B2G_BT_BLUEDROID
-endif #MOZ_B2G_BT_BLUEDROID
endif #MOZ_B2G_BT_BLUEZ
else
ifdef MOZ_ENABLE_DBUS
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS)
CFLAGS += $(MOZ_DBUS_GLIB_CFLAGS)
CXXFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) -DHAVE_PTHREADS
-DEFINES += -DMOZ_BLUETOOTH_DBUS
endif #MOZ_ENABLE_DBUS
endif #MOZ_WIDGET_TOOLKIT
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
# subdirectory.
LOCAL_INCLUDES += $(VPATH:%=-I%)
endif #MOZ_B2G_BT
-
-include $(topsrcdir)/config/rules.mk
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -40,35 +40,38 @@ if CONFIG['MOZ_B2G_BT']:
'bluez/gonk/BluetoothGonkService.cpp',
'bluez/linux/BluetoothDBusService.cpp',
]
LOCAL_INCLUDES += [
'bluez',
'bluez/gonk',
'bluez/linux',
]
+ DEFINES['MOZ_B2G_BT_BLUEZ'] = True
elif CONFIG['MOZ_B2G_BT_BLUEDROID']:
SOURCES += [
'bluedroid/BluetoothA2dpManager.cpp',
'bluedroid/BluetoothHfpManager.cpp',
'bluedroid/gonk/BluetoothServiceBluedroid.cpp',
]
LOCAL_INCLUDES += [
'bluedroid',
'bluedroid/gonk',
]
+ DEFINES['MOZ_B2G_BT_BLUEDROID'] = True
elif CONFIG['MOZ_ENABLE_DBUS']:
SOURCES += [
'bluez/BluetoothHfpManager.cpp',
'bluez/linux/BluetoothDBusService.cpp',
]
LOCAL_INCLUDES += [
'bluez',
'bluez/linux',
]
+ DEFINES['MOZ_BLUETOOTH_DBUS'] = True
FINAL_LIBRARY = 'gklayout'
EXPORTS.mozilla.dom.bluetooth.ipc += [
'ipc/BluetoothMessageUtils.h',
]
EXPORTS.mozilla.dom.bluetooth += [
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -38,17 +38,17 @@ interface nsIDOMFile;
interface nsIFile;
interface nsIDOMTouch;
interface nsIDOMClientRect;
interface nsIURI;
interface nsIDOMEventTarget;
interface nsIRunnable;
interface nsICompositionStringSynthesizer;
-[scriptable, uuid(928356ff-26b2-434e-a7ce-c1a660162d81)]
+[scriptable, uuid(3772df78-905f-40cf-952f-e4954c63d0ec)]
interface nsIDOMWindowUtils : nsISupports {
/**
* Image animation mode of the window. When this attribute's value
* is changed, the implementation should set all images in the window
* to the given value. That is, when set to kDontAnimMode, all images
* will stop animating. The attribute's value must be one of the
* animationMode values from imgIContainer.
@@ -648,16 +648,24 @@ interface nsIDOMWindowUtils : nsISupport
* Returns the scroll position of the window's currently loaded document.
*
* @param aFlushLayout flushes layout if true. Otherwise, no flush occurs.
* @see nsIDOMWindow::scrollX/Y
*/
void getScrollXY(in boolean aFlushLayout, out long aScrollX, out long aScrollY);
/**
+ * Returns the scroll position of the window's currently loaded document.
+ *
+ * @param aFlushLayout flushes layout if true. Otherwise, no flush occurs.
+ * @see nsIDOMWindow::scrollX/Y
+ */
+ void getScrollXYFloat(in boolean aFlushLayout, out float aScrollX, out float aScrollY);
+
+ /**
* Sets the scroll position of the root scroll frame of the window.
* Returns true on success, false on error (if the window didn't have a root
* scroll frame).
*/
boolean scrollToCSSPixelsApproximate(in float aX, in float aY);
/**
* Returns the scrollbar width of the window's scroll frame.
@@ -1039,17 +1047,17 @@ interface nsIDOMWindowUtils : nsISupport
/**
* True if the layer manager for the widget associated with this window is
* forwarding layers to a remote compositor, false otherwise. Throws an
* error if there is no widget associated with this window.
*/
readonly attribute boolean layerManagerRemote;
/**
- * Record (and return) frame-intervals and paint-times for frames which were presented
+ * Record (and return) frame-intervals for frames which were presented
* between calling StartFrameTimeRecording and StopFrameTimeRecording.
*
* - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late
* (elements were overwritten since Start), result is considered invalid and hence empty.
* - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent).
* Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize.
* - Note: the first frame-interval may be longer than expected because last frame
* might have been presented some time before calling StartFrameTimeRecording.
@@ -1061,17 +1069,16 @@ interface nsIDOMWindowUtils : nsISupport
void startFrameTimeRecording([retval] out unsigned long startIndex);
/**
* Returns number of recorded frames since startIndex was issued,
* and allocates+populates 2 arraye with the recorded data.
* - Allocation is infallible. Should be released even if size is 0.
*/
void stopFrameTimeRecording(in unsigned long startIndex,
- [optional, array, size_is(frameCount)] out float paintTimes,
[optional] out unsigned long frameCount,
[retval, array, size_is(frameCount)] out float frameIntervals);
/**
* Signals that we're begining to tab switch. This is used by painting code to
* determine total tab switch time.
*/
void beginTabSwitch();
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -1,21 +1,7 @@
# 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 $(topsrcdir)/config/rules.mk
-DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
-
-ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
-DEFINES += -DMOZ_ENABLE_FREETYPE
-endif
-
-ifdef MOZ_PERMISSIONS
-DEFINES += -DMOZ_PERMISSIONS
-endif
-
-ifdef MOZ_CHILD_PERMISSIONS
-DEFINES += -DMOZ_CHILD_PERMISSIONS
-endif
-
CXXFLAGS += $(TK_CFLAGS)
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -650,16 +650,18 @@ TabChild::HandlePossibleViewportChange()
if (viewportInfo.GetDefaultZoom().scale < 0.01f) {
viewportInfo.SetDefaultZoom(metrics.CalculateIntrinsicScale());
}
CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom();
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
defaultZoom <= viewportInfo.GetMaxZoom());
metrics.mZoom = defaultZoom;
+
+ metrics.mScrollId = viewId;
}
metrics.mDisplayPort = AsyncPanZoomController::CalculatePendingDisplayPort(
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
@@ -1554,78 +1556,71 @@ TabChild::RecvUpdateFrame(const FrameMet
bool
TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
{
if (!mGlobal || !mTabChildGlobal) {
return true;
}
- CSSRect cssCompositedRect = aFrameMetrics.CalculateCompositedRectInCssPixels();
+ nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
+
+ FrameMetrics newMetrics = aFrameMetrics;
+ APZCCallbackHelper::UpdateRootFrame(utils, newMetrics);
+
+ CSSRect cssCompositedRect = newMetrics.CalculateCompositedRectInCssPixels();
// The BrowserElementScrolling helper must know about these updated metrics
// for other functions it performs, such as double tap handling.
// Note, %f must not be used because it is locale specific!
nsCString data;
- data.AppendPrintf("{ \"x\" : %d", NS_lround(aFrameMetrics.mScrollOffset.x));
- data.AppendPrintf(", \"y\" : %d", NS_lround(aFrameMetrics.mScrollOffset.y));
+ data.AppendPrintf("{ \"x\" : %d", NS_lround(newMetrics.mScrollOffset.x));
+ data.AppendPrintf(", \"y\" : %d", NS_lround(newMetrics.mScrollOffset.y));
data.AppendLiteral(", \"viewport\" : ");
data.AppendLiteral("{ \"width\" : ");
- data.AppendFloat(aFrameMetrics.mViewport.width);
+ data.AppendFloat(newMetrics.mViewport.width);
data.AppendLiteral(", \"height\" : ");
- data.AppendFloat(aFrameMetrics.mViewport.height);
+ data.AppendFloat(newMetrics.mViewport.height);
data.AppendLiteral(" }");
data.AppendLiteral(", \"displayPort\" : ");
data.AppendLiteral("{ \"x\" : ");
- data.AppendFloat(aFrameMetrics.mDisplayPort.x);
+ data.AppendFloat(newMetrics.mDisplayPort.x);
data.AppendLiteral(", \"y\" : ");
- data.AppendFloat(aFrameMetrics.mDisplayPort.y);
+ data.AppendFloat(newMetrics.mDisplayPort.y);
data.AppendLiteral(", \"width\" : ");
- data.AppendFloat(aFrameMetrics.mDisplayPort.width);
+ data.AppendFloat(newMetrics.mDisplayPort.width);
data.AppendLiteral(", \"height\" : ");
- data.AppendFloat(aFrameMetrics.mDisplayPort.height);
+ data.AppendFloat(newMetrics.mDisplayPort.height);
data.AppendLiteral(" }");
data.AppendLiteral(", \"compositionBounds\" : ");
- data.AppendPrintf("{ \"x\" : %d", aFrameMetrics.mCompositionBounds.x);
- data.AppendPrintf(", \"y\" : %d", aFrameMetrics.mCompositionBounds.y);
- data.AppendPrintf(", \"width\" : %d", aFrameMetrics.mCompositionBounds.width);
- data.AppendPrintf(", \"height\" : %d", aFrameMetrics.mCompositionBounds.height);
+ data.AppendPrintf("{ \"x\" : %d", newMetrics.mCompositionBounds.x);
+ data.AppendPrintf(", \"y\" : %d", newMetrics.mCompositionBounds.y);
+ data.AppendPrintf(", \"width\" : %d", newMetrics.mCompositionBounds.width);
+ data.AppendPrintf(", \"height\" : %d", newMetrics.mCompositionBounds.height);
data.AppendLiteral(" }");
data.AppendLiteral(", \"cssPageRect\" : ");
data.AppendLiteral("{ \"x\" : ");
- data.AppendFloat(aFrameMetrics.mScrollableRect.x);
+ data.AppendFloat(newMetrics.mScrollableRect.x);
data.AppendLiteral(", \"y\" : ");
- data.AppendFloat(aFrameMetrics.mScrollableRect.y);
+ data.AppendFloat(newMetrics.mScrollableRect.y);
data.AppendLiteral(", \"width\" : ");
- data.AppendFloat(aFrameMetrics.mScrollableRect.width);
+ data.AppendFloat(newMetrics.mScrollableRect.width);
data.AppendLiteral(", \"height\" : ");
- data.AppendFloat(aFrameMetrics.mScrollableRect.height);
+ data.AppendFloat(newMetrics.mScrollableRect.height);
data.AppendLiteral(" }");
data.AppendLiteral(", \"cssCompositedRect\" : ");
data.AppendLiteral("{ \"width\" : ");
data.AppendFloat(cssCompositedRect.width);
data.AppendLiteral(", \"height\" : ");
data.AppendFloat(cssCompositedRect.height);
data.AppendLiteral(" }");
data.AppendLiteral(" }");
DispatchMessageManagerMessage(NS_LITERAL_STRING("Viewport:Change"), data);
- nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
-
- APZCCallbackHelper::UpdateRootFrame(utils, aFrameMetrics);
-
- mLastMetrics = aFrameMetrics;
-
- // ScrollWindowTo() can make some small adjustments to the offset before
- // actually scrolling the window. To ensure that the scroll offset stored
- // in mLastMetrics is the same as the offset stored in the window,
- // re-query the latter.
- CSSIntPoint actualScrollOffset;
- utils->GetScrollXY(false, &actualScrollOffset.x, &actualScrollOffset.y);
- mLastMetrics.mScrollOffset = actualScrollOffset;
+ mLastMetrics = newMetrics;
return true;
}
bool
TabChild::RecvHandleDoubleTap(const CSSIntPoint& aPoint)
{
if (!mGlobal || !mTabChildGlobal) {
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -103,8 +103,16 @@ LOCAL_INCLUDES += [
'/layout/base',
'/netwerk/base/src',
'/toolkit/xre',
'/uriloader/exthandler',
'/widget/xpwidgets',
'/xpcom/base',
]
+DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX']
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk', 'qt'):
+ DEFINES['MOZ_ENABLE_FREETYPE'] = True
+
+for var in ('MOZ_PERMISSIONS', 'MOZ_CHILD_PERMISSIONS'):
+ if CONFIG[var]:
+ DEFINES[var] = True
--- a/dom/locales/en-US/chrome/layout/css.properties
+++ b/dom/locales/en-US/chrome/layout/css.properties
@@ -61,28 +61,29 @@ PEAttSelNoClose=Expected ']' to terminat
PEAttSelBadValue=Expected identifier or string for value in attribute selector but found '%1$S'.
PEPseudoSelEOF=name of pseudo-class or pseudo-element
PEPseudoSelBadName=Expected identifier for pseudo-class or pseudo-element but found '%1$S'.
PEPseudoSelNonFunc=Function token for non-function pseudo-class or pseudo-element, or the other way around, when reading '%1$S'.
PEPseudoSelNotPE=Expected pseudo-element but found '%1$S'.
PEPseudoSelDoubleNot=Negation pseudo-class can't be negated '%1$S'.
PEPseudoSelPEInNot=Pseudo-elements can't be negated '%1$S'.
PEPseudoSelNewStyleOnly=This pseudo-element must use the "::" form: '%1$S'.
-PEPseudoSelTrailing=Found trailing token after pseudo-element, which must be the last part of a selector: '%1$S'.
+PEPseudoSelTrailing=Expected end of selector or a user action pseudo-class after pseudo-element but found '%1$S'.
PEPseudoSelMultiplePE=Extra pseudo-element '%1$S'.
PEPseudoSelUnknown=Unknown pseudo-class or pseudo-element '%1$S'.
PENegationEOF=selector within negation
PENegationBadInner=Malformed simple selector as negation pseudo-class argument '%1$S'.
PENegationNoClose=Missing closing ')' in negation pseudo-class '%1$S'.
PENegationBadArg=Missing argument in negation pseudo-class '%1$S'.
PEPseudoClassArgEOF=argument to pseudo-class selector
PEPseudoClassArgNotIdent=Expected identifier for pseudo-class parameter but found '%1$S'.
PEPseudoClassArgNotNth=Expected part of argument to pseudo-class but found '%1$S'.
PEPseudoClassNoClose=Missing closing ')' in pseudo-class, found '%1$S' instead.
PEPseudoClassNoArg=Missing argument in pseudo-class '%1$S'.
+PEPseudoClassNotUserAction=Expected end of selector or a user action pseudo-class after pseudo-element but found pseudo-class '%1$S'.
PESelectorEOF=selector
PEBadDeclBlockStart=Expected '{' to begin declaration block but found '%1$S'.
PEColorEOF=color
PEColorNotColor=Expected color but found '%1$S'.
PEColorComponentEOF=color component
PEExpectedPercent=Expected a percentage but found '%1$S'.
PEExpectedInt=Expected an integer but found '%1$S'.
PEColorBadRGBContents=Expected number or percentage in rgb() but found '%1$S'.
--- a/dom/plugins/ipc/hangui/Makefile.in
+++ b/dom/plugins/ipc/hangui/Makefile.in
@@ -1,20 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
OS_LIBS = $(call EXPAND_LIBNAME,comctl32)
RCINCLUDE = HangUIDlg.rc
-DEFINES += \
- -DNS_NO_XPCOM \
- $(NULL)
-
STL_FLAGS = \
-D_HAS_EXCEPTIONS=0 \
$(NULL)
MOZ_GLUE_LDFLAGS =
include $(topsrcdir)/config/rules.mk
--- a/dom/plugins/ipc/hangui/moz.build
+++ b/dom/plugins/ipc/hangui/moz.build
@@ -9,8 +9,9 @@ FAIL_ON_WARNINGS = True
PROGRAM = 'plugin-hang-ui'
UNIFIED_SOURCES += [
'MiniShmChild.cpp',
'PluginHangUIChild.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
+DEFINES['NS_NO_XPCOM'] = True
--- a/dom/src/events/nsJSEventListener.cpp
+++ b/dom/src/events/nsJSEventListener.cpp
@@ -37,22 +37,21 @@ static EventListenerCounter sEventListen
#endif
using namespace mozilla;
using namespace mozilla::dom;
/*
* nsJSEventListener implementation
*/
-nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext,
- JSObject* aScopeObject,
+nsJSEventListener::nsJSEventListener(JSObject* aScopeObject,
nsISupports *aTarget,
nsIAtom* aType,
const nsEventHandler& aHandler)
- : nsIJSEventListener(aContext, aScopeObject, aTarget, aType, aHandler)
+ : nsIJSEventListener(aScopeObject, aTarget, aType, aHandler)
{
if (mScopeObject) {
mozilla::HoldJSObjects(this);
}
}
nsJSEventListener::~nsJSEventListener()
{
@@ -76,31 +75,29 @@ nsJSEventListener::UpdateScopeObject(JS:
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSEventListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSEventListener)
if (tmp->mScopeObject) {
tmp->mScopeObject = nullptr;
mozilla::DropJSObjects(tmp);
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
}
tmp->mHandler.ForgetHandler();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSEventListener)
if (MOZ_UNLIKELY(cb.WantDebugInfo()) && tmp->mEventName) {
nsAutoCString name;
name.AppendLiteral("nsJSEventListener handlerName=");
name.Append(
NS_ConvertUTF16toUTF8(nsDependentAtomString(tmp->mEventName)).get());
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name.get());
} else {
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsJSEventListener, tmp->mRefCnt.get())
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mHandler.Ptr())
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSEventListener)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScopeObject)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
@@ -143,23 +140,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSEve
bool
nsJSEventListener::IsBlackForCC()
{
// We can claim to be black if all the things we reference are
// effectively black already.
if ((!mScopeObject || !xpc_IsGrayGCThing(mScopeObject)) &&
(!mHandler.HasEventHandler() ||
!mHandler.Ptr()->HasGrayCallable())) {
- if (!mContext) {
- // Well, we certainly won't be marking it, so move on!
- return true;
- }
- nsIScriptGlobalObject* sgo =
- static_cast<nsJSContext*>(mContext.get())->GetCachedGlobalObject();
- return sgo && sgo->IsBlackForCC();
+ return true;
}
return false;
}
nsresult
nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
{
nsCOMPtr<EventTarget> target = do_QueryInterface(mTarget);
@@ -259,23 +250,20 @@ nsJSEventListener::HandleEvent(nsIDOMEve
return NS_OK;
}
/*
* Factory functions
*/
nsresult
-NS_NewJSEventListener(nsIScriptContext* aContext, JSObject* aScopeObject,
+NS_NewJSEventListener(JSObject* aScopeObject,
nsISupports*aTarget, nsIAtom* aEventType,
const nsEventHandler& aHandler,
nsIJSEventListener** aReturn)
{
- MOZ_ASSERT(aContext || aHandler.HasEventHandler(),
- "Must have a handler if we don't have an nsIScriptContext");
NS_ENSURE_ARG(aEventType || !NS_IsMainThread());
nsJSEventListener* it =
- new nsJSEventListener(aContext, aScopeObject, aTarget, aEventType,
- aHandler);
+ new nsJSEventListener(aScopeObject, aTarget, aEventType, aHandler);
NS_ADDREF(*aReturn = it);
return NS_OK;
}
--- a/dom/src/events/nsJSEventListener.h
+++ b/dom/src/events/nsJSEventListener.h
@@ -16,19 +16,18 @@
#include "nsIScriptContext.h"
#include "nsCycleCollectionParticipant.h"
// nsJSEventListener interface
// misnamed - JS no longer has exclusive rights over this interface!
class nsJSEventListener : public nsIJSEventListener
{
public:
- nsJSEventListener(nsIScriptContext* aContext, JSObject* aScopeObject,
- nsISupports* aTarget, nsIAtom* aType,
- const nsEventHandler& aHandler);
+ nsJSEventListener(JSObject* aScopeObject, nsISupports* aTarget,
+ nsIAtom* aType, const nsEventHandler& aHandler);
virtual ~nsJSEventListener();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsIDOMEventListener interface
NS_DECL_NSIDOMEVENTLISTENER
// nsIJSEventListener
--- a/dom/tests/mochitest/dom-level1-core/test_nodeappendchildchildexists.html
+++ b/dom/tests/mochitest/dom-level1-core/test_nodeappendchildchildexists.html
@@ -69,17 +69,16 @@ function loadComplete() {
}
}
var docName = 'nodeappendchildchildexists';
window.doc = window;
-SimpleTest.expectAssertions(1); // Bug 892638
SimpleTest.waitForExplicitFinish();
addLoadEvent(setUpPage);
/**
*
If the "newChild" is already in the tree, it is first
removed before the new one is appended.
--- a/dom/tests/mochitest/dom-level1-core/test_nodeinsertbeforenewchildexists.html
+++ b/dom/tests/mochitest/dom-level1-core/test_nodeinsertbeforenewchildexists.html
@@ -69,17 +69,16 @@ function loadComplete() {
}
}
var docName = 'nodeinsertbeforenewchildexists';
window.doc = window;
-SimpleTest.expectAssertions(1); // Bug 892638
SimpleTest.waitForExplicitFinish();
addLoadEvent(setUpPage);
/**
*
If the "newChild" is already in the tree, the
"insertBefore(newChild,refChild)" method must first
--- a/dom/tests/mochitest/dom-level1-core/test_nodereplacechildnewchildexists.html
+++ b/dom/tests/mochitest/dom-level1-core/test_nodereplacechildnewchildexists.html
@@ -69,17 +69,16 @@ function loadComplete() {
}
}
var docName = 'nodereplacechildnewchildexists';
window.doc = window;
-SimpleTest.expectAssertions(1); // Bug 892638
SimpleTest.waitForExplicitFinish();
addLoadEvent(setUpPage);
/**
*
Retrieve the second employee and replace its TWELFTH
child(address) with its SECOND child(employeeId). After the
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -15,20 +15,37 @@ https://bugzilla.mozilla.org/show_bug.cg
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 766694 **/
-// This is a list of all interfaces that are exposed to every webpage. Please only
-// add things to this list with great care.
+// This is a list of all interfaces that are exposed to every webpage.
+// Please only add things to this list with great care and proper review
+// from the associated module peers.
-// IMPORTANT: Do not change this list without review from a JavaScript Engine peer!
+// This file lists global interfaces we want exposed and verifies they
+// are what we intend. Each entry in the arrays below can either be a
+// simple string with the interface name, or an object with a 'name'
+// property giving the interface name as a string, and additional
+// properties which quality the exposure of that interface. For example:
+//
+// [
+// "AGlobalInterface",
+// {name: "ExperimentalThing", release: false},
+// {name: "OptionalThing", pref: "some.thing.enabled"},
+// {name: "FancyControl", xbl: true},
+// ];
+//
+// See createInterfaceMap() below for a complete list of properties.
+
+// IMPORTANT: Do not change this list without review from
+// a JavaScript Engine peer!
var ecmaGlobals =
[
"Array",
"ArrayBuffer",
"Boolean",
"DataView",
"Date",
"Error",
@@ -65,36 +82,37 @@ var ecmaGlobals =
"TypeError",
"Uint16Array",
"Uint32Array",
"Uint8Array",
"Uint8ClampedArray",
"URIError",
"WeakMap",
];
-// IMPORTANT: Do not change this list without review from a JavaScript Engine peer!
+// IMPORTANT: Do not change the list above without review from
+// a JavaScript Engine peer!
-// IMPORTANT: Do not change this list without review from a DOM peer, except to
-// remove items from it!
+// IMPORTANT: Do not change the list below without review from a DOM peer,
+// except to remove items from it!
//
// This is a list of interfaces that were prefixed with 'moz' instead of 'Moz'.
// We should never to that again, interfaces in the DOM start with an uppercase
// letter. If you think you need to add an interface here, DON'T. Rename your
// interface.
var legacyMozPrefixedInterfaces =
[
"mozContact",
"mozRTCIceCandidate",
"mozRTCPeerConnection",
"mozRTCSessionDescription",
];
-// IMPORTANT: Do not change this list without review from a DOM peer, except to
-// remove items from it!
+// IMPORTANT: Do not change the list above without review from a DOM peer,
+// except to remove items from it!
-// IMPORTANT: Do not change this list without review from a DOM peer!
+// IMPORTANT: Do not change the list below without review from a DOM peer!
var interfaceNamesInGlobalScope =
[
"AnalyserNode",
"AnimationEvent",
"ArchiveRequest",
"Attr",
"Audio",
"AudioBuffer",
@@ -625,18 +643,18 @@ var interfaceNamesInGlobalScope =
{name: "XULControlElement", xbl: true},
{name: "XULControllers", xbl: true},
{name: "XULDocument", xbl: true},
{name: "XULElement", xbl: true},
{name: "XULLabeledControlElement", xbl: true},
{name: "XULPopupElement", xbl: true},
{name: "XULTemplateBuilder", xbl: true},
{name: "XULTreeBuilder", xbl: true},
- ]
-// IMPORTANT: Do not change this list without review from a DOM peer!
+ ];
+// IMPORTANT: Do not change the list above without review from a DOM peer!
function createInterfaceMap(isXBLScope) {
var prefs = SpecialPowers.Services.prefs;
var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
var isNightly = version.endsWith("a1");
var isRelease = !version.contains("a");
var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
var isB2G = !isDesktop && !navigator.userAgent.contains("Android");
--- a/dom/workers/Principal.cpp
+++ b/dom/workers/Principal.cpp
@@ -4,26 +4,25 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Principal.h"
#include "jsapi.h"
BEGIN_WORKERS_NAMESPACE
-namespace {
-
-JSPrincipals gPrincipal = {
- 1
-#ifdef DEBUG
- , kJSPrincipalsDebugToken
-#endif
-};
-
-} // anonymous namespace
-
JSPrincipals*
GetWorkerPrincipal()
{
- return &gPrincipal;
+ static Atomic<uint32_t> sInitialized(0);
+ static JSPrincipals sPrincipal;
+
+ uint32_t isInitialized = sInitialized.exchange(1);
+ if (!isInitialized) {
+ sPrincipal.refcount = 1;
+#ifdef DEBUG
+ sPrincipal.debugToken = kJSPrincipalsDebugToken;
+#endif
+ }
+ return &sPrincipal;
}
END_WORKERS_NAMESPACE
--- a/embedding/tests/winEmbed/Makefile.in
+++ b/embedding/tests/winEmbed/Makefile.in
@@ -29,17 +29,16 @@
RESFILE = winEmbed.res
LIBS = \
$(DEPTH)/profile/dirserviceprovider/standalone/$(LIB_PREFIX)profdirserviceprovidersa_s.$(LIB_SUFFIX) \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)
-DEFINES += -DXPCOM_GLUE
STL_FLAGS=
OS_LIBS += $(call EXPAND_LIBNAME,ole32 comdlg32 shell32 version)
include $(topsrcdir)/config/rules.mk
#
# Control the default heap size.
--- a/embedding/tests/winEmbed/moz.build
+++ b/embedding/tests/winEmbed/moz.build
@@ -8,8 +8,10 @@ PROGRAM = 'winEmbed'
SOURCES += [
'WebBrowserChrome.cpp',
'WindowCreator.cpp',
'winEmbed.cpp',
]
XPI_NAME = 'winembed'
+
+DEFINES['XPCOM_GLUE'] = True
--- a/extensions/spellcheck/hunspell/src/Makefile.in
+++ b/extensions/spellcheck/hunspell/src/Makefile.in
@@ -1,18 +1,12 @@
# 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 MOZ_NATIVE_HUNSPELL
-# This variable is referenced in configure.in. Make sure to change that file
-# too if you need to change this variable.
-DEFINES = -DHUNSPELL_STATIC
-endif
-
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(topsrcdir)/extensions/spellcheck/src
ifdef MOZ_NATIVE_HUNSPELL
# MOZ_HUNSPELL_CFLAGS is extracted through pkgconfig during configure,
# even though the variable doesn't show up in configure.in.
CXXFLAGS += $(MOZ_HUNSPELL_CFLAGS)
--- a/extensions/spellcheck/hunspell/src/moz.build
+++ b/extensions/spellcheck/hunspell/src/moz.build
@@ -18,10 +18,13 @@ if not CONFIG['MOZ_NATIVE_HUNSPELL']:
'filemgr.cpp',
'hashmgr.cpp',
'hunspell.cpp',
'hunzip.cpp',
'phonet.cpp',
'replist.cpp',
'suggestmgr.cpp',
]
+ # This variable is referenced in configure.in. Make sure to change that file
+ # too if you need to change this variable.
+ DEFINES['HUNSPELL_STATIC'] = True
FINAL_LIBRARY = 'spellchecker'
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -48,16 +48,17 @@ typedef struct CGContext *CGContextRef;
namespace mozilla {
namespace gfx {
class SourceSurface;
class DataSourceSurface;
class DrawTarget;
class DrawEventRecorder;
+class FilterNode;
struct NativeSurface {
NativeSurfaceType mType;
SurfaceFormat mFormat;
void *mSurface;
};
struct NativeFont {
@@ -351,17 +352,21 @@ public:
virtual int32_t Stride() = 0;
/*
* This function is called after modifying the data on the source surface
* directly through the data pointer.
*/
virtual void MarkDirty() {}
- virtual TemporaryRef<DataSourceSurface> GetDataSurface() { RefPtr<DataSourceSurface> temp = this; return temp.forget(); }
+ /*
+ * Returns a DataSourceSurface with the same data as this one, but
+ * guaranteed to have surface->GetType() == SURFACE_DATA.
+ */
+ virtual TemporaryRef<DataSourceSurface> GetDataSurface();
};
/* This is an abstract object that accepts path segments. */
class PathSink : public RefCounted<PathSink>
{
public:
virtual ~PathSink() {}
@@ -614,16 +619,29 @@ public:
*/
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
+ * Draw the output of a FilterNode to the DrawTarget.
+ *
+ * aNode FilterNode to draw
+ * aSourceRect Source rectangle in FilterNode space to draw
+ * aDestPoint Destination point on the DrawTarget to draw the
+ * SourceRectangle of the filter output to
+ */
+ virtual void DrawFilter(FilterNode *aNode,
+ const Rect &aSourceRect,
+ const Point &aDestPoint,
+ const DrawOptions &aOptions = DrawOptions()) = 0;
+
+ /*
* Blend a surface to the draw target with a shadow. The shadow is drawn as a
* gaussian blur using a specified sigma. The shadow is clipped to the size
* of the input surface, so the input surface should contain a transparent
* border the size of the approximate coverage of the blur (3 * aSigma).
* NOTE: This function works in device space!
*
* aSurface Source surface to draw.
* aDest Destination point that this drawing operation should draw to.
@@ -857,16 +875,24 @@ public:
* aExtendNone This describes how to extend the stop color outside of the
* gradient area.
*/
virtual TemporaryRef<GradientStops>
CreateGradientStops(GradientStop *aStops,
uint32_t aNumStops,
ExtendMode aExtendMode = EXTEND_CLAMP) const = 0;
+ /*
+ * Create a FilterNode object that can be used to apply a filter to various
+ * inputs.
+ *
+ * aType Type of filter node to be created.
+ */
+ virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) = 0;
+
const Matrix &GetTransform() const { return mTransform; }
/*
* Set a transform on the surface, this transform is applied at drawing time
* to both the mask and source of the operation.
*/
virtual void SetTransform(const Matrix &aTransform)
{ mTransform = aTransform; mTransformDirty = true; }
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -388,21 +388,22 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& a
if (size.isValid()) {
mSurfaceAllocationSize = size.value();
}
}
}
AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
int32_t aStride,
- float aSigma)
+ float aSigmaX,
+ float aSigmaY)
: mRect(int32_t(aRect.x), int32_t(aRect.y),
int32_t(aRect.width), int32_t(aRect.height)),
mSpreadRadius(),
- mBlurRadius(CalculateBlurRadius(Point(aSigma, aSigma))),
+ mBlurRadius(CalculateBlurRadius(Point(aSigmaX, aSigmaY))),
mStride(aStride),
mSurfaceAllocationSize(-1)
{
IntRect intRect;
if (aRect.ToIntRect(&intRect)) {
CheckedInt<int32_t> minDataSize = CheckedInt<int32_t>(intRect.width)*intRect.height;
if (minDataSize.isValid()) {
mSurfaceAllocationSize = minDataSize.value();
--- a/gfx/2d/Blur.h
+++ b/gfx/2d/Blur.h
@@ -61,17 +61,18 @@ public:
AlphaBoxBlur(const Rect& aRect,
const IntSize& aSpreadRadius,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect);
AlphaBoxBlur(const Rect& aRect,
int32_t aStride,
- float aSigma);
+ float aSigmaX,
+ float aSigmaY);
~AlphaBoxBlur();
/**
* Return the size, in pixels, of the 8-bit alpha surface we'd use.
*/
IntSize GetSize();
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DataSourceSurface.cpp
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#include "2D.h"
+#include "DataSourceSurfaceWrapper.h"
+
+namespace mozilla {
+namespace gfx {
+
+TemporaryRef<DataSourceSurface>
+DataSourceSurface::GetDataSurface()
+{
+ RefPtr<DataSourceSurface> temp;
+ if (GetType() == SURFACE_DATA) {
+ temp = this;
+ } else {
+ temp = new DataSourceSurfaceWrapper(this);
+ }
+ return temp;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/DataSourceSurfaceWrapper.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#ifndef MOZILLA_GFX_DATASOURCESURFACEWRAPPER_H_
+#define MOZILLA_GFX_DATASOURCESURFACEWRAPPER_H_
+
+#include "2D.h"
+
+namespace mozilla {
+namespace gfx {
+
+// Wraps a DataSourceSurface and forwards all methods except for GetType(),
+// from which it always returns SURFACE_DATA.
+class DataSourceSurfaceWrapper : public DataSourceSurface
+{
+public:
+ DataSourceSurfaceWrapper(DataSourceSurface *aSurface)
+ : mSurface(aSurface)
+ {}
+
+ virtual SurfaceType GetType() const MOZ_OVERRIDE { return SURFACE_DATA; }
+
+ virtual uint8_t *GetData() MOZ_OVERRIDE { return mSurface->GetData(); }
+ virtual int32_t Stride() MOZ_OVERRIDE { return mSurface->Stride(); }
+ virtual IntSize GetSize() const MOZ_OVERRIDE { return mSurface->GetSize(); }
+ virtual SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mSurface->GetFormat(); }
+ virtual bool IsValid() const MOZ_OVERRIDE { return mSurface->IsValid(); }
+ virtual void MarkDirty() { mSurface->MarkDirty(); }
+
+private:
+ RefPtr<DataSourceSurface> mSurface;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_DATASOURCESURFACEWRAPPER_H_ */
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -6,16 +6,17 @@
#include "DrawTargetCG.h"
#include "SourceSurfaceCG.h"
#include "Rect.h"
#include "ScaledFontMac.h"
#include "Tools.h"
#include <vector>
#include <algorithm>
#include "MacIOSurface.h"
+#include "FilterNodeSoftware.h"
using namespace std;
//CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
// A private API that Cairo has been using for a long time
CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
@@ -203,26 +204,34 @@ DrawTargetCG::CreateSourceSurfaceFromDat
if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
return nullptr;
}
return newSurf;
}
+// This function returns a retained CGImage that needs to be released after
+// use. The reason for this is that we want to either reuse an existing CGImage
+// or create a new one.
static CGImageRef
-GetImageFromSourceSurface(SourceSurface *aSurface)
+GetRetainedImageFromSourceSurface(SourceSurface *aSurface)
{
if (aSurface->GetType() == SURFACE_COREGRAPHICS_IMAGE)
- return static_cast<SourceSurfaceCG*>(aSurface)->GetImage();
+ return CGImageRetain(static_cast<SourceSurfaceCG*>(aSurface)->GetImage());
else if (aSurface->GetType() == SURFACE_COREGRAPHICS_CGCONTEXT)
- return static_cast<SourceSurfaceCGContext*>(aSurface)->GetImage();
- else if (aSurface->GetType() == SURFACE_DATA)
- return static_cast<DataSourceSurfaceCG*>(aSurface)->GetImage();
- abort();
+ return CGImageRetain(static_cast<SourceSurfaceCGContext*>(aSurface)->GetImage());
+
+ if (aSurface->GetType() == SURFACE_DATA) {
+ DataSourceSurface* dataSource = static_cast<DataSourceSurface*>(aSurface);
+ return CreateCGImage(nullptr, dataSource->GetData(), dataSource->GetSize(),
+ dataSource->Stride(), dataSource->GetFormat());
+ }
+
+ MOZ_CRASH("unsupported source surface");
}
TemporaryRef<SourceSurface>
DrawTargetCG::OptimizeSourceSurface(SourceSurface *aSurface) const
{
return nullptr;
}
@@ -274,52 +283,65 @@ void
DrawTargetCG::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aDrawOptions)
{
MarkChanged();
- CGImageRef image;
- CGImageRef subimage = nullptr;
CGContextSaveGState(mCg);
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
UnboundnessFixer fixer;
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AA_NONE);
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
- image = GetImageFromSourceSurface(aSurface);
+ CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
+
/* we have two options here:
* - create a subimage -- this is slower
* - fancy things with clip and different dest rects */
- {
- subimage = CGImageCreateWithImageInRect(image, RectToCGRect(aSource));
- image = subimage;
- }
+ CGImageRef subimage = CGImageCreateWithImageInRect(image, RectToCGRect(aSource));
+ CGImageRelease(image);
CGContextScaleCTM(cg, 1, -1);
CGRect flippedRect = CGRectMake(aDest.x, -(aDest.y + aDest.height),
aDest.width, aDest.height);
CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(aSurfOptions.mFilter));
- CGContextDrawImage(cg, flippedRect, image);
+ CGContextDrawImage(cg, flippedRect, subimage);
fixer.Fix(mCg);
CGContextRestoreGState(mCg);
CGImageRelease(subimage);
}
+TemporaryRef<FilterNode>
+DrawTargetCG::CreateFilter(FilterType aType)
+{
+ return FilterNodeSoftware::Create(aType);
+}
+
+void
+DrawTargetCG::DrawFilter(FilterNode *aNode,
+ const Rect &aSourceRect,
+ const Point &aDestPoint,
+ const DrawOptions &aOptions)
+{
+ FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
+ filter->Draw(this, aSourceRect, aDestPoint, aOptions);
+}
+
static CGColorRef ColorToCGColor(CGColorSpaceRef aColorSpace, const Color& aColor)
{
CGFloat components[4] = {aColor.r, aColor.g, aColor.b, aColor.a};
return CGColorCreate(aColorSpace, components);
}
class GradientStopsCG : public GradientStops
{
@@ -654,17 +676,17 @@ isGradient(const Pattern &aPattern)
/* CoreGraphics patterns ignore the userspace transform so
* we need to multiply it in */
static CGPatternRef
CreateCGPattern(const Pattern &aPattern, CGAffineTransform aUserSpace)
{
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
// XXX: is .get correct here?
- CGImageRef image = GetImageFromSourceSurface(pat.mSurface.get());
+ CGImageRef image = GetRetainedImageFromSourceSurface(pat.mSurface.get());
CGFloat xStep, yStep;
switch (pat.mExtendMode) {
case EXTEND_CLAMP:
// The 1 << 22 comes from Webkit see Pattern::createPlatformPattern() in PatternCG.cpp for more info
xStep = static_cast<CGFloat>(1 << 22);
yStep = static_cast<CGFloat>(1 << 22);
break;
case EXTEND_REFLECT:
@@ -691,17 +713,17 @@ CreateCGPattern(const Pattern &aPattern,
{static_cast<CGFloat>(CGImageGetWidth(image)), static_cast<CGFloat>(CGImageGetHeight(image))}
};
CGAffineTransform transform =
CGAffineTransformConcat(CGAffineTransformConcat(CGAffineTransformMakeScale(1,
-1),
GfxMatrixToCGAffineTransform(pat.mMatrix)),
aUserSpace);
transform = CGAffineTransformTranslate(transform, 0, -static_cast<float>(CGImageGetHeight(image)));
- return CGPatternCreate(CGImageRetain(image), bounds, transform, xStep, yStep, kCGPatternTilingConstantSpacing,
+ return CGPatternCreate(image, bounds, transform, xStep, yStep, kCGPatternTilingConstantSpacing,
true, &patternCallbacks);
}
static void
SetFillFromPattern(CGContextRef cg, CGColorSpaceRef aColorSpace, const Pattern &aPattern)
{
assert(!isGradient(aPattern));
if (aPattern.GetType() == PATTERN_COLOR) {
@@ -756,27 +778,26 @@ SetStrokeFromPattern(CGContextRef cg, CG
void
DrawTargetCG::MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aDrawOptions)
{
MarkChanged();
- CGImageRef image;
CGContextSaveGState(mCg);
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
UnboundnessFixer fixer;
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AA_NONE);
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
- image = GetImageFromSourceSurface(aMask);
+ CGImageRef image = GetRetainedImageFromSourceSurface(aMask);
// use a negative-y so that the mask image draws right ways up
CGContextScaleCTM(cg, 1, -1);
IntSize size = aMask->GetSize();
CGContextClipToMask(cg, CGRectMake(aOffset.x, -(aOffset.y + size.height), size.width, size.height), image);
@@ -785,16 +806,18 @@ DrawTargetCG::MaskSurface(const Pattern
// we shouldn't need to clip to an additional rectangle
// as the cliping to the mask should be sufficient.
DrawGradient(cg, aSource, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
} else {
SetFillFromPattern(cg, mColorSpace, aSource);
CGContextFillRect(cg, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
}
+ CGImageRelease(image);
+
fixer.Fix(mCg);
CGContextRestoreGState(mCg);
}
void
@@ -818,27 +841,28 @@ DrawTargetCG::FillRect(const Rect &aRect
CGContextClipToRect(cg, RectToCGRect(aRect));
DrawGradient(cg, aPattern, RectToCGRect(aRect));
} else {
if (aPattern.GetType() == PATTERN_SURFACE && static_cast<const SurfacePattern&>(aPattern).mExtendMode != EXTEND_REPEAT) {
// SetFillFromPattern can handle this case but using CGContextDrawImage
// should give us better performance, better output, smaller PDF and
// matches what cairo does.
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
- CGImageRef image = GetImageFromSourceSurface(pat.mSurface.get());
+ CGImageRef image = GetRetainedImageFromSourceSurface(pat.mSurface.get());
CGContextClipToRect(cg, RectToCGRect(aRect));
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
CGContextTranslateCTM(cg, 0, CGImageGetHeight(image));
CGContextScaleCTM(cg, 1, -1);
CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image));
CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
CGContextDrawImage(cg, imageRect, image);
+ CGImageRelease(image);
} else {
SetFillFromPattern(cg, mColorSpace, aPattern);
CGContextFillRect(cg, RectToCGRect(aRect));
}
}
fixer.Fix(mCg);
CGContextRestoreGState(mCg);
@@ -1161,28 +1185,25 @@ CGContextResetClip(CGContextRef);
void
DrawTargetCG::CopySurface(SourceSurface *aSurface,
const IntRect& aSourceRect,
const IntPoint &aDestination)
{
MarkChanged();
- CGImageRef image;
- CGImageRef subimage = nullptr;
if (aSurface->GetType() == SURFACE_COREGRAPHICS_IMAGE ||
aSurface->GetType() == SURFACE_COREGRAPHICS_CGCONTEXT) {
- image = GetImageFromSourceSurface(aSurface);
+ CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
+
/* we have two options here:
* - create a subimage -- this is slower
* - fancy things with clip and different dest rects */
- {