Backout bug 537857
This commit is contained in:
Коммит
db81ae547a
|
@ -181,7 +181,7 @@ pref("browser.shell.checkDefaultBrowser", true);
|
|||
// 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
|
||||
// The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
|
||||
pref("browser.startup.page", 1);
|
||||
pref("browser.startup.homepage", "resource:/browserconfig.properties");
|
||||
pref("browser.startup.homepage", "chrome://branding/locale/browserconfig.properties");
|
||||
|
||||
pref("browser.enable_automatic_image_resizing", true);
|
||||
pref("browser.chrome.site_icons", true);
|
||||
|
|
|
@ -4264,7 +4264,7 @@ var XULBrowserWindow = {
|
|||
FullZoom.onLocationChange(gBrowser.currentURI, true);
|
||||
var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
|
||||
var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
|
||||
// use a pseudo-object instead of a (potentially non-existing) channel for getting
|
||||
// use a pseudo-object instead of a (potentially nonexistent) channel for getting
|
||||
// a correct error message - and make sure that the UI is always either in
|
||||
// loading (STATE_START) or done (STATE_STOP) mode
|
||||
this.onStateChange(
|
||||
|
@ -4775,7 +4775,7 @@ var gHomeButton = {
|
|||
// use this if we can't find the pref
|
||||
if (!url) {
|
||||
var SBS = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
|
||||
var configBundle = SBS.createBundle("resource:/browserconfig.properties");
|
||||
var configBundle = SBS.createBundle("chrome://branding/locale/browserconfig.properties");
|
||||
url = configBundle.GetStringFromName(this.prefDomain);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,13 +168,19 @@ const COPYCOL_IMAGE = COL_IMAGE_ADDRESS;
|
|||
var gMetaView = new pageInfoTreeView(COPYCOL_META_CONTENT);
|
||||
var gImageView = new pageInfoTreeView(COPYCOL_IMAGE);
|
||||
|
||||
gImageView.getCellProperties = function(row, col, props) {
|
||||
var aserv = Components.classes[ATOM_CONTRACTID]
|
||||
.getService(Components.interfaces.nsIAtomService);
|
||||
|
||||
var atomSvc = Components.classes["@mozilla.org/atom-service;1"]
|
||||
.getService(Components.interfaces.nsIAtomService);
|
||||
gImageView._ltrAtom = atomSvc.getAtom("ltr");
|
||||
gImageView._brokenAtom = atomSvc.getAtom("broken");
|
||||
|
||||
gImageView.getCellProperties = function(row, col, props) {
|
||||
if (gImageView.data[row][COL_IMAGE_SIZE] == gStrings.unknown &&
|
||||
!/^https:/.test(gImageView.data[row][COL_IMAGE_ADDRESS]))
|
||||
props.AppendElement(aserv.getAtom("broken"));
|
||||
props.AppendElement(this._brokenAtom);
|
||||
|
||||
if (col.element.id == "image-address")
|
||||
props.AppendElement(this._ltrAtom);
|
||||
};
|
||||
|
||||
var gImageHash = { };
|
||||
|
|
|
@ -45,11 +45,3 @@ include $(DEPTH)/config/autoconf.mk
|
|||
DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(FINAL_TARGET)/browserconfig.properties
|
||||
|
||||
install::
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(DESTDIR)$(mozappdir)/browserconfig.properties
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
# Nightly branding only exists in en-US
|
||||
locale/branding/brand.dtd (en-US/brand.dtd)
|
||||
* locale/branding/brand.properties (en-US/brand.properties)
|
||||
* locale/branding/browserconfig.properties (browserconfig.properties)
|
||||
|
|
|
@ -45,11 +45,3 @@ include $(DEPTH)/config/autoconf.mk
|
|||
DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(FINAL_TARGET)/browserconfig.properties
|
||||
|
||||
install::
|
||||
@$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
|
||||
$(srcdir)/browserconfig.properties > $(DESTDIR)$(mozappdir)/browserconfig.properties
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
# Unofficial branding only exists in en-US
|
||||
locale/branding/brand.dtd (en-US/brand.dtd)
|
||||
* locale/branding/brand.properties (en-US/brand.properties)
|
||||
* locale/branding/browserconfig.properties (browserconfig.properties)
|
||||
|
|
|
@ -109,7 +109,7 @@ var tests = [
|
|||
},
|
||||
|
||||
{
|
||||
desc: "JSON restore: nonexisting file should fail",
|
||||
desc: "JSON restore: nonexistent file should fail",
|
||||
currTopic: NSIOBSERVER_TOPIC_BEGIN,
|
||||
finalTopic: NSIOBSERVER_TOPIC_FAILED,
|
||||
data: NSIOBSERVER_DATA_JSON,
|
||||
|
@ -163,7 +163,7 @@ var tests = [
|
|||
},
|
||||
|
||||
{
|
||||
desc: "HTML restore: nonexisting file should fail",
|
||||
desc: "HTML restore: nonexistent file should fail",
|
||||
currTopic: NSIOBSERVER_TOPIC_BEGIN,
|
||||
finalTopic: NSIOBSERVER_TOPIC_FAILED,
|
||||
data: NSIOBSERVER_DATA_HTML,
|
||||
|
@ -217,7 +217,7 @@ var tests = [
|
|||
},
|
||||
|
||||
{
|
||||
desc: "HTML initial restore: nonexisting file should fail",
|
||||
desc: "HTML initial restore: nonexistent file should fail",
|
||||
currTopic: NSIOBSERVER_TOPIC_BEGIN,
|
||||
finalTopic: NSIOBSERVER_TOPIC_FAILED,
|
||||
data: NSIOBSERVER_DATA_HTML_INIT,
|
||||
|
@ -279,7 +279,7 @@ var tests = [
|
|||
},
|
||||
|
||||
{
|
||||
desc: "HTML restore into folder: nonexisting file should fail",
|
||||
desc: "HTML restore into folder: nonexistent file should fail",
|
||||
currTopic: NSIOBSERVER_TOPIC_BEGIN,
|
||||
finalTopic: NSIOBSERVER_TOPIC_FAILED,
|
||||
data: NSIOBSERVER_DATA_HTML,
|
||||
|
|
|
@ -8,11 +8,11 @@ var testdata = {
|
|||
};
|
||||
|
||||
function test() {
|
||||
// test getting non-existing values
|
||||
// test getting nonexistent values
|
||||
var itemValue = Application.prefs.getValue(testdata.missing, "default");
|
||||
is(itemValue, "default", "Check 'Application.prefs.getValue' for non-existing item");
|
||||
is(itemValue, "default", "Check 'Application.prefs.getValue' for nonexistent item");
|
||||
|
||||
is(Application.prefs.get(testdata.missing), null, "Check 'Application.prefs.get' for non-existing item");
|
||||
is(Application.prefs.get(testdata.missing), null, "Check 'Application.prefs.get' for nonexistent item");
|
||||
|
||||
// test setting and getting a value
|
||||
Application.prefs.setValue(testdata.dummy, "dummy");
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
function test() {
|
||||
// test for existence of values
|
||||
var hasItem = Application.storage.has("fuel-test-missing");
|
||||
is(hasItem, false, "Check 'Application.storage.has' for non-existing item");
|
||||
is(hasItem, false, "Check 'Application.storage.has' for nonexistent item");
|
||||
Application.storage.set("fuel-test", "dummy");
|
||||
hasItem = Application.storage.has("fuel-test");
|
||||
is(hasItem, true, "Check 'Application.storage.has' for existing item");
|
||||
|
||||
// test getting non-existing and existing values
|
||||
// test getting nonexistent and existing values
|
||||
var itemValue = Application.storage.get("fuel-test-missing", "default");
|
||||
is(itemValue, "default", "Check 'Application.storage.get' for non-existing item");
|
||||
is(itemValue, "default", "Check 'Application.storage.get' for nonexistent item");
|
||||
itemValue = Application.storage.get("fuel-test", "default");
|
||||
is(itemValue, "dummy", "Check 'Application.storage.get' for existing item");
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
@BINPATH@/chrome/@AB_CD@.jar
|
||||
@BINPATH@/chrome/@AB_CD@.manifest
|
||||
@BINPATH@/@PREF_DIR@/firefox-l10n.js
|
||||
@BINPATH@/browserconfig.properties
|
||||
@BINPATH@/searchplugins/*
|
||||
@BINPATH@/defaults/profile/bookmarks.html
|
||||
@BINPATH@/defaults/profile/localstore.rdf
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
@DLL_PREFIX@xpistub@DLL_SUFFIX@
|
||||
@DLL_PREFIX@zlib@DLL_SUFFIX@
|
||||
LICENSE
|
||||
browserconfig.properties
|
||||
chrome.manifest
|
||||
chrome/US.jar
|
||||
chrome/app-chrome.manifest
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
%include browser.css
|
||||
%undef WINSTRIPE_AERO
|
||||
|
||||
%if 0
|
||||
@media all and (-moz-windows-compositor) {
|
||||
#main-window:not(:-moz-lwtheme) {
|
||||
-moz-appearance: -moz-win-glass;
|
||||
|
@ -73,7 +72,6 @@
|
|||
text-shadow: white -1px -1px .5em, white -1px 1px .5em, white 1px 1px .5em, white 1px -1px .5em;
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
#print-preview-toolbar:not(:-moz-lwtheme) {
|
||||
|
|
|
@ -113,7 +113,6 @@ MOZ_VTUNE = @MOZ_VTUNE@
|
|||
MOZ_TRACEVIS = @MOZ_TRACEVIS@
|
||||
DEHYDRA_PATH = @DEHYDRA_PATH@
|
||||
|
||||
MOZ_XPCTOOLS = @MOZ_XPCTOOLS@
|
||||
NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
|
||||
USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
|
||||
INCREMENTAL_LINKER = @INCREMENTAL_LINKER@
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#Compares with: foo1.class foo2.class (if -d specified, checks in 'dir',
|
||||
# otherwise assumes .class files in same directory as .java files)
|
||||
#Returns: list of input arguments which are newer than corresponding class
|
||||
#files (non-existent class files are considered to be real old :-)
|
||||
#files (nonexistent class files are considered to be real old :-)
|
||||
#
|
||||
|
||||
$found = 1;
|
||||
|
|
|
@ -1518,7 +1518,7 @@ normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
|
|||
else
|
||||
# assume MSYS
|
||||
# We use 'pwd -W' to get DOS form of the path. However, since the given path
|
||||
# could be a file or a non-existent path, we cannot call 'pwd -W' directly
|
||||
# could be a file or a nonexistent path, we cannot call 'pwd -W' directly
|
||||
# on the path. Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
|
||||
# on it, then merge with the rest of the path.
|
||||
root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
|
||||
|
|
|
@ -212,6 +212,7 @@ dbus/dbus-glib.h
|
|||
dbus/dbus-glib-lowlevel.h
|
||||
ddeml.h
|
||||
Debug.h
|
||||
deque
|
||||
dem.h
|
||||
descrip.h
|
||||
Devices.h
|
||||
|
@ -274,6 +275,7 @@ freetype/tttables.h
|
|||
freetype/t1tables.h
|
||||
fribidi/fribidi.h
|
||||
FSp_fopen.h
|
||||
fstream
|
||||
fstream.h
|
||||
ft2build.h
|
||||
fts.h
|
||||
|
@ -329,6 +331,7 @@ IOKit/pwr_mgt/IOPMLib.h
|
|||
iomanip
|
||||
iostream
|
||||
iostream.h
|
||||
iterator
|
||||
jar.h
|
||||
JavaControl.h
|
||||
JavaEmbedding/JavaControl.h
|
||||
|
@ -607,6 +610,7 @@ pthread.h
|
|||
pwd.h
|
||||
Python.h
|
||||
QDOffscreen.h
|
||||
queue
|
||||
Quickdraw.h
|
||||
QuickDraw.h
|
||||
QuickTimeComponents.h
|
||||
|
@ -641,6 +645,7 @@ security.h
|
|||
secutil.h
|
||||
semaphore.h
|
||||
servprov.h
|
||||
set
|
||||
setjmp.h
|
||||
SFNTLayoutTypes.h
|
||||
SFNTTypes.h
|
||||
|
@ -834,6 +839,7 @@ UReanimator.h
|
|||
URegions.h
|
||||
URegistrar.h
|
||||
UResourceMgr.h
|
||||
utility
|
||||
urlhist.h
|
||||
urlmon.h
|
||||
UScrap.h
|
||||
|
|
26
configure.in
26
configure.in
|
@ -6273,7 +6273,7 @@ dnl Remove dupes
|
|||
MOZ_EXTENSIONS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_EXTENSIONS}`
|
||||
|
||||
dnl Ensure every extension exists, to avoid mostly-inscrutable error messages
|
||||
dnl when trying to build a non-existent extension.
|
||||
dnl when trying to build a nonexistent extension.
|
||||
for extension in $MOZ_EXTENSIONS; do
|
||||
if test ! -d "${srcdir}/extensions/${extension}"; then
|
||||
AC_MSG_ERROR([Unrecognized extension provided to --enable-extensions: ${extension}.])
|
||||
|
@ -6527,15 +6527,6 @@ MOZ_ARG_ENABLE_BOOL(leaky,
|
|||
MOZ_LEAKY=)
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl xpctools
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(xpctools,
|
||||
[ --enable-xpctools Build JS profiling tool],
|
||||
MOZ_XPCTOOLS=1,
|
||||
MOZ_XPCTOOLS= )
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl build the tests by default
|
||||
dnl ========================================================
|
||||
|
@ -6934,7 +6925,19 @@ MOZ_ARG_ENABLE_STRING(debug,
|
|||
fi ],
|
||||
MOZ_DEBUG=)
|
||||
|
||||
MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -D_DEBUG -DTRACING"
|
||||
MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -D_DEBUG"
|
||||
case "${target_os}" in
|
||||
beos*)
|
||||
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${USER}"
|
||||
;;
|
||||
msvc*|mks*|cygwin*|mingw*|os2*|wince*|winmo*)
|
||||
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
|
||||
;;
|
||||
*)
|
||||
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_`$WHOAMI`"
|
||||
;;
|
||||
esac
|
||||
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DTRACING"
|
||||
|
||||
MOZ_DEBUG_DISABLE_DEFS="-DNDEBUG -DTRIMMED"
|
||||
|
||||
|
@ -8476,7 +8479,6 @@ AC_SUBST(MOZ_JPROF)
|
|||
AC_SUBST(MOZ_SHARK)
|
||||
AC_SUBST(MOZ_CALLGRIND)
|
||||
AC_SUBST(MOZ_VTUNE)
|
||||
AC_SUBST(MOZ_XPCTOOLS)
|
||||
AC_SUBST(MOZ_JSLOADER)
|
||||
AC_SUBST(MOZ_USE_NATIVE_UCONV)
|
||||
AC_SUBST(MOZ_QUANTIFY)
|
||||
|
|
|
@ -1099,6 +1099,23 @@ nsAttrValue::ParseNonNegativeIntValue(const nsAString& aString)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAttrValue::ParsePositiveIntValue(const nsAString& aString)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
PRInt32 ec;
|
||||
PRBool strict;
|
||||
PRInt32 originalVal = StringToInteger(aString, &strict, &ec);
|
||||
if (NS_FAILED(ec) || originalVal <= 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SetIntValueAndType(originalVal, eInteger, nsnull);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString)
|
||||
{
|
||||
|
|
|
@ -258,6 +258,21 @@ public:
|
|||
*/
|
||||
PRBool ParseNonNegativeIntValue(const nsAString& aString);
|
||||
|
||||
/**
|
||||
* Parse a string value into a positive integer.
|
||||
* This method follows the rules for parsing non-negative integer from:
|
||||
* http://dev.w3.org/html5/spec/infrastructure.html#rules-for-parsing-non-negative-integers
|
||||
* In addition of these rules, the value has to be greater than zero.
|
||||
*
|
||||
* This is generally used for parsing content attributes which reflecting IDL
|
||||
* attributes are limited to only non-negative numbers greater than zero, see:
|
||||
* http://dev.w3.org/html5/spec/common-dom-interfaces.html#limited-to-only-non-negative-numbers-greater-than-zero
|
||||
*
|
||||
* @param aString the string to parse
|
||||
* @return whether the value was valid
|
||||
*/
|
||||
PRBool ParsePositiveIntValue(const nsAString& aString);
|
||||
|
||||
/**
|
||||
* Parse a string into a color.
|
||||
*
|
||||
|
|
|
@ -432,7 +432,7 @@ nsImageLoadingContent::RemoveObserver(imgIDecoderObserver* aObserver)
|
|||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
NS_WARNING("Asked to remove non-existent observer");
|
||||
NS_WARNING("Asked to remove nonexistent observer");
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
|
|
@ -665,7 +665,7 @@
|
|||
t( "ID Selector w/ Element", "body#body", ["body"], false );
|
||||
t( "ID Selector w/ Element", "ul#first", [] );
|
||||
t( "ID selector with existing ID descendant", "#firstp #simon1", ["simon1"] );
|
||||
t( "ID selector with non-existent descendant", "#firstp #foobar", [] );
|
||||
t( "ID selector with nonexistent descendant", "#firstp #foobar", [] );
|
||||
|
||||
t( "ID selector using UTF8", "#台北Táiběi", ["台北Táiběi"] );
|
||||
t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] );
|
||||
|
@ -686,7 +686,7 @@
|
|||
t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] );
|
||||
t( "All Children of ID with no children", "#firstUL > *", [] );
|
||||
|
||||
t( "ID selector with non-existent ancestor", "#asdfasdf #foobar", [] ); // bug #986
|
||||
t( "ID selector with nonexistent ancestor", "#asdfasdf #foobar", [] ); // bug #986
|
||||
|
||||
//t( "body div#form", [], "ID selector within the context of another element" );
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=390219
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "non-existing_url", true);
|
||||
xhr.open("GET", "nonexistent_url", true);
|
||||
xhr.send(null);
|
||||
xhr.abort();
|
||||
xhr.open("GET", ".", true);
|
||||
|
|
|
@ -69,7 +69,7 @@ function checkModification(e, funcName, argument, expectedRes, before, after) {
|
|||
" " + contextMsg);
|
||||
|
||||
var expectedAfter = after;
|
||||
// XUL returns an empty string when getting a non-existing class attribute.
|
||||
// XUL returns an empty string when getting a nonexistent class attribute.
|
||||
if (e.namespaceURI == XUL_NS && expectedAfter === null)
|
||||
expectedAfter = "";
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort r
|
|||
expectedTestCount++;
|
||||
|
||||
|
||||
// Test reading from non-existing files
|
||||
// Test reading from nonexistent files
|
||||
r = new FileReader();
|
||||
var didThrow = false;
|
||||
try {
|
||||
|
@ -264,7 +264,7 @@ try {
|
|||
}
|
||||
// Once this test passes, we shoud test that onerror gets called and
|
||||
// that the FileReader object is in the right state during that call.
|
||||
todo(!didThrow, "shouldn't throw when opening non-existing file, should fire error instead");
|
||||
todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
|
||||
|
||||
|
||||
function getLoadHandler(expectedResult, expectedLength, testName) {
|
||||
|
|
|
@ -2158,13 +2158,12 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
|||
}
|
||||
}
|
||||
} else if (surf->Format() == gfxASurface::ImageFormatRGB24) {
|
||||
PRUint8* src = surf->Data();
|
||||
PRUint8* dst = surf->Data();
|
||||
|
||||
// this wants some SSE love
|
||||
|
||||
for (int j = 0; j < height; j++) {
|
||||
src = surf->Data() + j * surf->Stride();
|
||||
PRUint8* src = surf->Data() + j * surf->Stride();
|
||||
// note that dst's stride is always tightly packed
|
||||
for (int i = 0; i < width; i++) {
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
|
|
|
@ -1106,6 +1106,31 @@ NS_NewHTML##_elementName##Element(nsINodeInfo *aNodeInfo, PRBool aFromParser)\
|
|||
return SetAttrHelper(nsGkAtoms::_atom, aValue); \
|
||||
}
|
||||
|
||||
/**
|
||||
* A macro to implement the getter and setter for a given content
|
||||
* property that needs to set a positive integer. The method uses
|
||||
* the generic GetAttr and SetAttr methods. This macro is much like
|
||||
* the NS_IMPL_NON_NEGATIVE_INT_ATTR macro except the exception is
|
||||
* thrown also when the value is equal to 0.
|
||||
*/
|
||||
#define NS_IMPL_POSITIVE_INT_ATTR(_class, _method, _atom) \
|
||||
NS_IMPL_POSITIVE_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, 1)
|
||||
|
||||
#define NS_IMPL_POSITIVE_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
|
||||
NS_IMETHODIMP \
|
||||
_class::Get##_method(PRInt32* aValue) \
|
||||
{ \
|
||||
return GetIntAttr(nsGkAtoms::_atom, _default, aValue); \
|
||||
} \
|
||||
NS_IMETHODIMP \
|
||||
_class::Set##_method(PRInt32 aValue) \
|
||||
{ \
|
||||
if (aValue <= 0) { \
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR; \
|
||||
} \
|
||||
return SetIntAttr(nsGkAtoms::_atom, aValue); \
|
||||
}
|
||||
|
||||
/**
|
||||
* QueryInterface() implementation helper macros
|
||||
*/
|
||||
|
|
|
@ -1206,7 +1206,8 @@ NS_IMPL_BOOL_ATTR(nsHTMLSelectElement, Autofocus, autofocus)
|
|||
NS_IMPL_BOOL_ATTR(nsHTMLSelectElement, Disabled, disabled)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLSelectElement, Multiple, multiple)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLSelectElement, Name, name)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLSelectElement, Size, size, 0)
|
||||
NS_IMPL_POSITIVE_INT_ATTR_DEFAULT_VALUE(nsHTMLSelectElement, Size, size,
|
||||
GetDefaultSize())
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLSelectElement, TabIndex, tabindex, 0)
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1368,7 +1369,7 @@ nsHTMLSelectElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aAttribute == nsGkAtoms::size && kNameSpaceID_None == aNamespaceID) {
|
||||
return aResult.ParseIntWithBounds(aValue, 0);
|
||||
return aResult.ParsePositiveIntValue(aValue);
|
||||
}
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
aResult);
|
||||
|
|
|
@ -473,6 +473,14 @@ protected:
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the default size.
|
||||
*/
|
||||
PRInt32 GetDefaultSize() const
|
||||
{
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ? 4 : 1;
|
||||
}
|
||||
|
||||
/** The options[] array */
|
||||
nsRefPtr<nsHTMLOptionCollection> mOptions;
|
||||
/** false if the parser is in the middle of adding children. */
|
||||
|
|
|
@ -177,6 +177,7 @@ _TEST_FILES = test_bug589.html \
|
|||
file_bug546995.html \
|
||||
test_bug377624.html \
|
||||
test_bug562932.html \
|
||||
test_bug551846.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=551846
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 551846</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551846">Mozilla Bug 551846</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<select id='s'>
|
||||
<option>Tulip</option>
|
||||
<option>Lily</option>
|
||||
<option>Gagea</option>
|
||||
<option>Snowflake</option>
|
||||
<option>Ismene</option>
|
||||
</select>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 551846 **/
|
||||
|
||||
function checkSizeReflection(element, defaultValue)
|
||||
{
|
||||
is(element.size, defaultValue, "Default size should be " + defaultValue);
|
||||
|
||||
element.setAttribute('size', -15);
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
is(element.getAttribute('size'), -15,
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.setAttribute('size', 0);
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
|
||||
element.setAttribute('size', 2147483647); /* PR_INT32_MAX */
|
||||
is(element.size, 2147483647,
|
||||
"PR_INT32_MAX should be considered as a valid value");
|
||||
is(element.getAttribute('size'), 2147483647,
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.setAttribute('size', -2147483648); /* PR_INT32_MIN */
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
is(element.getAttribute('size'), -2147483648,
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.setAttribute('size', 'non-numerical-value');
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
is(element.getAttribute('size'), 'non-numerical-value',
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.setAttribute('size', 4294967294); /* PR_INT32_MAX * 2 */
|
||||
is(element.size, defaultValue,
|
||||
"Value greater than PR_INT32_MAX should be considered as invalid");
|
||||
is(element.getAttribute('size'), 4294967294,
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.setAttribute('size', -4294967296); /* PR_INT32_MIN * 2 */
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
is(element.getAttribute('size'), -4294967296,
|
||||
"The content attribute should containt the previously set value");
|
||||
|
||||
element.size = defaultValue + 1;
|
||||
element.removeAttribute('size');
|
||||
is(element.size, defaultValue,
|
||||
"When the attribute is removed, the size should be the default size");
|
||||
|
||||
element.setAttribute('size', 'foobar');
|
||||
is(element.size, defaultValue,
|
||||
"The reflecting IDL attribute should return the default value when content attribute value is invalid");
|
||||
element.removeAttribute('size');
|
||||
is(element.size, defaultValue,
|
||||
"When the attribute is removed, the size should be the default size");
|
||||
}
|
||||
|
||||
function checkSetSizeException(element)
|
||||
{
|
||||
var caught = false;
|
||||
|
||||
try {
|
||||
element.size = 1;
|
||||
} catch(e) {
|
||||
caught = true;
|
||||
}
|
||||
ok(!caught, "Setting a valid size shouldn't throw an exception");
|
||||
|
||||
caught = false;
|
||||
try {
|
||||
element.size = 0;
|
||||
} catch(e) {
|
||||
caught = true;
|
||||
}
|
||||
ok(caught, "Setting an invalid size from the IDL should throw an exception");
|
||||
|
||||
caught = false;
|
||||
try {
|
||||
element.size = -1;
|
||||
} catch(e) {
|
||||
caught = true;
|
||||
}
|
||||
ok(caught, "Setting an invalid size from the IDL should throw an exception");
|
||||
|
||||
caught = false;
|
||||
try {
|
||||
element.setAttribute('size', -10);
|
||||
} catch(e) {
|
||||
caught = true;
|
||||
}
|
||||
ok(!caught, "Setting an invalid size in the content attribute shouldn't throw an exception");
|
||||
|
||||
// reverting to defalut
|
||||
element.removeAttribute('size');
|
||||
}
|
||||
|
||||
function checkSizeWhenChangeMultiple(element)
|
||||
{
|
||||
s.setAttribute('size', -1)
|
||||
is(s.size, 1, "Size IDL attribute should be 1");
|
||||
|
||||
s.multiple = true;
|
||||
is(s.size, 4, "Size IDL attribute should be 4");
|
||||
|
||||
is(s.getAttribute('size'), -1, "Size content attribute should be -1");
|
||||
|
||||
s.setAttribute('size', -2);
|
||||
is(s.size, 4, "Size IDL attribute should be 4");
|
||||
|
||||
s.multiple = false;
|
||||
is(s.size, 1, "Size IDL attribute should be 1");
|
||||
|
||||
is(s.getAttribute('size'), -2, "Size content attribute should be -2");
|
||||
}
|
||||
|
||||
var s = document.getElementById('s');
|
||||
|
||||
checkSizeReflection(s, 1);
|
||||
checkSetSizeException(s);
|
||||
|
||||
s.setAttribute('multiple', 'true');
|
||||
checkSizeReflection(s, 4);
|
||||
checkSetSizeException(s);
|
||||
s.removeAttribute('multiple');
|
||||
|
||||
checkSizeWhenChangeMultiple(s);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1764,7 +1764,7 @@ HTMLContentSink::BeginContext(PRInt32 aPosition)
|
|||
}
|
||||
|
||||
if (!mCurrentContext) {
|
||||
NS_ERROR("Non-existing context");
|
||||
NS_ERROR("Nonexistent context");
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1804,7 +1804,7 @@ HTMLContentSink::BeginContext(PRInt32 aPosition)
|
|||
NS_IMETHODIMP
|
||||
HTMLContentSink::EndContext(PRInt32 aPosition)
|
||||
{
|
||||
NS_PRECONDITION(mCurrentContext && aPosition > -1, "non-existing context");
|
||||
NS_PRECONDITION(mCurrentContext && aPosition > -1, "nonexistent context");
|
||||
|
||||
PRUint32 n = mContextStack.Length() - 1;
|
||||
SinkContext* sc = mContextStack.ElementAt(n);
|
||||
|
|
|
@ -2154,7 +2154,7 @@ nsHTMLDocument::Close()
|
|||
// document.open() and document.close() have completed, then this
|
||||
// method should cause the firing of an onload event.
|
||||
NS_ASSERTION(mWyciwygChannel, "nsHTMLDocument::Close(): Trying to remove "
|
||||
"non-existent wyciwyg channel!");
|
||||
"nonexistent wyciwyg channel!");
|
||||
RemoveWyciwygChannel();
|
||||
NS_ASSERTION(!mWyciwygChannel, "nsHTMLDocument::Close(): "
|
||||
"nsIWyciwygChannel could not be removed!");
|
||||
|
|
|
@ -56,7 +56,7 @@ class nsVideoInfo {
|
|||
public:
|
||||
nsVideoInfo()
|
||||
: mFramerate(0.0),
|
||||
mAspectRatio(1.0),
|
||||
mPixelAspectRatio(1.0),
|
||||
mCallbackPeriod(1),
|
||||
mAudioRate(0),
|
||||
mAudioChannels(0),
|
||||
|
@ -68,8 +68,8 @@ public:
|
|||
// Frames per second.
|
||||
float mFramerate;
|
||||
|
||||
// Aspect ratio, as stored in the metadata.
|
||||
float mAspectRatio;
|
||||
// Pixel aspect ratio, as stored in the metadata.
|
||||
float mPixelAspectRatio;
|
||||
|
||||
// Length of a video frame in milliseconds, or the callback period if
|
||||
// there's no audio.
|
||||
|
|
|
@ -1030,7 +1030,7 @@ void nsBuiltinDecoderStateMachine::RenderVideoFrame(VideoData* aData)
|
|||
nsRefPtr<Image> image = aData->mImage;
|
||||
if (image) {
|
||||
const nsVideoInfo& info = mReader->GetInfo();
|
||||
mDecoder->SetVideoData(gfxIntSize(info.mPicture.width, info.mPicture.height), info.mAspectRatio, image);
|
||||
mDecoder->SetVideoData(gfxIntSize(info.mPicture.width, info.mPicture.height), info.mPixelAspectRatio, image);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ nsMediaDecoder::nsMediaDecoder() :
|
|||
mProgressTime(),
|
||||
mDataTime(),
|
||||
mVideoUpdateLock(nsnull),
|
||||
mAspectRatio(1.0),
|
||||
mPixelAspectRatio(1.0),
|
||||
mSizeChanged(PR_FALSE),
|
||||
mShuttingDown(PR_FALSE)
|
||||
{
|
||||
|
@ -126,14 +126,14 @@ void nsMediaDecoder::Invalidate()
|
|||
nsIntSize scaledSize(mRGBWidth, mRGBHeight);
|
||||
// Apply the aspect ratio to produce the intrinsic size we report
|
||||
// to the element.
|
||||
if (mAspectRatio > 1.0) {
|
||||
if (mPixelAspectRatio > 1.0) {
|
||||
// Increase the intrinsic width
|
||||
scaledSize.width =
|
||||
ConditionDimension(mAspectRatio*scaledSize.width, scaledSize.width);
|
||||
ConditionDimension(mPixelAspectRatio*scaledSize.width, scaledSize.width);
|
||||
} else {
|
||||
// Increase the intrinsic height
|
||||
scaledSize.height =
|
||||
ConditionDimension(scaledSize.height/mAspectRatio, scaledSize.height);
|
||||
ConditionDimension(scaledSize.height/mPixelAspectRatio, scaledSize.height);
|
||||
}
|
||||
mElement->UpdateMediaSize(scaledSize);
|
||||
|
||||
|
@ -213,16 +213,16 @@ nsresult nsMediaDecoder::StopProgress()
|
|||
}
|
||||
|
||||
void nsMediaDecoder::SetVideoData(const gfxIntSize& aSize,
|
||||
float aAspectRatio,
|
||||
float aPixelAspectRatio,
|
||||
Image* aImage)
|
||||
{
|
||||
nsAutoLock lock(mVideoUpdateLock);
|
||||
|
||||
if (mRGBWidth != aSize.width || mRGBHeight != aSize.height ||
|
||||
mAspectRatio != aAspectRatio) {
|
||||
mPixelAspectRatio != aPixelAspectRatio) {
|
||||
mRGBWidth = aSize.width;
|
||||
mRGBHeight = aSize.height;
|
||||
mAspectRatio = aAspectRatio;
|
||||
mPixelAspectRatio = aPixelAspectRatio;
|
||||
mSizeChanged = PR_TRUE;
|
||||
}
|
||||
if (mImageContainer && aImage) {
|
||||
|
|
|
@ -231,7 +231,7 @@ public:
|
|||
// Set the video width, height, pixel aspect ratio, and current image.
|
||||
// Ownership of the image is transferred to the decoder.
|
||||
void SetVideoData(const gfxIntSize& aSize,
|
||||
float aAspectRatio,
|
||||
float aPixelAspectRatio,
|
||||
Image* aImage);
|
||||
|
||||
protected:
|
||||
|
@ -283,7 +283,7 @@ protected:
|
|||
float mFramerate;
|
||||
|
||||
// Pixel aspect ratio (ratio of the pixel width to pixel height)
|
||||
float mAspectRatio;
|
||||
float mPixelAspectRatio;
|
||||
|
||||
// Has our size changed since the last repaint?
|
||||
PRPackedBool mSizeChanged;
|
||||
|
|
|
@ -149,7 +149,7 @@ nsTheoraState::nsTheoraState(ogg_page* aBosPage) :
|
|||
mCtx(0),
|
||||
mFrameDuration(0),
|
||||
mFrameRate(0),
|
||||
mAspectRatio(0)
|
||||
mPixelAspectRatio(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsTheoraState);
|
||||
th_info_init(&mInfo);
|
||||
|
@ -191,7 +191,7 @@ PRBool nsTheoraState::Init() {
|
|||
n = mInfo.aspect_numerator;
|
||||
|
||||
d = mInfo.aspect_denominator;
|
||||
mAspectRatio = (n == 0 || d == 0) ?
|
||||
mPixelAspectRatio = (n == 0 || d == 0) ?
|
||||
1.0f : static_cast<float>(n) / static_cast<float>(d);
|
||||
|
||||
// Ensure the frame isn't larger than our prescribed maximum.
|
||||
|
|
|
@ -190,7 +190,7 @@ public:
|
|||
// Number of frames per second.
|
||||
float mFrameRate;
|
||||
|
||||
float mAspectRatio;
|
||||
float mPixelAspectRatio;
|
||||
};
|
||||
|
||||
class nsSkeletonState : public nsOggCodecState {
|
||||
|
|
|
@ -250,16 +250,14 @@ nsresult nsOggReader::ReadMetadata()
|
|||
// Initialize the first Theora and Vorbis bitstreams. According to the
|
||||
// Theora spec these can be considered the 'primary' bitstreams for playback.
|
||||
// Extract the metadata needed from these streams.
|
||||
float aspectRatio = 0;
|
||||
// Set a default callback period for if we have no video data
|
||||
mCallbackPeriod = 1000 / AUDIO_FRAME_RATE;
|
||||
if (mTheoraState) {
|
||||
if (mTheoraState->Init()) {
|
||||
mCallbackPeriod = mTheoraState->mFrameDuration;
|
||||
aspectRatio = mTheoraState->mAspectRatio;
|
||||
gfxIntSize sz(mTheoraState->mInfo.pic_width,
|
||||
mTheoraState->mInfo.pic_height);
|
||||
mDecoder->SetVideoData(sz, mTheoraState->mAspectRatio, nsnull);
|
||||
mDecoder->SetVideoData(sz, mTheoraState->mPixelAspectRatio, nsnull);
|
||||
} else {
|
||||
mTheoraState = nsnull;
|
||||
}
|
||||
|
@ -277,7 +275,7 @@ nsresult nsOggReader::ReadMetadata()
|
|||
}
|
||||
if (HasVideo()) {
|
||||
mInfo.mFramerate = mTheoraState->mFrameRate;
|
||||
mInfo.mAspectRatio = mTheoraState->mAspectRatio;
|
||||
mInfo.mPixelAspectRatio = mTheoraState->mPixelAspectRatio;
|
||||
mInfo.mPicture.width = mTheoraState->mInfo.pic_width;
|
||||
mInfo.mPicture.height = mTheoraState->mInfo.pic_height;
|
||||
mInfo.mPicture.x = mTheoraState->mInfo.pic_x;
|
||||
|
|
|
@ -32,25 +32,22 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGStylableElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDOMSVGAltGlyphElement.h"
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsSVGString.h"
|
||||
#include "nsSVGTextPositioningElement.h"
|
||||
|
||||
typedef nsSVGStylableElement nsSVGAltGlyphElementBase;
|
||||
typedef nsSVGTextPositioningElement nsSVGAltGlyphElementBase;
|
||||
|
||||
class nsSVGAltGlyphElement : public nsSVGAltGlyphElementBase,
|
||||
class nsSVGAltGlyphElement : public nsSVGAltGlyphElementBase, // = nsIDOMSVGTextPositioningElement
|
||||
public nsIDOMSVGAltGlyphElement,
|
||||
public nsIDOMSVGURIReference,
|
||||
public nsSVGTextPositioningElement // = nsIDOMSVGTextPositioningElement
|
||||
public nsIDOMSVGURIReference
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGAltGlyphElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGAltGlyphElement(nsINodeInfo* aNodeInfo);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
@ -64,8 +61,8 @@ public:
|
|||
NS_FORWARD_NSIDOMNODE(nsSVGAltGlyphElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGAltGlyphElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAltGlyphElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextContentElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGTextPositioningElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGAltGlyphElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGAltGlyphElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -73,9 +70,6 @@ public:
|
|||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
virtual nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
|
||||
}
|
||||
|
||||
// nsSVGElement overrides
|
||||
virtual StringAttributesInfo GetStringInfo();
|
||||
|
@ -119,17 +113,6 @@ nsSVGAltGlyphElement::nsSVGAltGlyphElement(nsINodeInfo *aNodeInfo)
|
|||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGAltGlyphElement::Init()
|
||||
{
|
||||
nsresult rv = nsSVGAltGlyphElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = Initialise(this);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMNode methods
|
||||
|
|
|
@ -194,7 +194,6 @@ protected:
|
|||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue);
|
||||
|
||||
friend class nsSVGTextPositioningElement;
|
||||
// Hooks for subclasses
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
||||
|
|
|
@ -36,23 +36,20 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGStylableElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDOMSVGTSpanElement.h"
|
||||
#include "nsSVGSVGElement.h"
|
||||
#include "nsSVGTextPositioningElement.h"
|
||||
|
||||
typedef nsSVGStylableElement nsSVGTSpanElementBase;
|
||||
typedef nsSVGTextPositioningElement nsSVGTSpanElementBase;
|
||||
|
||||
class nsSVGTSpanElement : public nsSVGTSpanElementBase,
|
||||
public nsIDOMSVGTSpanElement,
|
||||
public nsSVGTextPositioningElement // = nsIDOMSVGTextPositioningElement
|
||||
class nsSVGTSpanElement : public nsSVGTSpanElementBase, // = nsIDOMSVGTextPositioningElement
|
||||
public nsIDOMSVGTSpanElement
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGTSpanElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGTSpanElement(nsINodeInfo* aNodeInfo);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
@ -65,8 +62,8 @@ public:
|
|||
NS_FORWARD_NSIDOMNODE(nsSVGTSpanElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGTSpanElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTSpanElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextContentElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGTextPositioningElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTSpanElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGTSpanElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -74,9 +71,6 @@ public:
|
|||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
virtual nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
|
||||
}
|
||||
|
||||
// nsSVGElement overrides
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
@ -112,18 +106,6 @@ nsSVGTSpanElement::nsSVGTSpanElement(nsINodeInfo *aNodeInfo)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsSVGTSpanElement::Init()
|
||||
{
|
||||
nsresult rv = nsSVGTSpanElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = Initialise(this);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMNode methods
|
||||
|
||||
|
|
|
@ -41,14 +41,30 @@
|
|||
|
||||
#include "nsIDOMSVGTextContentElement.h"
|
||||
#include "nsSVGTextContainerFrame.h"
|
||||
#include "nsSVGStylableElement.h"
|
||||
|
||||
class nsSVGTextContentElement
|
||||
typedef nsSVGStylableElement nsSVGTextContentElementBase;
|
||||
|
||||
/**
|
||||
* Note that nsSVGTextElement does not inherit nsSVGTextPositioningElement, or
|
||||
* this class - it reimplements us instead (see its documenting comment). The
|
||||
* upshot is that any changes to this class also need to be made in
|
||||
* nsSVGTextElement.
|
||||
*/
|
||||
class nsSVGTextContentElement : public nsSVGTextContentElementBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
|
||||
|
||||
protected:
|
||||
virtual nsSVGTextContainerFrame* GetTextContainerFrame()=0;
|
||||
|
||||
nsSVGTextContentElement(nsINodeInfo *aNodeInfo)
|
||||
: nsSVGTextContentElementBase(aNodeInfo)
|
||||
{}
|
||||
|
||||
nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,12 +44,27 @@
|
|||
#include "nsSVGTextPositioningElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsSVGLengthList.h"
|
||||
#include "nsSVGAnimatedLengthList.h"
|
||||
#include "nsSVGNumberList.h"
|
||||
#include "nsSVGAnimatedNumberList.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGTextElementBase;
|
||||
|
||||
/**
|
||||
* This class does not inherit nsSVGTextPositioningElement - it reimplements it
|
||||
* instead.
|
||||
*
|
||||
* Ideally this class would inherit nsSVGTextPositioningElement in addition to
|
||||
* nsSVGGraphicElement, but we don't want two instances of nsSVGStylableElement
|
||||
* and all the classes it inherits. Instead we choose to inherit one of the
|
||||
* classes (nsSVGGraphicElement) and reimplement the missing pieces from the
|
||||
* other (nsSVGTextPositioningElement (and thus nsSVGTextContentElement)). Care
|
||||
* must be taken when making changes to the reimplemented pieces to keep
|
||||
* nsSVGTextPositioningElement in sync (and vice versa).
|
||||
*/
|
||||
class nsSVGTextElement : public nsSVGTextElementBase,
|
||||
public nsIDOMSVGTextElement,
|
||||
public nsSVGTextPositioningElement // = nsIDOMSVGTextPositioningElement
|
||||
public nsIDOMSVGTextElement // nsIDOMSVGTextPositioningElement
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGTextElement(nsIContent **aResult,
|
||||
|
@ -62,14 +77,14 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGTEXTELEMENT
|
||||
NS_DECL_NSIDOMSVGTEXTPOSITIONINGELEMENT
|
||||
NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
|
||||
|
||||
// xxx If xpcom allowed virtual inheritance we wouldn't need to
|
||||
// forward here :-(
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGTextElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGTextElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextContentElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGTextPositioningElement::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -77,10 +92,16 @@ public:
|
|||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
virtual nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
|
||||
}
|
||||
|
||||
// nsIDOMSVGTextPositioning properties:
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> mX;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> mY;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> mdX;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> mdY;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedNumberList> mRotate;
|
||||
};
|
||||
|
||||
|
||||
|
@ -118,8 +139,65 @@ nsSVGTextElement::Init()
|
|||
nsresult rv = nsSVGTextElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = Initialise(this);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::x, #IMPLIED attrib: x
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::X);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::x, mX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::y, #IMPLIED attrib: y
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::Y);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::y, mY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dx, #IMPLIED attrib: dx
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::X);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::dx, mdX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dy, #IMPLIED attrib: dy
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::Y);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::dy, mdY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::rotate, #IMPLIED attrib: rotate
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGNumberList> numberList;
|
||||
rv = NS_NewSVGNumberList(getter_AddRefs(numberList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedNumberList(getter_AddRefs(mRotate),
|
||||
numberList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::rotate, mRotate);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -136,6 +214,195 @@ NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGTextElement)
|
|||
|
||||
// - no methods -
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGTextPositioningElement methods
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList x; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetX(nsIDOMSVGAnimatedLengthList * *aX)
|
||||
{
|
||||
*aX = mX;
|
||||
NS_IF_ADDREF(*aX);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList y; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetY(nsIDOMSVGAnimatedLengthList * *aY)
|
||||
{
|
||||
*aY = mY;
|
||||
NS_IF_ADDREF(*aY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dx; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetDx(nsIDOMSVGAnimatedLengthList * *aDx)
|
||||
{
|
||||
*aDx = mdX;
|
||||
NS_IF_ADDREF(*aDx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dy; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetDy(nsIDOMSVGAnimatedLengthList * *aDy)
|
||||
{
|
||||
*aDy = mdY;
|
||||
NS_IF_ADDREF(*aDy);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedNumberList rotate; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetRotate(nsIDOMSVGAnimatedNumberList * *aRotate)
|
||||
{
|
||||
*aRotate = mRotate;
|
||||
NS_IF_ADDREF(*aRotate);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGTextContentElement methods
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLength textLength; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetTextLength(nsIDOMSVGAnimatedLength * *aTextLength)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsSVGTextElement::GetTextLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedEnumeration lengthAdjust; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetLengthAdjust(nsIDOMSVGAnimatedEnumeration * *aLengthAdjust)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsSVGTextElement::GetLengthAdjust");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* long getNumberOfChars (); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetNumberOfChars(PRInt32 *_retval)
|
||||
{
|
||||
*_retval = 0;
|
||||
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
if (metrics)
|
||||
*_retval = metrics->GetNumberOfChars();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* float getComputedTextLength (); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetComputedTextLength(float *_retval)
|
||||
{
|
||||
*_retval = 0.0;
|
||||
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
if (metrics)
|
||||
*_retval = metrics->GetComputedTextLength();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* float getSubStringLength (in unsigned long charnum, in unsigned long nchars); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval)
|
||||
{
|
||||
*_retval = 0.0f;
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
if (!metrics)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 charcount = metrics->GetNumberOfChars();
|
||||
if (charcount <= charnum || nchars > charcount - charnum)
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
if (nchars == 0)
|
||||
return NS_OK;
|
||||
|
||||
*_retval = metrics->GetSubStringLength(charnum, nchars);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGPoint getStartPositionOfChar (in unsigned long charnum); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
|
||||
if (!metrics) return NS_ERROR_FAILURE;
|
||||
|
||||
return metrics->GetStartPositionOfChar(charnum, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMSVGPoint getEndPositionOfChar (in unsigned long charnum); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
|
||||
if (!metrics) return NS_ERROR_FAILURE;
|
||||
|
||||
return metrics->GetEndPositionOfChar(charnum, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMSVGRect getExtentOfChar (in unsigned long charnum); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
|
||||
if (!metrics) return NS_ERROR_FAILURE;
|
||||
|
||||
return metrics->GetExtentOfChar(charnum, _retval);
|
||||
}
|
||||
|
||||
/* float getRotationOfChar (in unsigned long charnum); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetRotationOfChar(PRUint32 charnum, float *_retval)
|
||||
{
|
||||
*_retval = 0.0;
|
||||
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
|
||||
if (!metrics) return NS_ERROR_FAILURE;
|
||||
|
||||
return metrics->GetRotationOfChar(charnum, _retval);
|
||||
}
|
||||
|
||||
/* long getCharNumAtPosition (in nsIDOMSVGPoint point); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
|
||||
{
|
||||
if (!point)
|
||||
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
|
||||
|
||||
*_retval = -1;
|
||||
|
||||
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
|
||||
if (metrics)
|
||||
*_retval = metrics->GetCharNumAtPosition(point);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void selectSubString (in unsigned long charnum, in unsigned long nchars); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextElement::SelectSubString(PRUint32 charnum, PRUint32 nchars)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsSVGTextElement::SelectSubString");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
|
|
|
@ -43,12 +43,11 @@
|
|||
#include "nsSVGString.h"
|
||||
#include "nsSVGTextContentElement.h"
|
||||
|
||||
typedef nsSVGStylableElement nsSVGTextPathElementBase;
|
||||
typedef nsSVGTextContentElement nsSVGTextPathElementBase;
|
||||
|
||||
class nsSVGTextPathElement : public nsSVGTextPathElementBase,
|
||||
class nsSVGTextPathElement : public nsSVGTextPathElementBase, // = nsIDOMSVGTextContentElement
|
||||
public nsIDOMSVGTextPathElement,
|
||||
public nsIDOMSVGURIReference,
|
||||
public nsSVGTextContentElement // = nsIDOMSVGTextContentElement
|
||||
public nsIDOMSVGURIReference
|
||||
{
|
||||
friend class nsSVGTextPathFrame;
|
||||
|
||||
|
@ -69,7 +68,7 @@ public:
|
|||
NS_FORWARD_NSIDOMNODE(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextContentElement::)
|
||||
NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextPathElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -78,10 +77,6 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
virtual nsSVGTextContainerFrame* GetTextContainerFrame() {
|
||||
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
|
||||
}
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual EnumAttributesInfo GetEnumInfo();
|
||||
virtual StringAttributesInfo GetStringInfo();
|
||||
|
|
|
@ -40,56 +40,58 @@
|
|||
#include "nsSVGNumberList.h"
|
||||
|
||||
nsresult
|
||||
nsSVGTextPositioningElement::Initialise(nsSVGElement *aSVGElement)
|
||||
nsSVGTextPositioningElement::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = nsSVGTextPositioningElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// Create mapped properties:
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::x, #IMPLIED attrib: x
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), aSVGElement, nsSVGUtils::X);
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::X);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = aSVGElement->AddMappedSVGValue(nsGkAtoms::x, mX);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::x, mX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::y, #IMPLIED attrib: y
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), aSVGElement, nsSVGUtils::Y);
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::Y);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = aSVGElement->AddMappedSVGValue(nsGkAtoms::y, mY);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::y, mY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dx, #IMPLIED attrib: dx
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), aSVGElement, nsSVGUtils::X);
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::X);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = aSVGElement->AddMappedSVGValue(nsGkAtoms::dx, mdX);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::dx, mdX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dy, #IMPLIED attrib: dy
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), aSVGElement, nsSVGUtils::Y);
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList), this, nsSVGUtils::Y);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = aSVGElement->AddMappedSVGValue(nsGkAtoms::dy, mdY);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::dy, mdY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
|
@ -101,7 +103,7 @@ nsSVGTextPositioningElement::Initialise(nsSVGElement *aSVGElement)
|
|||
rv = NS_NewSVGAnimatedNumberList(getter_AddRefs(mRotate),
|
||||
numberList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = aSVGElement->AddMappedSVGValue(nsGkAtoms::rotate, mRotate);
|
||||
rv = AddMappedSVGValue(nsGkAtoms::rotate, mRotate);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,13 +41,27 @@
|
|||
#include "nsIDOMSVGAnimatedLengthList.h"
|
||||
#include "nsIDOMSVGAnimatedNumberList.h"
|
||||
|
||||
class nsSVGTextPositioningElement : public nsSVGTextContentElement
|
||||
class nsSVGElement;
|
||||
|
||||
typedef nsSVGTextContentElement nsSVGTextPositioningElementBase;
|
||||
|
||||
/**
|
||||
* Note that nsSVGTextElement does not inherit this class - it reimplements it
|
||||
* instead (see its documenting comment). The upshot is that any changes to
|
||||
* this class also need to be made in nsSVGTextElement.
|
||||
*/
|
||||
class nsSVGTextPositioningElement : public nsSVGTextPositioningElementBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIDOMSVGTEXTPOSITIONINGELEMENT
|
||||
|
||||
protected:
|
||||
nsresult Initialise(nsSVGElement *aSVGElement);
|
||||
|
||||
nsSVGTextPositioningElement(nsINodeInfo *aNodeInfo)
|
||||
: nsSVGTextPositioningElementBase(aNodeInfo)
|
||||
{}
|
||||
|
||||
nsresult Init();
|
||||
|
||||
// nsIDOMSVGTextPositioning properties:
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> mX;
|
||||
|
|
|
@ -1708,12 +1708,9 @@ nsXULTreeBuilder::CloseContainer(PRInt32 aIndex)
|
|||
|
||||
nsTreeRows::iterator iter = mRows[aIndex];
|
||||
|
||||
nsTreeRows::Subtree& subtree = *(iter->mSubtree);
|
||||
if (iter->mSubtree)
|
||||
RemoveMatchesFor(*iter->mSubtree);
|
||||
|
||||
RemoveMatchesFor(subtree);
|
||||
|
||||
// Update the view
|
||||
iter = mRows[aIndex];
|
||||
|
||||
PRInt32 count = mRows.GetSubtreeSizeFor(iter);
|
||||
mRows.RemoveSubtreeFor(iter);
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
location.reload();
|
||||
} catch (e) {
|
||||
// We probably tried to reload a URI that caused an exception to
|
||||
// occur; e.g. a non-existent file.
|
||||
// occur; e.g. a nonexistent file.
|
||||
}
|
||||
|
||||
buttonEl.disabled = true;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var workingURL = "http://mochi.test:8888/tests/docshell/test/bug529119-window.html";
|
||||
var faultyURL = "http://some-non-existent-domain-27489274c892748217cn2384.com/";
|
||||
var faultyURL = "http://some-nonexistent-domain-27489274c892748217cn2384.com/";
|
||||
|
||||
var w = null;
|
||||
var phase = 0;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var workingURL = "http://mochi.test:8888/tests/docshell/test/bug529119-window.html";
|
||||
var faultyURL = "http://some-non-existent-domain-27489274c892748217cn2384.com/";
|
||||
var faultyURL = "http://some-nonexistent-domain-27489274c892748217cn2384.com/";
|
||||
|
||||
var w = null;
|
||||
var phase = 0;
|
||||
|
|
|
@ -1299,7 +1299,7 @@ nsDOMStorage::SetSecure(const nsAString& aKey, PRBool aSecure)
|
|||
#endif
|
||||
|
||||
nsSessionStorageEntry *entry = mItems.GetEntry(aKey);
|
||||
NS_ASSERTION(entry, "Don't use SetSecure() with non-existing keys!");
|
||||
NS_ASSERTION(entry, "Don't use SetSecure() with nonexistent keys!");
|
||||
|
||||
if (entry) {
|
||||
entry->mItem->SetSecureInternal(aSecure);
|
||||
|
|
|
@ -500,7 +500,7 @@ nsHTMLEditor::SetFinalPosition(PRInt32 aX, PRInt32 aY)
|
|||
}
|
||||
|
||||
void
|
||||
nsHTMLEditor::AddPositioningOffet(PRInt32 & aX, PRInt32 & aY)
|
||||
nsHTMLEditor::AddPositioningOffset(PRInt32 & aX, PRInt32 & aY)
|
||||
{
|
||||
// Get the positioning offset
|
||||
nsresult res;
|
||||
|
@ -544,7 +544,7 @@ nsHTMLEditor::AbsolutelyPositionElement(nsIDOMElement * aElement,
|
|||
NS_LITERAL_STRING("absolute"),
|
||||
PR_FALSE);
|
||||
|
||||
AddPositioningOffet(x, y);
|
||||
AddPositioningOffset(x, y);
|
||||
SnapToGrid(x, y);
|
||||
SetElementPosition(aElement, x, y);
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ protected:
|
|||
|
||||
nsresult CopyCellBackgroundColor(nsIDOMElement *destCell, nsIDOMElement *sourceCell);
|
||||
|
||||
// Reduce rowspan/colspan when cells span into non-existent rows/columns
|
||||
// Reduce rowspan/colspan when cells span into nonexistent rows/columns
|
||||
NS_IMETHOD FixBadRowSpan(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32& aNewRowCount);
|
||||
NS_IMETHOD FixBadColSpan(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32& aNewColCount);
|
||||
|
||||
|
@ -907,7 +907,7 @@ protected:
|
|||
nsresult CreateGrabber(nsIDOMNode * aParentNode, nsIDOMElement ** aReturn);
|
||||
nsresult StartMoving(nsIDOMElement * aHandle);
|
||||
nsresult SetFinalPosition(PRInt32 aX, PRInt32 aY);
|
||||
void AddPositioningOffet(PRInt32 & aX, PRInt32 & aY);
|
||||
void AddPositioningOffset(PRInt32 & aX, PRInt32 & aY);
|
||||
void SnapToGrid(PRInt32 & newX, PRInt32 & newY);
|
||||
nsresult GrabberClicked();
|
||||
nsresult EndMoving();
|
||||
|
|
|
@ -321,12 +321,12 @@ class NS_STACK_CLASS nsWSRunObject
|
|||
// together, the above represent the point at which we are building up ws info.
|
||||
|
||||
PRBool mPRE; // true if we are in preformatted whitespace context
|
||||
nsCOMPtr<nsIDOMNode> mStartNode; // node/offet where ws starts
|
||||
nsCOMPtr<nsIDOMNode> mStartNode; // node/offset where ws starts
|
||||
PRInt32 mStartOffset; // ...
|
||||
PRInt16 mStartReason; // reason why ws starts (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsIDOMNode> mStartReasonNode;// the node that implicated by start reason
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mEndNode; // node/offet where ws ends
|
||||
nsCOMPtr<nsIDOMNode> mEndNode; // node/offset where ws ends
|
||||
PRInt32 mEndOffset; // ...
|
||||
PRInt16 mEndReason; // reason why ws ends (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsIDOMNode> mEndReasonNode; // the node that implicated by end reason
|
||||
|
|
|
@ -18,7 +18,7 @@ http://localhost:8080/
|
|||
|
||||
Note: the first time you hit the homepage it may take a little
|
||||
while - that's because it's trying to read out median times for all
|
||||
of the tests from a non-existent datastore and write to memcache.
|
||||
of the tests from a nonexistent datastore and write to memcache.
|
||||
Just be a lil patient.
|
||||
|
||||
You can run the unit tests at:
|
||||
|
|
|
@ -1666,6 +1666,19 @@ NS_IMETHODIMP nsWebBrowser::EnsureDocShellTreeOwner()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void DrawThebesLayer(ThebesLayer* aLayer,
|
||||
gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
void* aCallbackData)
|
||||
{
|
||||
nscolor* color = static_cast<nscolor*>(aCallbackData);
|
||||
aContext->NewPath();
|
||||
aContext->SetColor(gfxRGBA(*color));
|
||||
nsIntRect dirtyRect = aRegionToDraw.GetBounds();
|
||||
aContext->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
|
||||
aContext->Fill();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
|
||||
{
|
||||
|
@ -1696,19 +1709,7 @@ nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
|
|||
root->SetVisibleRegion(dirtyRect);
|
||||
layerManager->SetRoot(root);
|
||||
}
|
||||
layerManager->EndConstruction();
|
||||
if (root) {
|
||||
nsIntRegion toDraw;
|
||||
gfxContext* ctx = root->BeginDrawing(&toDraw);
|
||||
if (ctx) {
|
||||
ctx->NewPath();
|
||||
ctx->SetColor(gfxRGBA(browser->mBackgroundColor));
|
||||
ctx->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
root->EndDrawing();
|
||||
layerManager->EndTransaction();
|
||||
layerManager->EndTransaction(DrawThebesLayer, &browser->mBackgroundColor);
|
||||
return nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,8 @@ class THEBES_API LayerManager {
|
|||
public:
|
||||
enum LayersBackend {
|
||||
LAYERS_BASIC = 0,
|
||||
LAYERS_OPENGL
|
||||
LAYERS_OPENGL,
|
||||
LAYERS_D3D9
|
||||
};
|
||||
|
||||
virtual ~LayerManager() {}
|
||||
|
@ -143,14 +144,29 @@ public:
|
|||
*/
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0;
|
||||
/**
|
||||
* Finish the construction phase of the transaction and enter the
|
||||
* drawing phase.
|
||||
* Function called to draw the contents of each ThebesLayer.
|
||||
* aRegionToDraw contains the region that needs to be drawn.
|
||||
* This would normally be a subregion of the visible region. Drawing is
|
||||
* not necessarily clipped to aRegionToDraw.
|
||||
* The callee must draw all of aRegionToDraw.
|
||||
*
|
||||
* aContext must not be used after the call has returned.
|
||||
* We guarantee that buffered contents in the visible
|
||||
* region are valid once drawing is complete.
|
||||
*/
|
||||
virtual void EndConstruction() = 0;
|
||||
typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
|
||||
gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
void* aCallbackData);
|
||||
/**
|
||||
* Complete the transaction.
|
||||
* Finish the construction phase of the transaction, perform the
|
||||
* drawing phase, and end the transaction.
|
||||
* During the drawing phase, all ThebesLayers in the tree are
|
||||
* drawn in tree order, exactly once each, except for those layers
|
||||
* where it is known that the visible region is empty.
|
||||
*/
|
||||
virtual void EndTransaction() = 0;
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) = 0;
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
|
@ -197,6 +213,8 @@ public:
|
|||
virtual LayersBackend GetBackendType() = 0;
|
||||
};
|
||||
|
||||
class ThebesLayer;
|
||||
|
||||
/**
|
||||
* A Layer represents anything that can be rendered onto a destination
|
||||
* surface.
|
||||
|
@ -297,6 +315,12 @@ public:
|
|||
void SetUserData(void* aData) { mUserData = aData; }
|
||||
void* GetUserData() { return mUserData; }
|
||||
|
||||
/**
|
||||
* Dynamic downcast to a Thebes layer. Returns null if this is not
|
||||
* a ThebesLayer.
|
||||
*/
|
||||
virtual ThebesLayer* AsThebesLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Only the implementation should call this. This is per-implementation
|
||||
* private data. Normally, all layers with a given layer manager
|
||||
|
@ -358,36 +382,7 @@ public:
|
|||
*/
|
||||
virtual void InvalidateRegion(const nsIntRegion& aRegion) = 0;
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
* Start drawing into the layer. On return, aRegionToDraw contains the
|
||||
* region that needs to be drawn in by the caller. This would normally
|
||||
* be a subregion of the visible region. Drawing is not necessarily
|
||||
* clipped to aRegionToDraw.
|
||||
*
|
||||
* No other layer operations are allowed until we call EndDrawing on this
|
||||
* layer. During the drawing phase, all ThebesLayers in the tree must be
|
||||
* drawn in tree order, exactly once each, except for those layers
|
||||
* where it is known that the visible region is empty. (Calling
|
||||
* BeginDrawing on non-visible layers is allowed, but aRegionToDraw
|
||||
* will return empty.)
|
||||
*
|
||||
* When an empty region is returned in aRegionToDraw, BeginDrawing
|
||||
* may return a null context.
|
||||
*
|
||||
* The layer system will hold a reference to the returned gfxContext*
|
||||
* until EndDrawing is called. The returned gfxContext must not be used
|
||||
* after EndDrawing is called.
|
||||
*/
|
||||
virtual gfxContext* BeginDrawing(nsIntRegion* aRegionToDraw) = 0;
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
* We've finished drawing into this layer. At this point the caller
|
||||
* must have drawn all of aRegionToDraw that was returned by
|
||||
* BeginDrawing, and we guarantee that buffered contents in the visible
|
||||
* region are now valid.
|
||||
*/
|
||||
virtual void EndDrawing() = 0;
|
||||
virtual ThebesLayer* AsThebesLayer() { return this; }
|
||||
|
||||
protected:
|
||||
ThebesLayer(LayerManager* aManager, void* aImplData)
|
||||
|
|
|
@ -42,6 +42,7 @@ VPATH = \
|
|||
$(srcdir) \
|
||||
$(srcdir)/basic \
|
||||
$(srcdir)/opengl \
|
||||
$(srcdir)/d3d9 \
|
||||
$(NULL)
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
@ -52,6 +53,9 @@ LIBXUL_LIBRARY = 1
|
|||
FORCE_STATIC_LIB = 1
|
||||
|
||||
DEFINES += -DIMPL_THEBES
|
||||
ifdef MOZ_DEBUG
|
||||
DEFINES += -DD3D_DEBUG_INFO
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
BasicLayers.h \
|
||||
|
@ -70,6 +74,21 @@ CPPSRCS = \
|
|||
ImageLayerOGL.cpp \
|
||||
CanvasLayerOGL.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
ifndef WINCE
|
||||
EXPORTS += LayerManagerD3D9.h
|
||||
|
||||
CPPSRCS += \
|
||||
LayerManagerD3D9.cpp \
|
||||
ThebesLayerD3D9.cpp \
|
||||
ContainerLayerD3D9.cpp \
|
||||
ImageLayerD3D9.cpp \
|
||||
ColorLayerD3D9.cpp \
|
||||
CanvasLayerD3D9.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -94,7 +94,9 @@ public:
|
|||
* set up to account for all the properties of the layer (transform,
|
||||
* opacity, etc).
|
||||
*/
|
||||
virtual void Paint(gfxContext* aContext) {}
|
||||
virtual void Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) {}
|
||||
|
||||
protected:
|
||||
nsIntRegion mVisibleRegion;
|
||||
|
@ -240,8 +242,9 @@ public:
|
|||
"Can only set properties in construction phase");
|
||||
}
|
||||
|
||||
virtual gfxContext* BeginDrawing(nsIntRegion* aRegionToDraw);
|
||||
virtual void EndDrawing();
|
||||
virtual void Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
|
@ -250,30 +253,17 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
gfxContext*
|
||||
BasicThebesLayer::BeginDrawing(nsIntRegion* aRegionToDraw)
|
||||
void
|
||||
BasicThebesLayer::Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->IsBeforeInTree(BasicManager()->GetLastPainted(), this),
|
||||
"Painting layers out of order");
|
||||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
gfxContext* target = BasicManager()->GetTarget();
|
||||
if (!target)
|
||||
return nsnull;
|
||||
NS_ASSERTION(target, "We shouldn't be called if there's no target");
|
||||
|
||||
BasicManager()->AdvancePaintingTo(this);
|
||||
|
||||
*aRegionToDraw = mVisibleRegion;
|
||||
return target;
|
||||
}
|
||||
|
||||
void
|
||||
BasicThebesLayer::EndDrawing()
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
NS_ASSERTION(BasicManager()->GetLastPainted() == this,
|
||||
"Not currently drawing this layer");
|
||||
aCallback(this, target, mVisibleRegion, aCallbackData);
|
||||
}
|
||||
|
||||
class BasicImageLayer : public ImageLayer, BasicImplData {
|
||||
|
@ -295,7 +285,9 @@ public:
|
|||
mVisibleRegion = aRegion;
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
|
@ -305,7 +297,9 @@ protected:
|
|||
};
|
||||
|
||||
void
|
||||
BasicImageLayer::Paint(gfxContext* aContext)
|
||||
BasicImageLayer::Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
if (!mContainer)
|
||||
return;
|
||||
|
@ -365,7 +359,9 @@ public:
|
|||
mVisibleRegion = aRegion;
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
|
@ -375,7 +371,9 @@ protected:
|
|||
};
|
||||
|
||||
void
|
||||
BasicColorLayer::Paint(gfxContext* aContext)
|
||||
BasicColorLayer::Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
aContext->SetColor(mColor);
|
||||
aContext->Paint();
|
||||
|
@ -397,7 +395,9 @@ public:
|
|||
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Updated(const nsIntRect& aRect);
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
|
@ -484,7 +484,9 @@ BasicCanvasLayer::Updated(const nsIntRect& aRect)
|
|||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext)
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
|
||||
|
||||
|
@ -511,7 +513,7 @@ BasicCanvasLayer::Paint(gfxContext* aContext)
|
|||
}
|
||||
|
||||
BasicLayerManager::BasicLayerManager(gfxContext* aContext) :
|
||||
mDefaultTarget(aContext), mLastPainted(nsnull)
|
||||
mDefaultTarget(aContext)
|
||||
#ifdef DEBUG
|
||||
, mPhase(PHASE_NONE)
|
||||
#endif
|
||||
|
@ -554,24 +556,23 @@ BasicLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
|||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::EndConstruction()
|
||||
BasicLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
NS_ASSERTION(mRoot, "Root not set");
|
||||
NS_ASSERTION(mPhase == PHASE_CONSTRUCTION, "Should be in construction phase");
|
||||
#ifdef DEBUG
|
||||
mPhase = PHASE_DRAWING;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::EndTransaction()
|
||||
{
|
||||
NS_ASSERTION(mPhase == PHASE_DRAWING, "Should be in drawing phase");
|
||||
if (mTarget) {
|
||||
PaintLayer(mRoot, aCallback, aCallbackData);
|
||||
mTarget = nsnull;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mPhase = PHASE_NONE;
|
||||
#endif
|
||||
AdvancePaintingTo(nsnull);
|
||||
mTarget = nsnull;
|
||||
// No retained layers supported for now
|
||||
mRoot = nsnull;
|
||||
}
|
||||
|
@ -625,10 +626,14 @@ UseOpaqueSurface(Layer* aLayer)
|
|||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::BeginPaintingLayer(Layer* aLayer)
|
||||
BasicLayerManager::PaintLayer(Layer* aLayer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
PRBool needsGroup = NeedsGroup(aLayer);
|
||||
if ((needsGroup || NeedsState(aLayer)) && mTarget) {
|
||||
PRBool needsSaveRestore = needsGroup || NeedsState(aLayer);
|
||||
|
||||
if (needsSaveRestore) {
|
||||
mTarget->Save();
|
||||
|
||||
if (aLayer->GetClipRect()) {
|
||||
|
@ -667,66 +672,22 @@ BasicLayerManager::BeginPaintingLayer(Layer* aLayer)
|
|||
}
|
||||
}
|
||||
|
||||
mLastPainted = aLayer;
|
||||
ToData(aLayer)->Paint(mTarget, aCallback, aCallbackData);
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
PaintLayer(child, aCallback, aCallbackData);
|
||||
}
|
||||
|
||||
// For layers that paint themselves (e.g., BasicImageLayer), paint
|
||||
// them now.
|
||||
ToData(aLayer)->Paint(mTarget);
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::EndPaintingLayer()
|
||||
{
|
||||
PRBool needsGroup = NeedsGroup(mLastPainted);
|
||||
if ((needsGroup || NeedsState(mLastPainted)) && mTarget) {
|
||||
if (needsSaveRestore) {
|
||||
if (needsGroup) {
|
||||
mTarget->PopGroupToSource();
|
||||
mTarget->Paint(mLastPainted->GetOpacity());
|
||||
mTarget->Paint(aLayer->GetOpacity());
|
||||
}
|
||||
|
||||
mTarget->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::AdvancePaintingTo(BasicThebesLayer* aLayer)
|
||||
{
|
||||
NS_ASSERTION(!aLayer || IsBeforeInTree(mLastPainted, aLayer),
|
||||
"Painting layers out of order");
|
||||
|
||||
// Traverse the layer tree from mLastPainted to aLayer, calling
|
||||
// BeginPaintingLayer and EndPaintingLayer as we enter or exit layers.
|
||||
do {
|
||||
Layer* firstChild;
|
||||
Layer* nextSibling;
|
||||
// Advance mLastPainted one step through the tree in preorder
|
||||
if (!mLastPainted) {
|
||||
// This is the first AdvancePaintingTo call. Start at the root.
|
||||
BeginPaintingLayer(mRoot);
|
||||
} else if ((firstChild = mLastPainted->GetFirstChild()) != nsnull) {
|
||||
// Descend into our first child, if there is one.
|
||||
BeginPaintingLayer(firstChild);
|
||||
} else if ((nextSibling = mLastPainted->GetNextSibling()) != nsnull) {
|
||||
// There are no children to descend into. Leave this layer and
|
||||
// advance to our next sibling, if there is one.
|
||||
EndPaintingLayer();
|
||||
BeginPaintingLayer(nextSibling);
|
||||
} else {
|
||||
// There are no children to descend into and we have no next sibling.
|
||||
// Exit layers until we find a layer which has a next sibling
|
||||
// (or we exit the root).
|
||||
do {
|
||||
EndPaintingLayer();
|
||||
mLastPainted = mLastPainted->GetParent();
|
||||
} while (mLastPainted && !mLastPainted->GetNextSibling());
|
||||
if (mLastPainted) {
|
||||
EndPaintingLayer();
|
||||
BeginPaintingLayer(mLastPainted->GetNextSibling());
|
||||
}
|
||||
}
|
||||
} while (mLastPainted != aLayer);
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
BasicLayerManager::CreateThebesLayer()
|
||||
{
|
||||
|
@ -767,54 +728,5 @@ BasicLayerManager::CreateCanvasLayer()
|
|||
return layer.forget();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
AppendAncestors(Layer* aLayer, nsTArray<Layer*>* aAncestors)
|
||||
{
|
||||
while (aLayer) {
|
||||
aAncestors->AppendElement(aLayer);
|
||||
aLayer = aLayer->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
BasicLayerManager::IsBeforeInTree(Layer* aBefore, Layer* aLayer)
|
||||
{
|
||||
if (!aBefore) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
nsAutoTArray<Layer*,8> beforeAncestors, afterAncestors;
|
||||
AppendAncestors(aBefore, &beforeAncestors);
|
||||
AppendAncestors(aLayer, &afterAncestors);
|
||||
PRInt32 beforeIndex = beforeAncestors.Length() - 1;
|
||||
PRInt32 afterIndex = afterAncestors.Length() - 1;
|
||||
NS_ASSERTION(beforeAncestors[beforeIndex] == mRoot, "aBefore not in tree?");
|
||||
NS_ASSERTION(afterAncestors[afterIndex] == mRoot, "aLayer not in tree?");
|
||||
--beforeIndex;
|
||||
--afterIndex;
|
||||
while (beforeIndex >= 0 && afterIndex >= 0) {
|
||||
if (beforeAncestors[beforeIndex] != afterAncestors[afterIndex]) {
|
||||
BasicContainerLayer* parent =
|
||||
static_cast<BasicContainerLayer*>(beforeAncestors[beforeIndex + 1]);
|
||||
for (Layer* child = parent->GetFirstChild();
|
||||
child != afterAncestors[afterIndex];
|
||||
child = child->GetNextSibling()) {
|
||||
if (child == beforeAncestors[beforeIndex]) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
--beforeIndex;
|
||||
--afterIndex;
|
||||
}
|
||||
if (afterIndex > 0) {
|
||||
// aBefore is an ancestor of aLayer, so it's before aLayer in preorder
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,8 +78,8 @@ public:
|
|||
|
||||
virtual void BeginTransaction();
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
virtual void EndConstruction();
|
||||
virtual void EndTransaction();
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
virtual void SetRoot(Layer* aLayer);
|
||||
|
||||
|
@ -94,36 +94,20 @@ public:
|
|||
#ifdef DEBUG
|
||||
PRBool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
|
||||
PRBool InDrawing() { return mPhase == PHASE_DRAWING; }
|
||||
PRBool IsBeforeInTree(Layer* aBefore, Layer* aLayer);
|
||||
#endif
|
||||
// Prepares mTarget for painting into aLayer. Layers are painted
|
||||
// in tree order, so this method essentially traverses the layer tree
|
||||
// in preorder from mLastPainted to aLayer, doing whatever's needed
|
||||
// as we exit container layers and enter new container layers, and
|
||||
// drawing any non-ThebesLayers we encounter.
|
||||
void AdvancePaintingTo(BasicThebesLayer* aLayer);
|
||||
Layer* GetLastPainted() { return mLastPainted; }
|
||||
gfxContext* GetTarget() { return mTarget; }
|
||||
|
||||
private:
|
||||
// This gets called when we start painting aLayer. It can change
|
||||
// the state of mTarget by saving state, setting clipping and/or
|
||||
// pushing a group.
|
||||
void BeginPaintingLayer(Layer* aLayer);
|
||||
// This gets called when we finish painting aLayer. It can change
|
||||
// the state of mTarget by popping a group and/or restoring the state.
|
||||
void EndPaintingLayer();
|
||||
// Paints aLayer to mTarget.
|
||||
void PaintLayer(Layer* aLayer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
nsRefPtr<Layer> mRoot;
|
||||
// The default context for BeginTransaction.
|
||||
nsRefPtr<gfxContext> mDefaultTarget;
|
||||
// The context to draw into. This is always the context that
|
||||
// our ThebesLayers will return.
|
||||
// The context to draw into.
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
// The most recently painted layer during the drawing phase of
|
||||
// a transaction, or null if no layer has been painted in this
|
||||
// transaction.
|
||||
Layer* mLastPainted;
|
||||
|
||||
#ifdef DEBUG
|
||||
enum TransactionPhase { PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING };
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "CanvasLayerD3D9.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
CanvasLayerD3D9::~CanvasLayerD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::Initialize(const Data& aData)
|
||||
{
|
||||
NS_ASSERTION(mSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
|
||||
|
||||
if (aData.mSurface) {
|
||||
mSurface = aData.mSurface;
|
||||
NS_ASSERTION(aData.mGLContext == nsnull,
|
||||
"CanvasLayer can't have both surface and GLContext");
|
||||
mNeedsYFlip = PR_FALSE;
|
||||
} else if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
|
||||
mNeedsYFlip = PR_TRUE;
|
||||
} else {
|
||||
NS_ERROR("CanvasLayer created without mSurface or mGLContext?");
|
||||
}
|
||||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, 0,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::Updated(const nsIntRect& aRect)
|
||||
{
|
||||
if (!mTexture) {
|
||||
NS_WARNING("CanvasLayerD3D9::Updated called but no texture present!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
// WebGL reads entire surface.
|
||||
D3DLOCKED_RECT r;
|
||||
mTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
PRUint8 *destination;
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
destination = new PRUint8[mBounds.width * mBounds.height * 4];
|
||||
} else {
|
||||
destination = (PRUint8*)r.pBits;
|
||||
}
|
||||
|
||||
// We have to flush to ensure that any buffered GL operations are
|
||||
// in the framebuffer before we read.
|
||||
mGLContext->fFlush();
|
||||
|
||||
// For simplicity, we read the entire framebuffer for now -- in
|
||||
// the future we should use aRect, though with WebGL we don't
|
||||
// have an easy way to generate one.
|
||||
mGLContext->fReadPixels(0, 0, mBounds.width, mBounds.height,
|
||||
LOCAL_GL_BGRA, LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
destination);
|
||||
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
for (int y = 0; y < mBounds.height; y++) {
|
||||
memcpy((PRUint8*)r.pBits + r.Pitch * y,
|
||||
destination + mBounds.width * 4 * y,
|
||||
mBounds.width * 4);
|
||||
}
|
||||
delete [] destination;
|
||||
}
|
||||
mTexture->UnlockRect(0);
|
||||
} else if (mSurface) {
|
||||
RECT r;
|
||||
r.left = aRect.x;
|
||||
r.top = aRect.y;
|
||||
r.right = aRect.XMost();
|
||||
r.bottom = aRect.YMost();
|
||||
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
mTexture->LockRect(0, &lockedRect, &r, 0);
|
||||
|
||||
PRUint8 *startBits;
|
||||
PRUint32 sourceStride;
|
||||
|
||||
nsRefPtr<gfxImageSurface> sourceSurface;
|
||||
|
||||
if (mSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
|
||||
sourceSurface = static_cast<gfxWindowsSurface*>(mSurface.get())->GetImageSurface();
|
||||
startBits = sourceSurface->Data() + sourceSurface->Stride() * aRect.y +
|
||||
aRect.x * 4;
|
||||
sourceStride = sourceSurface->Stride();
|
||||
} else if (mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
sourceSurface = static_cast<gfxImageSurface*>(sourceSurface.get());
|
||||
if (sourceSurface->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
sourceSurface->Format() != gfxASurface::ImageFormatRGB24)
|
||||
{
|
||||
mTexture->UnlockRect(0);
|
||||
return;
|
||||
}
|
||||
startBits = sourceSurface->Data() + sourceSurface->Stride() * aRect.y +
|
||||
aRect.x * 4;
|
||||
sourceStride = sourceSurface->Stride();
|
||||
} else {
|
||||
sourceSurface = new gfxImageSurface(gfxIntSize(aRect.width, aRect.height),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(sourceSurface);
|
||||
ctx->Translate(gfxPoint(-aRect.x, -aRect.y));
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(sourceSurface);
|
||||
ctx->Paint();
|
||||
startBits = sourceSurface->Data();
|
||||
sourceStride = sourceSurface->Stride();
|
||||
}
|
||||
|
||||
for (int y = 0; y < aRect.height; y++) {
|
||||
memcpy((PRUint8*)lockedRect.pBits + lockedRect.Pitch * y,
|
||||
startBits + sourceStride * y,
|
||||
aRect.width * 4);
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
CanvasLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_CANVAS;
|
||||
}
|
||||
|
||||
Layer*
|
||||
CanvasLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::RenderLayer()
|
||||
{
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left. We also flip the Y axis here, note we can only do this
|
||||
* because we are in CULL_NONE mode!
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)mBounds.width;
|
||||
if (mNeedsYFlip) {
|
||||
quadTransform[1][1] = (float)-mBounds.height;
|
||||
quadTransform[3][1] = (float)mBounds.height - 0.5f;
|
||||
} else {
|
||||
quadTransform[1][1] = (float)mBounds.height;
|
||||
quadTransform[3][1] = -0.5f;
|
||||
}
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = -0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
if (!mGLBufferIsPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
}
|
||||
device()->SetTexture(0, mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
if (!mGLBufferIsPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_CANVASLAYEROGL_H
|
||||
#define GFX_CANVASLAYEROGL_H
|
||||
|
||||
#include "LayerManagerD3D9.h"
|
||||
#include "GLContext.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API CanvasLayerD3D9 :
|
||||
public CanvasLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
CanvasLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: CanvasLayer(aManager, NULL),
|
||||
LayerD3D9(aManager),
|
||||
mTexture(0),
|
||||
mGLBufferIsPremultiplied(PR_FALSE),
|
||||
mNeedsYFlip(PR_FALSE)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
~CanvasLayerD3D9();
|
||||
|
||||
// CanvasLayer implementation
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Updated(const nsIntRect& aRect);
|
||||
|
||||
// LayerD3D9 implementation
|
||||
virtual LayerType GetType();
|
||||
virtual Layer* GetLayer();
|
||||
virtual void RenderLayer();
|
||||
|
||||
protected:
|
||||
typedef mozilla::gl::GLContext GLContext;
|
||||
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<GLContext> mGLContext;
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
|
||||
nsIntRect mBounds;
|
||||
|
||||
PRPackedBool mGLBufferIsPremultiplied;
|
||||
PRPackedBool mNeedsYFlip;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_CANVASLAYERD3D9_H */
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert O'Callahan <robert@ocallahan.org>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ColorLayerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ColorLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_COLOR;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ColorLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
ColorLayerD3D9::RenderLayer()
|
||||
{
|
||||
// XXX we might be able to improve performance by using
|
||||
// IDirect3DDevice9::Clear
|
||||
|
||||
float quadTransform[4][4];
|
||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
||||
// Transform the quad to the size of the visible area.
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)visibleRect.width;
|
||||
quadTransform[1][1] = (float)visibleRect.height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)visibleRect.x;
|
||||
quadTransform[3][1] = (float)visibleRect.y;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float color[4];
|
||||
// color is premultiplied, so we need to adjust all channels
|
||||
color[0] = (float)(mColor.r * GetOpacity());
|
||||
color[1] = (float)(mColor.g * GetOpacity());
|
||||
color[2] = (float)(mColor.b * GetOpacity());
|
||||
color[3] = (float)(mColor.a * GetOpacity());
|
||||
|
||||
device()->SetPixelShaderConstantF(0, color, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::SOLIDCOLORLAYER);
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
|
@ -1,8 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/*
|
||||
*
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -16,16 +12,15 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is from xterm-122 source XFree86:
|
||||
* xc/programs/xterm/keysym2ucs.h,v 1.1 1999/06/12 15:37:18 dawes Exp.
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Markus G. Kuhn <mkuhn@acm.org> and Richard Verhoeven <river@win.tue.nl>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Frank Tang <ftang@netscape.com> adopt into mozilla
|
||||
* Robert O'Callahan <robert@ocallahan.org>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -40,22 +35,40 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* This module converts keysym values into the corresponding ISO 10646-1
|
||||
* (UCS, Unicode) values.
|
||||
*/
|
||||
|
||||
#include <X11/X.h>
|
||||
#ifndef GFX_COLORLAYERD3D9_H
|
||||
#define GFX_COLORLAYERD3D9_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "LayerManagerD3D9.h"
|
||||
|
||||
long keysym2ucs(KeySym keysym);
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
class THEBES_API ColorLayerD3D9 : public ColorLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ColorLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ColorLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion) { mVisibleRegion = aRegion; }
|
||||
|
||||
// LayerD3D9 Implementation
|
||||
virtual LayerType GetType();
|
||||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer();
|
||||
|
||||
protected:
|
||||
nsIntRegion mVisibleRegion;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_COLORLAYERD3D9_H */
|
|
@ -0,0 +1,252 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ContainerLayerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ContainerLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ContainerLayerD3D9::GetVisibleRect()
|
||||
{
|
||||
return mVisibleRect;
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
mVisibleRect = aRegion.GetBounds();
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::InsertAfter(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
LayerD3D9 *newChild = static_cast<LayerD3D9*>(aChild->ImplData());
|
||||
aChild->SetParent(this);
|
||||
if (!aAfter) {
|
||||
LayerD3D9 *oldFirstChild = GetFirstChildD3D9();
|
||||
mFirstChild = newChild->GetLayer();
|
||||
newChild->SetNextSibling(oldFirstChild);
|
||||
return;
|
||||
}
|
||||
for (LayerD3D9 *child = GetFirstChildD3D9();
|
||||
child; child = child->GetNextSibling()) {
|
||||
if (aAfter == child->GetLayer()) {
|
||||
LayerD3D9 *oldNextSibling = child->GetNextSibling();
|
||||
child->SetNextSibling(newChild);
|
||||
child->GetNextSibling()->SetNextSibling(oldNextSibling);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_WARNING("Failed to find aAfter layer!");
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::RemoveChild(Layer *aChild)
|
||||
{
|
||||
if (GetFirstChild() == aChild) {
|
||||
mFirstChild = GetFirstChildD3D9()->GetNextSibling() ?
|
||||
GetFirstChildD3D9()->GetNextSibling()->GetLayer() : nsnull;
|
||||
return;
|
||||
}
|
||||
LayerD3D9 *lastChild = NULL;
|
||||
for (LayerD3D9 *child = GetFirstChildD3D9(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (child->GetLayer() == aChild) {
|
||||
// We're sure this is not our first child. So lastChild != NULL.
|
||||
lastChild->SetNextSibling(child->GetNextSibling());
|
||||
child->SetNextSibling(NULL);
|
||||
child->GetLayer()->SetParent(NULL);
|
||||
return;
|
||||
}
|
||||
lastChild = child;
|
||||
}
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ContainerLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_CONTAINER;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ContainerLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
LayerD3D9*
|
||||
ContainerLayerD3D9::GetFirstChildD3D9()
|
||||
{
|
||||
if (!mFirstChild) {
|
||||
return nsnull;
|
||||
}
|
||||
return static_cast<LayerD3D9*>(mFirstChild->ImplData());
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::RenderLayer()
|
||||
{
|
||||
float opacity = GetOpacity();
|
||||
nsRefPtr<IDirect3DSurface9> previousRenderTarget;
|
||||
nsRefPtr<IDirect3DTexture9> renderTexture;
|
||||
float previousRenderTargetOffset[4];
|
||||
float renderTargetOffset[] = { 0, 0, 0, 0 };
|
||||
float oldViewMatrix[4][4];
|
||||
|
||||
PRBool useIntermediate = (opacity != 1.0 || !mTransform.IsIdentity());
|
||||
|
||||
if (useIntermediate) {
|
||||
device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
|
||||
NULL);
|
||||
nsRefPtr<IDirect3DSurface9> renderSurface;
|
||||
renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
|
||||
device()->SetRenderTarget(0, renderSurface);
|
||||
device()->GetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
|
||||
renderTargetOffset[0] = (float)GetVisibleRect().x;
|
||||
renderTargetOffset[1] = (float)GetVisibleRect().y;
|
||||
device()->SetVertexShaderConstantF(12, renderTargetOffset, 1);
|
||||
|
||||
float viewMatrix[4][4];
|
||||
/*
|
||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
||||
* <1.0, -1.0> bottomright)
|
||||
*/
|
||||
memset(&viewMatrix, 0, sizeof(viewMatrix));
|
||||
viewMatrix[0][0] = 2.0f / mVisibleRect.width;
|
||||
viewMatrix[1][1] = -2.0f / mVisibleRect.height;
|
||||
viewMatrix[2][2] = 1.0f;
|
||||
viewMatrix[3][0] = -1.0f;
|
||||
viewMatrix[3][1] = 1.0f;
|
||||
viewMatrix[3][3] = 1.0f;
|
||||
|
||||
device()->GetVertexShaderConstantF(8, &oldViewMatrix[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Render this container's contents.
|
||||
*/
|
||||
LayerD3D9 *layerToRender = GetFirstChildD3D9();
|
||||
while (layerToRender) {
|
||||
const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
|
||||
RECT r;
|
||||
if (clipRect) {
|
||||
r.left = (LONG)(clipRect->x - renderTargetOffset[0]);
|
||||
r.top = (LONG)(clipRect->y - renderTargetOffset[1]);
|
||||
r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width);
|
||||
r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height);
|
||||
} else {
|
||||
if (useIntermediate) {
|
||||
r.left = 0;
|
||||
r.top = 0;
|
||||
} else {
|
||||
r.left = GetVisibleRect().x;
|
||||
r.top = GetVisibleRect().y;
|
||||
}
|
||||
r.right = r.left + GetVisibleRect().width;
|
||||
r.bottom = r.top + GetVisibleRect().height;
|
||||
}
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> renderSurface;
|
||||
device()->GetRenderTarget(0, getter_AddRefs(renderSurface));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
renderSurface->GetDesc(&desc);
|
||||
|
||||
r.left = NS_MAX<LONG>(0, r.left);
|
||||
r.top = NS_MAX<LONG>(0, r.top);
|
||||
r.bottom = NS_MIN<LONG>(r.bottom, desc.Height);
|
||||
r.right = NS_MIN<LONG>(r.right, desc.Width);
|
||||
|
||||
device()->SetScissorRect(&r);
|
||||
|
||||
layerToRender->RenderLayer();
|
||||
layerToRender = layerToRender->GetNextSibling();
|
||||
}
|
||||
|
||||
if (useIntermediate) {
|
||||
device()->SetRenderTarget(0, previousRenderTarget);
|
||||
device()->SetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
|
||||
device()->SetVertexShaderConstantF(8, &oldViewMatrix[0][0], 4);
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left.
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)GetVisibleRect().width;
|
||||
quadTransform[1][1] = (float)GetVisibleRect().height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)GetVisibleRect().x - 0.5f;
|
||||
quadTransform[3][1] = (float)GetVisibleRect().y - 0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacityVector[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacityVector[0] = opacity;
|
||||
device()->SetPixelShaderConstantF(0, opacityVector, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, renderTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -13,20 +12,18 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
|
@ -38,23 +35,46 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* Interface for JS code testing tool which does compile-time checking. */
|
||||
#ifndef GFX_CONTAINERLAYERD3D9_H
|
||||
#define GFX_CONTAINERLAYERD3D9_H
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsILocalFile.idl"
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D9.h"
|
||||
|
||||
[scriptable, uuid(71151570-e56f-11d3-8f65-0010a4e73d9a)]
|
||||
interface nsIXPCToolsCompiler : nsISupports
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ContainerLayerD3D9 : public ContainerLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
/**
|
||||
* XXX temporary hack because there does not seem to be another scriptable
|
||||
* way to get this info.
|
||||
*/
|
||||
readonly attribute nsILocalFile binDir;
|
||||
public:
|
||||
ContainerLayerD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
void CompileFile(in nsILocalFile aFile, in PRBool strict);
|
||||
const nsIntRect &GetVisibleRect();
|
||||
|
||||
/* ContainerLayer implementation */
|
||||
void SetVisibleRegion(const nsIntRegion& aRegion);
|
||||
|
||||
void InsertAfter(Layer* aChild, Layer* aAfter);
|
||||
|
||||
void RemoveChild(Layer* aChild);
|
||||
|
||||
/* LayerD3D9 implementation */
|
||||
LayerType GetType();
|
||||
|
||||
Layer* GetLayer();
|
||||
|
||||
LayerD3D9* GetFirstChildD3D9();
|
||||
|
||||
PRBool IsEmpty();
|
||||
|
||||
void RenderLayer();
|
||||
|
||||
private:
|
||||
nsIntRect mVisibleRect;
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define XPCTOOLS_COMPILER_CONTRACTID "xpctools.compiler.1"
|
||||
%}
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_CONTAINERLAYERD3D9_H */
|
|
@ -0,0 +1,463 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ImageLayerD3D9.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "yuv_convert.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
|
||||
ImageContainerD3D9::ImageContainerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ImageContainer(aManager)
|
||||
, mActiveImageLock("mozilla.layers.ImageContainerD3D9.mActiveImageLock")
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<Image>
|
||||
ImageContainerD3D9::CreateImage(const Image::Format *aFormats,
|
||||
PRUint32 aNumFormats)
|
||||
{
|
||||
if (!aNumFormats) {
|
||||
return nsnull;
|
||||
}
|
||||
nsRefPtr<Image> img;
|
||||
if (aFormats[0] == Image::PLANAR_YCBCR) {
|
||||
img = new PlanarYCbCrImageD3D9(static_cast<LayerManagerD3D9*>(mManager));
|
||||
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
|
||||
img = new CairoImageD3D9(static_cast<LayerManagerD3D9*>(mManager));
|
||||
}
|
||||
return img.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ImageContainerD3D9::SetCurrentImage(Image *aImage)
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
|
||||
mActiveImage = aImage;
|
||||
}
|
||||
|
||||
already_AddRefed<Image>
|
||||
ImageContainerD3D9::GetCurrentImage()
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
|
||||
nsRefPtr<Image> retval = mActiveImage;
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
ImageContainerD3D9::GetCurrentAsSurface(gfxIntSize *aSize)
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
if (!mActiveImage) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
|
||||
if (yuvImage->HasData()) {
|
||||
*aSize = yuvImage->mSize;
|
||||
}
|
||||
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(mActiveImage.get());
|
||||
*aSize = cairoImage->mSize;
|
||||
}
|
||||
|
||||
return static_cast<ImageD3D9*>(mActiveImage->GetImplData())->GetAsSurface();
|
||||
}
|
||||
|
||||
gfxIntSize
|
||||
ImageContainerD3D9::GetCurrentSize()
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
if (!mActiveImage) {
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
|
||||
if (!yuvImage->HasData()) {
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
return yuvImage->mSize;
|
||||
|
||||
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(mActiveImage.get());
|
||||
return cairoImage->mSize;
|
||||
}
|
||||
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ImageLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_IMAGE;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ImageLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLayerD3D9::RenderLayer()
|
||||
{
|
||||
if (!GetContainer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Image> image = GetContainer()->GetCurrentImage();
|
||||
|
||||
if (image->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(image.get());
|
||||
|
||||
if (!yuvImage->HasData()) {
|
||||
return;
|
||||
}
|
||||
yuvImage->AllocateTextures();
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we extend the quad half a pixel
|
||||
* beyond all edges.
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)yuvImage->mSize.width + 0.5f;
|
||||
quadTransform[1][1] = (float)yuvImage->mSize.height + 0.5f;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will
|
||||
* only use the the first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::YCBCRLAYER);
|
||||
|
||||
device()->SetTexture(0, yuvImage->mYTexture);
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetTexture(1, yuvImage->mCbTexture);
|
||||
device()->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetTexture(2, yuvImage->mCrTexture);
|
||||
device()->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
} else if (image->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(image.get());
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we extend the quad half a pixel
|
||||
* beyond all edges.
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)cairoImage->mSize.width + 0.5f;
|
||||
quadTransform[1][1] = (float)cairoImage->mSize.height + 0.5f;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will
|
||||
* only use the the first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, cairoImage->mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9(mozilla::layers::LayerManagerD3D9* aManager)
|
||||
: PlanarYCbCrImage(static_cast<ImageD3D9*>(this))
|
||||
, mManager(aManager)
|
||||
, mHasData(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
// For now, we copy the data
|
||||
int width_shift = 0;
|
||||
int height_shift = 0;
|
||||
if (aData.mYSize.width == aData.mCbCrSize.width &&
|
||||
aData.mYSize.height == aData.mCbCrSize.height) {
|
||||
// YV24 format
|
||||
width_shift = 0;
|
||||
height_shift = 0;
|
||||
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
|
||||
aData.mYSize.height == aData.mCbCrSize.height) {
|
||||
// YV16 format
|
||||
width_shift = 1;
|
||||
height_shift = 0;
|
||||
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
|
||||
aData.mYSize.height / 2 == aData.mCbCrSize.height ) {
|
||||
// YV12 format
|
||||
width_shift = 1;
|
||||
height_shift = 1;
|
||||
} else {
|
||||
NS_ERROR("YCbCr format not supported");
|
||||
}
|
||||
|
||||
mData = aData;
|
||||
mData.mCbCrStride = mData.mCbCrSize.width = aData.mPicSize.width >> width_shift;
|
||||
mData.mCbCrSize.height = aData.mPicSize.height >> height_shift;
|
||||
mData.mYSize = aData.mPicSize;
|
||||
mData.mYStride = mData.mYSize.width;
|
||||
|
||||
mBuffer = new PRUint8[mData.mCbCrStride * mData.mCbCrSize.height * 2 +
|
||||
mData.mYStride * mData.mYSize.height];
|
||||
mData.mYChannel = mBuffer;
|
||||
mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
|
||||
mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
|
||||
|
||||
mData.mCrChannel = new PRUint8[mData.mCbCrStride * mData.mCbCrSize.height];
|
||||
int cbcr_x = aData.mPicX >> width_shift;
|
||||
int cbcr_y = aData.mPicY >> height_shift;
|
||||
|
||||
for (int i = 0; i < mData.mYSize.height; i++) {
|
||||
memcpy(mData.mYChannel + i * mData.mYStride,
|
||||
aData.mYChannel + ((aData.mPicY + i) * aData.mYStride) + aData.mPicX,
|
||||
mData.mYStride);
|
||||
}
|
||||
for (int i = 0; i < mData.mCbCrSize.height; i++) {
|
||||
memcpy(mData.mCbChannel + i * mData.mCbCrStride,
|
||||
aData.mCbChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x,
|
||||
mData.mCbCrStride);
|
||||
}
|
||||
for (int i = 0; i < mData.mCbCrSize.height; i++) {
|
||||
memcpy(mData.mCrChannel + i * mData.mCbCrStride,
|
||||
aData.mCrChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x,
|
||||
mData.mCbCrStride);
|
||||
}
|
||||
|
||||
// Fix picture rect to be correct
|
||||
mData.mPicX = mData.mPicY = 0;
|
||||
mSize = aData.mPicSize;
|
||||
|
||||
mHasData = PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::AllocateTextures()
|
||||
{
|
||||
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
PRUint8* src;
|
||||
PRUint8* dest;
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mYTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mYChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mYSize.height; h++) {
|
||||
memcpy(dest, src, mData.mYSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mYStride;
|
||||
}
|
||||
|
||||
mYTexture->UnlockRect(0);
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCbTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCbChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCbTexture->UnlockRect(0);
|
||||
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCrTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCrChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCrTexture->UnlockRect(0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::FreeTextures()
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
PlanarYCbCrImageD3D9::GetAsSurface()
|
||||
{
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface(mSize, gfxASurface::ImageFormatRGB24);
|
||||
|
||||
// Convert from YCbCr to RGB now
|
||||
gfx::ConvertYCbCrToRGB32(mData.mYChannel,
|
||||
mData.mCbChannel,
|
||||
mData.mCrChannel,
|
||||
imageSurface->Data(),
|
||||
0,
|
||||
0,
|
||||
mSize.width,
|
||||
mSize.height,
|
||||
mData.mYStride,
|
||||
mData.mCbCrStride,
|
||||
imageSurface->Stride(),
|
||||
gfx::YV12);
|
||||
|
||||
return imageSurface.forget().get();
|
||||
}
|
||||
|
||||
CairoImageD3D9::~CairoImageD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CairoImageD3D9::SetData(const CairoImage::Data &aData)
|
||||
{
|
||||
mSize = aData.mSize;
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface(aData.mSize, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
|
||||
|
||||
context->SetSource(aData.mSurface);
|
||||
context->Paint();
|
||||
|
||||
//XXX: make sure we're using the correct usage flags
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
/* lock the entire texture */
|
||||
mTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
PRUint8* src = imageSurface->Data();
|
||||
//FIX cast
|
||||
PRUint8* dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data. If we don't need to do any swaping we can
|
||||
// use memcpy
|
||||
for (int i=0; i<aData.mSize.width*aData.mSize.height; i++) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
CairoImageD3D9::GetAsSurface()
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
|
@ -0,0 +1,155 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_IMAGELAYERD3D9_H
|
||||
#define GFX_IMAGELAYERD3D9_H
|
||||
|
||||
#include "LayerManagerD3D9.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API ImageContainerD3D9 : public ImageContainer
|
||||
{
|
||||
public:
|
||||
ImageContainerD3D9(LayerManagerD3D9 *aManager);
|
||||
virtual ~ImageContainerD3D9() {}
|
||||
|
||||
virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
|
||||
PRUint32 aNumFormats);
|
||||
|
||||
virtual void SetCurrentImage(Image* aImage);
|
||||
|
||||
virtual already_AddRefed<Image> GetCurrentImage();
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
|
||||
|
||||
virtual gfxIntSize GetCurrentSize();
|
||||
|
||||
private:
|
||||
typedef mozilla::Mutex Mutex;
|
||||
|
||||
nsRefPtr<Image> mActiveImage;
|
||||
|
||||
Mutex mActiveImageLock;
|
||||
};
|
||||
|
||||
class THEBES_API ImageLayerD3D9 : public ImageLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ImageLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ImageLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
// LayerD3D9 Implementation
|
||||
virtual LayerType GetType();
|
||||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer();
|
||||
};
|
||||
|
||||
class THEBES_API ImageD3D9
|
||||
{
|
||||
public:
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
|
||||
};
|
||||
|
||||
class THEBES_API PlanarYCbCrImageD3D9 : public PlanarYCbCrImage,
|
||||
public ImageD3D9
|
||||
{
|
||||
public:
|
||||
PlanarYCbCrImageD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
virtual void SetData(const Data &aData);
|
||||
|
||||
/*
|
||||
* Upload the data from out mData into our textures. For now we use this to
|
||||
* make sure the textures are created and filled on the main thread.
|
||||
*/
|
||||
void AllocateTextures();
|
||||
/*
|
||||
* XXX
|
||||
* Free the textures, we call this from the main thread when we're done
|
||||
* drawing this frame. We cannot free this from the constructor since it may
|
||||
* be destroyed off the main-thread and might not be able to properly clean
|
||||
* up its textures
|
||||
*/
|
||||
void FreeTextures();
|
||||
PRBool HasData() { return mHasData; }
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
LayerManagerD3D9 *mManager;
|
||||
Data mData;
|
||||
gfxIntSize mSize;
|
||||
nsRefPtr<IDirect3DTexture9> mYTexture;
|
||||
nsRefPtr<IDirect3DTexture9> mCrTexture;
|
||||
nsRefPtr<IDirect3DTexture9> mCbTexture;
|
||||
PRPackedBool mHasData;
|
||||
};
|
||||
|
||||
|
||||
class THEBES_API CairoImageD3D9 : public CairoImage,
|
||||
public ImageD3D9
|
||||
{
|
||||
public:
|
||||
CairoImageD3D9(LayerManagerD3D9 *aManager)
|
||||
: CairoImage(static_cast<ImageD3D9*>(this))
|
||||
, mManager(aManager)
|
||||
{ }
|
||||
~CairoImageD3D9();
|
||||
|
||||
virtual void SetData(const Data &aData);
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
gfxIntSize mSize;
|
||||
LayerManagerD3D9 *mManager;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_IMAGELAYERD3D9_H */
|
|
@ -0,0 +1,578 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "LayerManagerD3D9.h"
|
||||
|
||||
#include "ThebesLayerD3D9.h"
|
||||
#include "ContainerLayerD3D9.h"
|
||||
#include "ImageLayerD3D9.h"
|
||||
#include "ColorLayerD3D9.h"
|
||||
#include "CanvasLayerD3D9.h"
|
||||
|
||||
#include "LayerManagerD3D9Shaders.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
IDirect3D9 *LayerManagerD3D9::mD3D9 = NULL;
|
||||
|
||||
typedef IDirect3D9* (WINAPI*Direct3DCreate9Func)(
|
||||
UINT SDKVersion
|
||||
);
|
||||
|
||||
|
||||
LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
|
||||
{
|
||||
mWidget = aWidget;
|
||||
mCurrentCallbackInfo.Callback = NULL;
|
||||
mCurrentCallbackInfo.CallbackData = NULL;
|
||||
}
|
||||
|
||||
LayerManagerD3D9::~LayerManagerD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::Initialize()
|
||||
{
|
||||
if (!mD3D9) {
|
||||
Direct3DCreate9Func d3d9create = (Direct3DCreate9Func)
|
||||
GetProcAddress(LoadLibraryW(L"d3d9.dll"), "Direct3DCreate9");
|
||||
if (!d3d9create) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
mD3D9 = d3d9create(D3D_SDK_VERSION);
|
||||
if (!mD3D9) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
HRESULT hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
NULL,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
getter_AddRefs(mDevice));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!VerifyCaps()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
|
||||
getter_AddRefs(mLayerVS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
|
||||
getter_AddRefs(mRGBPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPS,
|
||||
getter_AddRefs(mYCbCrPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPS,
|
||||
getter_AddRefs(mSolidColorPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
|
||||
0,
|
||||
0,
|
||||
D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mVB),
|
||||
NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertex *vertices;
|
||||
hr = mVB->Lock(0, 0, (void**)&vertices, 0);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertices[0].x = vertices[0].y = 0;
|
||||
vertices[1].x = 1; vertices[1].y = 0;
|
||||
vertices[2].x = 0; vertices[2].y = 1;
|
||||
vertices[3].x = 1; vertices[3].y = 1;
|
||||
|
||||
mVB->Unlock();
|
||||
|
||||
hr = mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
D3DVERTEXELEMENT9 elements[] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
|
||||
D3DDECLUSAGE_POSITION, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
mDevice->CreateVertexDeclaration(elements, getter_AddRefs(mVD));
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
nsCOMPtr<nsIConsoleService>
|
||||
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
|
||||
|
||||
if (console) {
|
||||
nsString msg;
|
||||
msg +=
|
||||
NS_LITERAL_STRING("Direct3D 9 LayerManager Initialized Succesfully.\nDriver: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Driver));
|
||||
msg += NS_LITERAL_STRING("\nDescription: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Description));
|
||||
msg += NS_LITERAL_STRING("\nVersion: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsPrintfCString("%d.%d.%d.%d",
|
||||
HIWORD(identifier.DriverVersion.HighPart),
|
||||
LOWORD(identifier.DriverVersion.HighPart),
|
||||
HIWORD(identifier.DriverVersion.LowPart),
|
||||
LOWORD(identifier.DriverVersion.LowPart)));
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetClippingRegion(const nsIntRegion &aClippingRegion)
|
||||
{
|
||||
mClippingRegion = aClippingRegion;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::BeginTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::BeginTransactionWithTarget(gfxContext *aTarget)
|
||||
{
|
||||
mTarget = aTarget;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::EndConstruction()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
mCurrentCallbackInfo.Callback = aCallback;
|
||||
mCurrentCallbackInfo.CallbackData = aCallbackData;
|
||||
Render();
|
||||
/* Clean this out for sanity */
|
||||
mCurrentCallbackInfo.Callback = NULL;
|
||||
mCurrentCallbackInfo.CallbackData = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetRoot(Layer *aLayer)
|
||||
{
|
||||
mRootLayer = static_cast<LayerD3D9*>(aLayer->ImplData());
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
LayerManagerD3D9::CreateThebesLayer()
|
||||
{
|
||||
nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
LayerManagerD3D9::CreateContainerLayer()
|
||||
{
|
||||
nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
LayerManagerD3D9::CreateImageLayer()
|
||||
{
|
||||
nsRefPtr<ImageLayer> layer = new ImageLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ColorLayer>
|
||||
LayerManagerD3D9::CreateColorLayer()
|
||||
{
|
||||
nsRefPtr<ColorLayer> layer = new ColorLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
LayerManagerD3D9::CreateCanvasLayer()
|
||||
{
|
||||
nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
LayerManagerD3D9::CreateImageContainer()
|
||||
{
|
||||
nsRefPtr<ImageContainer> container = new ImageContainerD3D9(this);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetShaderMode(ShaderMode aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mRGBPS);
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mYCbCrPS);
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::Render()
|
||||
{
|
||||
if (!SetupBackBuffer()) {
|
||||
return;
|
||||
}
|
||||
SetupPipeline();
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
|
||||
mDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0, 0);
|
||||
|
||||
mDevice->BeginScene();
|
||||
|
||||
if (mRootLayer) {
|
||||
const nsIntRect *clipRect = mRootLayer->GetLayer()->GetClipRect();
|
||||
RECT r;
|
||||
if (clipRect) {
|
||||
r.left = (LONG)clipRect->x;
|
||||
r.top = (LONG)clipRect->y;
|
||||
r.right = (LONG)(clipRect->x + clipRect->width);
|
||||
r.bottom = (LONG)(clipRect->y + clipRect->height);
|
||||
} else {
|
||||
r.left = r.top = 0;
|
||||
r.right = rect.width;
|
||||
r.bottom = rect.height;
|
||||
}
|
||||
mDevice->SetScissorRect(&r);
|
||||
|
||||
mRootLayer->RenderLayer();
|
||||
}
|
||||
|
||||
mDevice->EndScene();
|
||||
|
||||
if (!mTarget) {
|
||||
const nsIntRect *r;
|
||||
for (nsIntRegionRectIterator iter(mClippingRegion);
|
||||
(r = iter.Next()) != nsnull;) {
|
||||
RECT rect;
|
||||
rect.left = r->x;
|
||||
rect.top = r->y;
|
||||
rect.right = r->XMost();
|
||||
rect.bottom = r->YMost();
|
||||
|
||||
mDevice->Present(&rect, &rect, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
PaintToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetupPipeline()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
|
||||
float viewMatrix[4][4];
|
||||
/*
|
||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
||||
* <1.0, -1.0> bottomright)
|
||||
*/
|
||||
memset(&viewMatrix, 0, sizeof(viewMatrix));
|
||||
viewMatrix[0][0] = 2.0f / rect.width;
|
||||
viewMatrix[1][1] = -2.0f / rect.height;
|
||||
viewMatrix[2][2] = 1.0f;
|
||||
viewMatrix[3][0] = -1.0f;
|
||||
viewMatrix[3][1] = 1.0f;
|
||||
viewMatrix[3][3] = 1.0f;
|
||||
|
||||
HRESULT hr = mDevice->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to set projection shader constant!");
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::SetupBackBuffer()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
backBuffer->GetDesc(&desc);
|
||||
|
||||
HRESULT hr = mDevice->TestCooperativeLevel();
|
||||
|
||||
/* The device is lost or something else is wrong, failure */
|
||||
if (FAILED(hr) && hr != D3DERR_DEVICENOTRESET) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the backbuffer is the right size, and the device is not lost, we can
|
||||
* safely render without doing anything.
|
||||
*/
|
||||
if ((desc.Width == rect.width && desc.Height == rect.height) &&
|
||||
SUCCEEDED(hr)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our device is lost or our backbuffer needs resizing, start by clearing
|
||||
* out all D3DPOOL_DEFAULT surfaces.
|
||||
*/
|
||||
for(unsigned int i = 0; i < mThebesLayers.Length(); i++) {
|
||||
mThebesLayers[i]->CleanResources();
|
||||
}
|
||||
|
||||
backBuffer = NULL;
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
hr = mDevice->Reset(&pp);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::PaintToTarget()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuff;
|
||||
nsRefPtr<IDirect3DSurface9> destSurf;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuff));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuff->GetDesc(&desc);
|
||||
|
||||
mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(destSurf), NULL);
|
||||
|
||||
mDevice->GetRenderTargetData(backBuff, destSurf);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface((unsigned char*)rect.pBits,
|
||||
gfxIntSize(desc.Width, desc.Height),
|
||||
rect.Pitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(imageSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
mTarget->Paint();
|
||||
destSurf->UnlockRect();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetupRenderState()
|
||||
{
|
||||
mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
mDevice->SetVertexDeclaration(mVD);
|
||||
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::VerifyCaps()
|
||||
{
|
||||
D3DCAPS9 caps;
|
||||
HRESULT hr = mDevice->GetDeviceCaps(&caps);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.DevCaps, D3DDEVCAPS_TEXTUREVIDEOMEMORY)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.SrcBlendCaps, D3DPBLENDCAPS_ONE) ||
|
||||
LACKS_CAP(caps.SrcBlendCaps, D3DBLEND_SRCALPHA) ||
|
||||
LACKS_CAP(caps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_ALPHA) ||
|
||||
HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_SQUAREONLY) ||
|
||||
(HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_POW2) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR) ||
|
||||
LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (caps.MaxTextureHeight < 4096 ||
|
||||
caps.MaxTextureWidth < 4096) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((caps.PixelShaderVersion & 0xffff) < 0x200 ||
|
||||
(caps.VertexShaderVersion & 0xffff) < 0x200) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
LayerD3D9::LayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: mD3DManager(aManager)
|
||||
, mNextSibling(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LayerD3D9*
|
||||
LayerD3D9::GetNextSibling()
|
||||
{
|
||||
return mNextSibling;
|
||||
}
|
||||
|
||||
void
|
||||
LayerD3D9::SetNextSibling(LayerD3D9 *aNextSibling)
|
||||
{
|
||||
mNextSibling = aNextSibling;
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
|
@ -0,0 +1,239 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_LAYERMANAGERD3D9_H
|
||||
#define GFX_LAYERMANAGERD3D9_H
|
||||
|
||||
#include "Layers.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class LayerD3D9;
|
||||
class ThebesLayerD3D9;
|
||||
|
||||
/*
|
||||
* This is the LayerManager used for Direct3D 9. For now this will render on
|
||||
* the main thread.
|
||||
*/
|
||||
class THEBES_API LayerManagerD3D9 : public LayerManager {
|
||||
public:
|
||||
LayerManagerD3D9(nsIWidget *aWidget);
|
||||
virtual ~LayerManagerD3D9();
|
||||
|
||||
/*
|
||||
* Initializes the layer manager, this is when the layer manager will
|
||||
* actually access the device and attempt to create the swap chain used
|
||||
* to draw to the window. If this method fails the device cannot be used.
|
||||
* This function is not threadsafe.
|
||||
*
|
||||
* \return True is initialization was succesful, false when it was not.
|
||||
*/
|
||||
PRBool Initialize();
|
||||
|
||||
/*
|
||||
* Sets the clipping region for this layer manager. This is important on
|
||||
* windows because using OGL we no longer have GDI's native clipping. Therefor
|
||||
* widget must tell us what part of the screen is being invalidated,
|
||||
* and we should clip to this.
|
||||
*
|
||||
* \param aClippingRegion Region to clip to. Setting an empty region
|
||||
* will disable clipping.
|
||||
*/
|
||||
void SetClippingRegion(const nsIntRegion& aClippingRegion);
|
||||
|
||||
/*
|
||||
* LayerManager implementation.
|
||||
*/
|
||||
void BeginTransaction();
|
||||
|
||||
void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
|
||||
void EndConstruction();
|
||||
|
||||
struct CallbackInfo {
|
||||
DrawThebesLayerCallback Callback;
|
||||
void *CallbackData;
|
||||
};
|
||||
|
||||
void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; }
|
||||
|
||||
void SetRoot(Layer* aLayer);
|
||||
|
||||
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
|
||||
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
||||
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
||||
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
||||
|
||||
virtual already_AddRefed<ImageContainer> CreateImageContainer();
|
||||
|
||||
virtual LayersBackend GetBackendType() { return LAYERS_D3D9; }
|
||||
|
||||
/*
|
||||
* Helper methods.
|
||||
*/
|
||||
void SetClippingEnabled(PRBool aEnabled);
|
||||
|
||||
IDirect3DDevice9 *device() const { return mDevice; }
|
||||
|
||||
enum ShaderMode {
|
||||
RGBLAYER,
|
||||
YCBCRLAYER,
|
||||
SOLIDCOLORLAYER
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode);
|
||||
|
||||
nsTArray<ThebesLayerD3D9*> mThebesLayers;
|
||||
|
||||
private:
|
||||
/* Direct3D9 instance */
|
||||
static IDirect3D9 *mD3D9;
|
||||
|
||||
/* Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
/*
|
||||
* Context target, NULL when drawing directly to our swap chain.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsRefPtr<IDirect3DDevice9> mDevice;
|
||||
|
||||
/* Vertex shader used for layer quads */
|
||||
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mRGBPS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mYCbCrPS;
|
||||
|
||||
/* Pixel shader used for solid colors */
|
||||
nsRefPtr<IDirect3DPixelShader9> mSolidColorPS;
|
||||
|
||||
/* Vertex buffer containing our basic vertex structure */
|
||||
nsRefPtr<IDirect3DVertexBuffer9> mVB;
|
||||
|
||||
/* Our vertex declaration */
|
||||
nsRefPtr<IDirect3DVertexDeclaration9> mVD;
|
||||
|
||||
/* Current root layer. */
|
||||
LayerD3D9 *mRootLayer;
|
||||
|
||||
/* Callback info for current transaction */
|
||||
CallbackInfo mCurrentCallbackInfo;
|
||||
|
||||
/*
|
||||
* Region we're clipping our current drawing to.
|
||||
*/
|
||||
nsIntRegion mClippingRegion;
|
||||
/*
|
||||
* Render the current layer tree to the active target.
|
||||
*/
|
||||
void Render();
|
||||
/*
|
||||
* Setup the pipeline.
|
||||
*/
|
||||
void SetupPipeline();
|
||||
/*
|
||||
* Setup the backbuffer.
|
||||
*
|
||||
* \return PR_TRUE if setup was succesful
|
||||
*/
|
||||
PRBool SetupBackBuffer();
|
||||
/*
|
||||
* Setup the render state for the surface.
|
||||
*/
|
||||
void SetupRenderState();
|
||||
/*
|
||||
* Copies the content of our backbuffer to the set transaction target.
|
||||
*/
|
||||
void PaintToTarget();
|
||||
/*
|
||||
* Verifies all required device capabilities are present.
|
||||
*/
|
||||
PRBool VerifyCaps();
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* General information and tree management for OGL layers.
|
||||
*/
|
||||
class LayerD3D9
|
||||
{
|
||||
public:
|
||||
LayerD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE, TYPE_COLOR,
|
||||
TYPE_CANVAS };
|
||||
|
||||
virtual LayerType GetType() = 0;
|
||||
|
||||
LayerD3D9 *GetNextSibling();
|
||||
virtual LayerD3D9 *GetFirstChildD3D9() { return nsnull; }
|
||||
|
||||
void SetNextSibling(LayerD3D9 *aParent);
|
||||
void SetFirstChild(LayerD3D9 *aParent);
|
||||
|
||||
virtual Layer* GetLayer() = 0;
|
||||
|
||||
virtual void RenderLayer() = 0;
|
||||
|
||||
IDirect3DDevice9 *device() const { return mD3DManager->device(); }
|
||||
protected:
|
||||
LayerManagerD3D9 *mD3DManager;
|
||||
LayerD3D9 *mNextSibling;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_LAYERMANAGERD3D9_H */
|
|
@ -0,0 +1,435 @@
|
|||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ELayerQuadVS /nologo
|
||||
// /FhLayerManagerD3D9Shaders.h /VnLayerQuadVS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float4x4 mLayerQuadTransform;
|
||||
// float4x4 mLayerTransform;
|
||||
// float4x4 mProjection;
|
||||
// float4 vRenderTargetOffset;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------------- ----- ----
|
||||
// mLayerQuadTransform c0 4
|
||||
// mLayerTransform c4 4
|
||||
// mProjection c8 4
|
||||
// vRenderTargetOffset c12 1
|
||||
//
|
||||
|
||||
vs_2_0
|
||||
dcl_position v0
|
||||
mul r0, v0.y, c1
|
||||
mad r0, c0, v0.x, r0
|
||||
mad r0, c2, v0.z, r0
|
||||
mad r0, c3, v0.w, r0
|
||||
mul r1, r0.y, c5
|
||||
mad r1, c4, r0.x, r1
|
||||
mad r1, c6, r0.z, r1
|
||||
mad r0, c7, r0.w, r1
|
||||
add r0, r0, -c12
|
||||
mul r1, r0.y, c9
|
||||
mad r1, c8, r0.x, r1
|
||||
mad r1, c10, r0.z, r1
|
||||
mad oPos, c11, r0.w, r1
|
||||
mov oT0.xy, v0
|
||||
|
||||
// approximately 14 instruction slots used
|
||||
#endif
|
||||
|
||||
const BYTE LayerQuadVS[] =
|
||||
{
|
||||
0, 2, 254, 255, 254, 255,
|
||||
67, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 215, 0,
|
||||
0, 0, 0, 2, 254, 255,
|
||||
4, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
208, 0, 0, 0, 108, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
4, 0, 0, 0, 128, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
144, 0, 0, 0, 2, 0,
|
||||
4, 0, 4, 0, 0, 0,
|
||||
128, 0, 0, 0, 0, 0,
|
||||
0, 0, 160, 0, 0, 0,
|
||||
2, 0, 8, 0, 4, 0,
|
||||
0, 0, 128, 0, 0, 0,
|
||||
0, 0, 0, 0, 172, 0,
|
||||
0, 0, 2, 0, 12, 0,
|
||||
1, 0, 0, 0, 192, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
109, 76, 97, 121, 101, 114,
|
||||
81, 117, 97, 100, 84, 114,
|
||||
97, 110, 115, 102, 111, 114,
|
||||
109, 0, 3, 0, 3, 0,
|
||||
4, 0, 4, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
109, 76, 97, 121, 101, 114,
|
||||
84, 114, 97, 110, 115, 102,
|
||||
111, 114, 109, 0, 109, 80,
|
||||
114, 111, 106, 101, 99, 116,
|
||||
105, 111, 110, 0, 118, 82,
|
||||
101, 110, 100, 101, 114, 84,
|
||||
97, 114, 103, 101, 116, 79,
|
||||
102, 102, 115, 101, 116, 0,
|
||||
1, 0, 3, 0, 1, 0,
|
||||
4, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 118, 115,
|
||||
95, 50, 95, 48, 0, 77,
|
||||
105, 99, 114, 111, 115, 111,
|
||||
102, 116, 32, 40, 82, 41,
|
||||
32, 72, 76, 83, 76, 32,
|
||||
83, 104, 97, 100, 101, 114,
|
||||
32, 67, 111, 109, 112, 105,
|
||||
108, 101, 114, 32, 57, 46,
|
||||
50, 55, 46, 57, 53, 50,
|
||||
46, 51, 48, 50, 50, 0,
|
||||
31, 0, 0, 2, 0, 0,
|
||||
0, 128, 0, 0, 15, 144,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
15, 128, 0, 0, 85, 144,
|
||||
1, 0, 228, 160, 4, 0,
|
||||
0, 4, 0, 0, 15, 128,
|
||||
0, 0, 228, 160, 0, 0,
|
||||
0, 144, 0, 0, 228, 128,
|
||||
4, 0, 0, 4, 0, 0,
|
||||
15, 128, 2, 0, 228, 160,
|
||||
0, 0, 170, 144, 0, 0,
|
||||
228, 128, 4, 0, 0, 4,
|
||||
0, 0, 15, 128, 3, 0,
|
||||
228, 160, 0, 0, 255, 144,
|
||||
0, 0, 228, 128, 5, 0,
|
||||
0, 3, 1, 0, 15, 128,
|
||||
0, 0, 85, 128, 5, 0,
|
||||
228, 160, 4, 0, 0, 4,
|
||||
1, 0, 15, 128, 4, 0,
|
||||
228, 160, 0, 0, 0, 128,
|
||||
1, 0, 228, 128, 4, 0,
|
||||
0, 4, 1, 0, 15, 128,
|
||||
6, 0, 228, 160, 0, 0,
|
||||
170, 128, 1, 0, 228, 128,
|
||||
4, 0, 0, 4, 0, 0,
|
||||
15, 128, 7, 0, 228, 160,
|
||||
0, 0, 255, 128, 1, 0,
|
||||
228, 128, 2, 0, 0, 3,
|
||||
0, 0, 15, 128, 0, 0,
|
||||
228, 128, 12, 0, 228, 161,
|
||||
5, 0, 0, 3, 1, 0,
|
||||
15, 128, 0, 0, 85, 128,
|
||||
9, 0, 228, 160, 4, 0,
|
||||
0, 4, 1, 0, 15, 128,
|
||||
8, 0, 228, 160, 0, 0,
|
||||
0, 128, 1, 0, 228, 128,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
15, 128, 10, 0, 228, 160,
|
||||
0, 0, 170, 128, 1, 0,
|
||||
228, 128, 4, 0, 0, 4,
|
||||
0, 0, 15, 192, 11, 0,
|
||||
228, 160, 0, 0, 255, 128,
|
||||
1, 0, 228, 128, 1, 0,
|
||||
0, 2, 0, 0, 3, 224,
|
||||
0, 0, 228, 144, 255, 255,
|
||||
0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ERGBShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnRGBShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float fLayerOpacity;
|
||||
// sampler2D s2D;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------- ----- ----
|
||||
// fLayerOpacity c0 1
|
||||
// s2D s0 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
dcl t0.xy
|
||||
dcl_2d s0
|
||||
texld r0, t0, s0
|
||||
mul r0, r0, c0.x
|
||||
mov oC0, r0
|
||||
|
||||
// approximately 3 instruction slots used (1 texture, 2 arithmetic)
|
||||
#endif
|
||||
|
||||
const BYTE RGBShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
45, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 127, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
2, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
120, 0, 0, 0, 68, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 84, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
100, 0, 0, 0, 3, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
104, 0, 0, 0, 0, 0,
|
||||
0, 0, 102, 76, 97, 121,
|
||||
101, 114, 79, 112, 97, 99,
|
||||
105, 116, 121, 0, 171, 171,
|
||||
0, 0, 3, 0, 1, 0,
|
||||
1, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 115, 50,
|
||||
68, 0, 4, 0, 12, 0,
|
||||
1, 0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
112, 115, 95, 50, 95, 48,
|
||||
0, 77, 105, 99, 114, 111,
|
||||
115, 111, 102, 116, 32, 40,
|
||||
82, 41, 32, 72, 76, 83,
|
||||
76, 32, 83, 104, 97, 100,
|
||||
101, 114, 32, 67, 111, 109,
|
||||
112, 105, 108, 101, 114, 32,
|
||||
57, 46, 50, 55, 46, 57,
|
||||
53, 50, 46, 51, 48, 50,
|
||||
50, 0, 31, 0, 0, 2,
|
||||
0, 0, 0, 128, 0, 0,
|
||||
3, 176, 31, 0, 0, 2,
|
||||
0, 0, 0, 144, 0, 8,
|
||||
15, 160, 66, 0, 0, 3,
|
||||
0, 0, 15, 128, 0, 0,
|
||||
228, 176, 0, 8, 228, 160,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
15, 128, 0, 0, 228, 128,
|
||||
0, 0, 0, 160, 1, 0,
|
||||
0, 2, 0, 8, 15, 128,
|
||||
0, 0, 228, 128, 255, 255,
|
||||
0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /EYCbCrShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnYCbCrShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float fLayerOpacity;
|
||||
// sampler2D s2DCb;
|
||||
// sampler2D s2DCr;
|
||||
// sampler2D s2DY;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------- ----- ----
|
||||
// fLayerOpacity c0 1
|
||||
// s2DY s0 1
|
||||
// s2DCb s1 1
|
||||
// s2DCr s2 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
def c1, -0.5, -0.0625, 1.16400003, 1.59599996
|
||||
def c2, 0.813000023, 0.391000003, 2.01799989, 1
|
||||
dcl t0.xy
|
||||
dcl_2d s0
|
||||
dcl_2d s1
|
||||
dcl_2d s2
|
||||
texld r0, t0, s2
|
||||
texld r1, t0, s0
|
||||
texld r2, t0, s1
|
||||
add r0.x, r0.x, c1.x
|
||||
add r0.y, r1.x, c1.y
|
||||
mul r0.y, r0.y, c1.z
|
||||
mad r0.z, r0.x, -c2.x, r0.y
|
||||
mad r1.x, r0.x, c1.w, r0.y
|
||||
add r0.x, r2.x, c1.x
|
||||
mad r1.y, r0.x, -c2.y, r0.z
|
||||
mad r1.z, r0.x, c2.z, r0.y
|
||||
mov r1.w, c2.w
|
||||
mul r0, r1, c0.x
|
||||
mov oC0, r0
|
||||
|
||||
// approximately 14 instruction slots used (3 texture, 11 arithmetic)
|
||||
#endif
|
||||
|
||||
const BYTE YCbCrShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
68, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 219, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
4, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
212, 0, 0, 0, 108, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 124, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
140, 0, 0, 0, 3, 0,
|
||||
1, 0, 1, 0, 0, 0,
|
||||
148, 0, 0, 0, 0, 0,
|
||||
0, 0, 164, 0, 0, 0,
|
||||
3, 0, 2, 0, 1, 0,
|
||||
0, 0, 172, 0, 0, 0,
|
||||
0, 0, 0, 0, 188, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
1, 0, 0, 0, 196, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
102, 76, 97, 121, 101, 114,
|
||||
79, 112, 97, 99, 105, 116,
|
||||
121, 0, 171, 171, 0, 0,
|
||||
3, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 67,
|
||||
98, 0, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 67,
|
||||
114, 0, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 89,
|
||||
0, 171, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 112, 115, 95, 50,
|
||||
95, 48, 0, 77, 105, 99,
|
||||
114, 111, 115, 111, 102, 116,
|
||||
32, 40, 82, 41, 32, 72,
|
||||
76, 83, 76, 32, 83, 104,
|
||||
97, 100, 101, 114, 32, 67,
|
||||
111, 109, 112, 105, 108, 101,
|
||||
114, 32, 57, 46, 50, 55,
|
||||
46, 57, 53, 50, 46, 51,
|
||||
48, 50, 50, 0, 81, 0,
|
||||
0, 5, 1, 0, 15, 160,
|
||||
0, 0, 0, 191, 0, 0,
|
||||
128, 189, 244, 253, 148, 63,
|
||||
186, 73, 204, 63, 81, 0,
|
||||
0, 5, 2, 0, 15, 160,
|
||||
197, 32, 80, 63, 39, 49,
|
||||
200, 62, 233, 38, 1, 64,
|
||||
0, 0, 128, 63, 31, 0,
|
||||
0, 2, 0, 0, 0, 128,
|
||||
0, 0, 3, 176, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
0, 8, 15, 160, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
1, 8, 15, 160, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
2, 8, 15, 160, 66, 0,
|
||||
0, 3, 0, 0, 15, 128,
|
||||
0, 0, 228, 176, 2, 8,
|
||||
228, 160, 66, 0, 0, 3,
|
||||
1, 0, 15, 128, 0, 0,
|
||||
228, 176, 0, 8, 228, 160,
|
||||
66, 0, 0, 3, 2, 0,
|
||||
15, 128, 0, 0, 228, 176,
|
||||
1, 8, 228, 160, 2, 0,
|
||||
0, 3, 0, 0, 1, 128,
|
||||
0, 0, 0, 128, 1, 0,
|
||||
0, 160, 2, 0, 0, 3,
|
||||
0, 0, 2, 128, 1, 0,
|
||||
0, 128, 1, 0, 85, 160,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
2, 128, 0, 0, 85, 128,
|
||||
1, 0, 170, 160, 4, 0,
|
||||
0, 4, 0, 0, 4, 128,
|
||||
0, 0, 0, 128, 2, 0,
|
||||
0, 161, 0, 0, 85, 128,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
1, 128, 0, 0, 0, 128,
|
||||
1, 0, 255, 160, 0, 0,
|
||||
85, 128, 2, 0, 0, 3,
|
||||
0, 0, 1, 128, 2, 0,
|
||||
0, 128, 1, 0, 0, 160,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
2, 128, 0, 0, 0, 128,
|
||||
2, 0, 85, 161, 0, 0,
|
||||
170, 128, 4, 0, 0, 4,
|
||||
1, 0, 4, 128, 0, 0,
|
||||
0, 128, 2, 0, 170, 160,
|
||||
0, 0, 85, 128, 1, 0,
|
||||
0, 2, 1, 0, 8, 128,
|
||||
2, 0, 255, 160, 5, 0,
|
||||
0, 3, 0, 0, 15, 128,
|
||||
1, 0, 228, 128, 0, 0,
|
||||
0, 160, 1, 0, 0, 2,
|
||||
0, 8, 15, 128, 0, 0,
|
||||
228, 128, 255, 255, 0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ESolidColorShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnSolidColorShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float4 fLayerColor;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------ ----- ----
|
||||
// fLayerColor c0 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
mov oC0, c0
|
||||
|
||||
// approximately 1 instruction slot used
|
||||
#endif
|
||||
|
||||
const BYTE SolidColorShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
34, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 83, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
1, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
76, 0, 0, 0, 48, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 60, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
102, 76, 97, 121, 101, 114,
|
||||
67, 111, 108, 111, 114, 0,
|
||||
1, 0, 3, 0, 1, 0,
|
||||
4, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 112, 115,
|
||||
95, 50, 95, 48, 0, 77,
|
||||
105, 99, 114, 111, 115, 111,
|
||||
102, 116, 32, 40, 82, 41,
|
||||
32, 72, 76, 83, 76, 32,
|
||||
83, 104, 97, 100, 101, 114,
|
||||
32, 67, 111, 109, 112, 105,
|
||||
108, 101, 114, 32, 57, 46,
|
||||
50, 55, 46, 57, 53, 50,
|
||||
46, 51, 48, 50, 50, 0,
|
||||
1, 0, 0, 2, 0, 8,
|
||||
15, 128, 0, 0, 228, 160,
|
||||
255, 255, 0, 0
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
float4x4 mLayerQuadTransform;
|
||||
float4x4 mLayerTransform;
|
||||
float4 vRenderTargetOffset;
|
||||
float4x4 mProjection;
|
||||
|
||||
texture tex0;
|
||||
sampler s2D;
|
||||
sampler s2DY;
|
||||
sampler s2DCb;
|
||||
sampler s2DCr;
|
||||
|
||||
float fLayerOpacity;
|
||||
float4 fLayerColor;
|
||||
|
||||
struct VS_INPUT {
|
||||
float4 vPosition : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 vPosition : POSITION;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_OUTPUT outp;
|
||||
outp.vPosition = aVertex.vPosition;
|
||||
outp.vPosition = mul(mLayerQuadTransform, outp.vPosition);
|
||||
outp.vPosition = mul(mLayerTransform, outp.vPosition);
|
||||
outp.vPosition = outp.vPosition - vRenderTargetOffset;
|
||||
outp.vPosition = mul(mProjection, outp.vPosition);
|
||||
outp.vTexCoords = aVertex.vPosition.xy;
|
||||
return outp;
|
||||
}
|
||||
|
||||
float4 RGBShader(const VS_OUTPUT aVertex) : COLOR
|
||||
{
|
||||
return tex2D(s2D, aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
float4 YCbCrShader(const VS_OUTPUT aVertex) : COLOR
|
||||
{
|
||||
float4 yuv;
|
||||
float4 color;
|
||||
|
||||
yuv.r = tex2D(s2DCr, aVertex.vTexCoords).r - 0.5;
|
||||
yuv.g = tex2D(s2DY, aVertex.vTexCoords).r - 0.0625;
|
||||
yuv.b = tex2D(s2DCb, aVertex.vTexCoords).r - 0.5;
|
||||
|
||||
color.r = yuv.g * 1.164 + yuv.r * 1.596;
|
||||
color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;
|
||||
color.b = yuv.g * 1.164 + yuv.b * 2.018;
|
||||
color.a = 1.0f;
|
||||
|
||||
return color * fLayerOpacity;
|
||||
}
|
||||
|
||||
float4 SolidColorShader(const VS_OUTPUT aVertex) : COLOR
|
||||
{
|
||||
return fLayerColor;
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ThebesLayerD3D9.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ThebesLayerD3D9::ThebesLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ThebesLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
aManager->mThebesLayers.AppendElement(this);
|
||||
}
|
||||
|
||||
ThebesLayerD3D9::~ThebesLayerD3D9()
|
||||
{
|
||||
mD3DManager->mThebesLayers.RemoveElement(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
if (aRegion.GetBounds() == mVisibleRect) {
|
||||
return;
|
||||
}
|
||||
mVisibleRect = aRegion.GetBounds();
|
||||
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
|
||||
mInvalidatedRect = mVisibleRect;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
nsIntRegion invalidatedRegion;
|
||||
invalidatedRegion.Or(aRegion, mInvalidatedRect);
|
||||
invalidatedRegion.And(invalidatedRegion, mVisibleRect);
|
||||
mInvalidatedRect = invalidatedRegion.GetBounds();
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ThebesLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_THEBES;
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ThebesLayerD3D9::GetVisibleRect()
|
||||
{
|
||||
return mVisibleRect;
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::RenderLayer()
|
||||
{
|
||||
if (!mTexture) {
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
mInvalidatedRect = mVisibleRect;
|
||||
}
|
||||
if (!mInvalidatedRect.IsEmpty()) {
|
||||
nsIntRegion region = mInvalidatedRect;
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatARGB32;;
|
||||
nsRefPtr<gfxASurface> destinationSurface;
|
||||
nsRefPtr<gfxContext> context;
|
||||
|
||||
destinationSurface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(destinationSurface);
|
||||
context->Translate(gfxPoint(-mInvalidatedRect.x, -mInvalidatedRect.y));
|
||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||
cbInfo.Callback(this, context, region, cbInfo.CallbackData);
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> tmpTexture;
|
||||
device()->CreateTexture(mInvalidatedRect.width, mInvalidatedRect.height, 1,
|
||||
0, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), NULL);
|
||||
|
||||
D3DLOCKED_RECT r;
|
||||
tmpTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface =
|
||||
new gfxImageSurface((unsigned char *)r.pBits,
|
||||
gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
r.Pitch,
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(imgSurface);
|
||||
context->SetSource(destinationSurface);
|
||||
context->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
context->Paint();
|
||||
|
||||
imgSurface = NULL;
|
||||
|
||||
tmpTexture->UnlockRect(0);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> srcSurface;
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
tmpTexture->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
|
||||
|
||||
POINT point;
|
||||
point.x = mInvalidatedRect.x - mVisibleRect.x;
|
||||
point.y = mInvalidatedRect.y - mVisibleRect.y;
|
||||
device()->UpdateSurface(srcSurface, NULL, dstSurface, &point);
|
||||
}
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left.
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)GetVisibleRect().width;
|
||||
quadTransform[1][1] = (float)GetVisibleRect().height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)GetVisibleRect().x - 0.5f;
|
||||
quadTransform[3][1] = (float)GetVisibleRect().y - 0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::CleanResources()
|
||||
{
|
||||
mTexture = nsnull;
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ThebesLayerD3D9::GetInvalidatedRect()
|
||||
{
|
||||
return mInvalidatedRect;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ThebesLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ThebesLayerD3D9::IsEmpty()
|
||||
{
|
||||
return !mTexture;
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_THEBESLAYERD3D9_H
|
||||
#define GFX_THEBESLAYERD3D9_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D9.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ThebesLayerD3D9 : public ThebesLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ThebesLayerD3D9(LayerManagerD3D9 *aManager);
|
||||
virtual ~ThebesLayerD3D9();
|
||||
|
||||
/* Layer implementation */
|
||||
void SetVisibleRegion(const nsIntRegion& aRegion);
|
||||
|
||||
/* ThebesLayer implementation */
|
||||
void InvalidateRegion(const nsIntRegion& aRegion);
|
||||
|
||||
/* LayerD3D9 implementation */
|
||||
LayerType GetType();
|
||||
Layer* GetLayer();
|
||||
virtual PRBool IsEmpty();
|
||||
virtual void RenderLayer();
|
||||
virtual void CleanResources();
|
||||
|
||||
/* ThebesLayerD3D9 */
|
||||
const nsIntRect &GetVisibleRect();
|
||||
const nsIntRect &GetInvalidatedRect();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Visible rectangle, this is used to know the size and position of the quad
|
||||
* when doing the rendering of this layer.
|
||||
*/
|
||||
nsIntRect mVisibleRect;
|
||||
/*
|
||||
* Currently invalidated rectangular area.
|
||||
*/
|
||||
nsIntRect mInvalidatedRect;
|
||||
|
||||
/*
|
||||
* D3D9 texture
|
||||
*/
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_THEBESLAYERD3D9_H */
|
|
@ -198,7 +198,9 @@ CanvasLayerOGL::Updated(const nsIntRect& aRect)
|
|||
}
|
||||
|
||||
void
|
||||
CanvasLayerOGL::RenderLayer(int aPreviousDestination)
|
||||
CanvasLayerOGL::RenderLayer(int aPreviousDestination,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
LayerManagerOGL *glManager = static_cast<LayerManagerOGL*>(mManager);
|
||||
GLContext *gl = glManager->gl();
|
||||
|
|
|
@ -66,7 +66,9 @@ public:
|
|||
// LayerOGL implementation
|
||||
virtual LayerType GetType() { return TYPE_CANVAS; }
|
||||
virtual Layer* GetLayer() { return this; }
|
||||
virtual void RenderLayer(int aPreviousDestination);
|
||||
virtual void RenderLayer(int aPreviousDestination,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
|
|
|
@ -53,7 +53,7 @@ ColorLayerOGL::GetLayer()
|
|||
}
|
||||
|
||||
void
|
||||
ColorLayerOGL::RenderLayer(int)
|
||||
ColorLayerOGL::RenderLayer(int, DrawThebesLayerCallback, void*)
|
||||
{
|
||||
static_cast<LayerManagerOGL*>(mManager)->MakeCurrent();
|
||||
|
||||
|
|
|
@ -61,7 +61,9 @@ public:
|
|||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer(int aPreviousDestination);
|
||||
virtual void RenderLayer(int aPreviousDestination,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
protected:
|
||||
nsIntRegion mVisibleRegion;
|
||||
|
|
|
@ -47,6 +47,15 @@ ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *aManager)
|
|||
mImplData = static_cast<LayerOGL*>(this);
|
||||
}
|
||||
|
||||
ContainerLayerOGL::~ContainerLayerOGL()
|
||||
{
|
||||
LayerOGL *nextChild;
|
||||
for (LayerOGL *child = GetFirstChildOGL(); child; child = nextChild) {
|
||||
nextChild = child->GetNextSibling();
|
||||
child->GetLayer()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ContainerLayerOGL::GetVisibleRect()
|
||||
{
|
||||
|
@ -65,6 +74,7 @@ ContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter)
|
|||
LayerOGL *newChild = static_cast<LayerOGL*>(aChild->ImplData());
|
||||
aChild->SetParent(this);
|
||||
if (!aAfter) {
|
||||
NS_ADDREF(aChild);
|
||||
LayerOGL *oldFirstChild = GetFirstChildOGL();
|
||||
mFirstChild = newChild->GetLayer();
|
||||
newChild->SetNextSibling(oldFirstChild);
|
||||
|
@ -73,6 +83,7 @@ ContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter)
|
|||
for (LayerOGL *child = GetFirstChildOGL();
|
||||
child; child = child->GetNextSibling()) {
|
||||
if (aAfter == child->GetLayer()) {
|
||||
NS_ADDREF(aChild);
|
||||
LayerOGL *oldNextSibling = child->GetNextSibling();
|
||||
child->SetNextSibling(newChild);
|
||||
child->GetNextSibling()->SetNextSibling(oldNextSibling);
|
||||
|
@ -87,6 +98,7 @@ ContainerLayerOGL::RemoveChild(Layer *aChild)
|
|||
{
|
||||
if (GetFirstChild() == aChild) {
|
||||
mFirstChild = GetFirstChildOGL()->GetNextSibling()->GetLayer();
|
||||
NS_RELEASE(aChild);
|
||||
return;
|
||||
}
|
||||
LayerOGL *lastChild = NULL;
|
||||
|
@ -97,6 +109,7 @@ ContainerLayerOGL::RemoveChild(Layer *aChild)
|
|||
lastChild->SetNextSibling(child->GetNextSibling());
|
||||
child->SetNextSibling(NULL);
|
||||
child->GetLayer()->SetParent(NULL);
|
||||
NS_RELEASE(aChild);
|
||||
return;
|
||||
}
|
||||
lastChild = child;
|
||||
|
@ -125,7 +138,9 @@ ContainerLayerOGL::GetFirstChildOGL()
|
|||
}
|
||||
|
||||
void
|
||||
ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
|
||||
ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
/**
|
||||
* Setup our temporary texture for rendering the contents of this container.
|
||||
|
@ -139,7 +154,8 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
|
|||
YCbCrLayerProgram *yCbCrProgram =
|
||||
static_cast<LayerManagerOGL*>(mManager)->GetYCbCrLayerProgram();
|
||||
|
||||
if (GetOpacity() != 1.0) {
|
||||
float opacity = GetOpacity();
|
||||
if (opacity != 1.0) {
|
||||
gl()->fGenTextures(1, &containerSurface);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, containerSurface);
|
||||
gl()->fTexImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
|
@ -202,11 +218,11 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
|
|||
gl()->fScissor(0, 0, GetVisibleRect().width, GetVisibleRect().height);
|
||||
}
|
||||
|
||||
layerToRender->RenderLayer(frameBuffer);
|
||||
layerToRender->RenderLayer(frameBuffer, aCallback, aCallbackData);
|
||||
layerToRender = layerToRender->GetNextSibling();
|
||||
}
|
||||
|
||||
if (GetOpacity() != 1.0) {
|
||||
if (opacity != 1.0) {
|
||||
// Unbind the current framebuffer and rebind the previous one.
|
||||
gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
|
||||
gl()->fDeleteFramebuffers(1, &frameBuffer);
|
||||
|
@ -241,7 +257,7 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
|
|||
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, containerSurface);
|
||||
|
||||
rgbProgram->SetLayerOpacity(GetOpacity());
|
||||
rgbProgram->SetLayerOpacity(opacity);
|
||||
rgbProgram->SetLayerTransform(&mTransform._11);
|
||||
rgbProgram->Apply();
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ class ContainerLayerOGL : public ContainerLayer,
|
|||
{
|
||||
public:
|
||||
ContainerLayerOGL(LayerManagerOGL *aManager);
|
||||
~ContainerLayerOGL();
|
||||
|
||||
const nsIntRect &GetVisibleRect();
|
||||
|
||||
|
@ -68,7 +69,9 @@ public:
|
|||
|
||||
PRBool IsEmpty();
|
||||
|
||||
void RenderLayer(int aPreviousFrameBuffer);
|
||||
void RenderLayer(int aPreviousFrameBuffer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
private:
|
||||
nsIntRect mVisibleRect;
|
||||
|
||||
|
|
|
@ -269,7 +269,8 @@ ImageLayerOGL::GetLayer()
|
|||
}
|
||||
|
||||
void
|
||||
ImageLayerOGL::RenderLayer(int)
|
||||
ImageLayerOGL::RenderLayer(int, DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
if (!GetContainer()) {
|
||||
return;
|
||||
|
|
|
@ -175,7 +175,9 @@ public:
|
|||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer(int aPreviousDestination);
|
||||
virtual void RenderLayer(int aPreviousDestination,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
};
|
||||
|
||||
class THEBES_API PlanarYCbCrImageOGL : public PlanarYCbCrImage
|
||||
|
|
|
@ -282,14 +282,10 @@ LayerManagerOGL::BeginTransactionWithTarget(gfxContext *aTarget)
|
|||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::EndConstruction()
|
||||
LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::EndTransaction()
|
||||
{
|
||||
Render();
|
||||
Render(aCallback, aCallbackData);
|
||||
mTarget = NULL;
|
||||
}
|
||||
|
||||
|
@ -358,7 +354,8 @@ LayerManagerOGL::MakeCurrent()
|
|||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::Render()
|
||||
LayerManagerOGL::Render(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
|
@ -384,7 +381,7 @@ LayerManagerOGL::Render()
|
|||
mGLContext->fScissor(0, 0, width, height);
|
||||
}
|
||||
|
||||
mRootLayer->RenderLayer(mFrameBuffer);
|
||||
mRootLayer->RenderLayer(mFrameBuffer, aCallback, aCallbackData);
|
||||
}
|
||||
|
||||
if (mTarget) {
|
||||
|
|
|
@ -216,7 +216,8 @@ public:
|
|||
|
||||
void EndConstruction();
|
||||
|
||||
void EndTransaction();
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
void SetRoot(Layer* aLayer);
|
||||
|
||||
|
@ -293,7 +294,8 @@ private:
|
|||
/**
|
||||
* Render the current layer tree to the active target.
|
||||
*/
|
||||
void Render();
|
||||
void Render(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
/**
|
||||
* Setup the pipeline.
|
||||
*/
|
||||
|
@ -316,6 +318,8 @@ private:
|
|||
class LayerOGL
|
||||
{
|
||||
public:
|
||||
typedef LayerManager::DrawThebesLayerCallback DrawThebesLayerCallback;
|
||||
|
||||
LayerOGL(LayerManagerOGL *aManager);
|
||||
|
||||
enum LayerType {
|
||||
|
@ -336,7 +340,8 @@ public:
|
|||
|
||||
virtual Layer* GetLayer() = 0;
|
||||
|
||||
virtual void RenderLayer(int aPreviousFrameBuffer) = 0;
|
||||
virtual void RenderLayer(int aPreviousFrameBuffer, DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) = 0;
|
||||
|
||||
typedef mozilla::gl::GLContext GLContext;
|
||||
|
||||
|
|
|
@ -128,96 +128,6 @@ ThebesLayerOGL::InvalidateRegion(const nsIntRegion &aRegion)
|
|||
mInvalidatedRect = invalidatedRegion.GetBounds();
|
||||
}
|
||||
|
||||
gfxContext *
|
||||
ThebesLayerOGL::BeginDrawing(nsIntRegion *aRegion)
|
||||
{
|
||||
if (mInvalidatedRect.IsEmpty()) {
|
||||
aRegion->SetEmpty();
|
||||
return NULL;
|
||||
}
|
||||
if (!mTexture) {
|
||||
aRegion->SetEmpty();
|
||||
return NULL;
|
||||
}
|
||||
*aRegion = mInvalidatedRect;
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat;
|
||||
|
||||
if (UseOpaqueSurface(this)) {
|
||||
imageFormat = gfxASurface::ImageFormatRGB24;
|
||||
} else {
|
||||
imageFormat = gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
mDestinationSurface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
|
||||
mContext = new gfxContext(mDestinationSurface);
|
||||
mContext->Translate(gfxPoint(-mInvalidatedRect.x, -mInvalidatedRect.y));
|
||||
return mContext.get();
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerOGL::EndDrawing()
|
||||
{
|
||||
static_cast<LayerManagerOGL*>(mManager)->MakeCurrent();
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface;
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat;
|
||||
|
||||
if (UseOpaqueSurface(this)) {
|
||||
imageFormat = gfxASurface::ImageFormatRGB24;
|
||||
} else {
|
||||
imageFormat = gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
switch (mDestinationSurface->GetType()) {
|
||||
case gfxASurface::SurfaceTypeImage:
|
||||
imageSurface = static_cast<gfxImageSurface*>(mDestinationSurface.get());
|
||||
break;
|
||||
#ifdef XP_WIN
|
||||
case gfxASurface::SurfaceTypeWin32:
|
||||
imageSurface =
|
||||
static_cast<gfxWindowsSurface*>(mDestinationSurface.get())->
|
||||
GetImageSurface();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/**
|
||||
* XXX - This is very undesirable. Implement this for other platforms in
|
||||
* a more efficient way as well!
|
||||
*/
|
||||
{
|
||||
imageSurface = new gfxImageSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
nsRefPtr<gfxContext> tmpContext = new gfxContext(imageSurface);
|
||||
tmpContext->SetSource(mDestinationSurface);
|
||||
tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpContext->Paint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||
gl()->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
0,
|
||||
mInvalidatedRect.x - mVisibleRect.x,
|
||||
mInvalidatedRect.y - mVisibleRect.y,
|
||||
mInvalidatedRect.width,
|
||||
mInvalidatedRect.height,
|
||||
LOCAL_GL_BGRA,
|
||||
LOCAL_GL_UNSIGNED_BYTE,
|
||||
imageSurface->Data());
|
||||
|
||||
mDestinationSurface = NULL;
|
||||
mContext = NULL;
|
||||
}
|
||||
|
||||
LayerOGL::LayerType
|
||||
ThebesLayerOGL::GetType()
|
||||
{
|
||||
|
@ -231,12 +141,77 @@ ThebesLayerOGL::GetVisibleRect()
|
|||
}
|
||||
|
||||
void
|
||||
ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer)
|
||||
ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
if (!mTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mInvalidatedRect.IsEmpty()) {
|
||||
gfxASurface::gfxImageFormat imageFormat;
|
||||
|
||||
if (UseOpaqueSurface(this)) {
|
||||
imageFormat = gfxASurface::ImageFormatRGB24;
|
||||
} else {
|
||||
imageFormat = gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surface);
|
||||
ctx->Translate(gfxPoint(-mInvalidatedRect.x, -mInvalidatedRect.y));
|
||||
aCallback(this, ctx, mInvalidatedRect, aCallbackData);
|
||||
|
||||
static_cast<LayerManagerOGL*>(mManager)->MakeCurrent();
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface;
|
||||
|
||||
switch (surface->GetType()) {
|
||||
case gfxASurface::SurfaceTypeImage:
|
||||
imageSurface = static_cast<gfxImageSurface*>(surface.get());
|
||||
break;
|
||||
#ifdef XP_WIN
|
||||
case gfxASurface::SurfaceTypeWin32:
|
||||
imageSurface =
|
||||
static_cast<gfxWindowsSurface*>(surface.get())->
|
||||
GetImageSurface();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/**
|
||||
* XXX - This is very undesirable. Implement this for other platforms in
|
||||
* a more efficient way as well!
|
||||
*/
|
||||
{
|
||||
imageSurface = new gfxImageSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
nsRefPtr<gfxContext> tmpContext = new gfxContext(imageSurface);
|
||||
tmpContext->SetSource(surface);
|
||||
tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpContext->Paint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||
gl()->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
0,
|
||||
mInvalidatedRect.x - mVisibleRect.x,
|
||||
mInvalidatedRect.y - mVisibleRect.y,
|
||||
mInvalidatedRect.width,
|
||||
mInvalidatedRect.height,
|
||||
LOCAL_GL_BGRA,
|
||||
LOCAL_GL_UNSIGNED_BYTE,
|
||||
imageSurface->Data());
|
||||
}
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
|
|
|
@ -59,15 +59,13 @@ public:
|
|||
/** ThebesLayer implementation */
|
||||
void InvalidateRegion(const nsIntRegion& aRegion);
|
||||
|
||||
gfxContext *BeginDrawing(nsIntRegion* aRegionToDraw);
|
||||
|
||||
void EndDrawing();
|
||||
|
||||
/** LayerOGL implementation */
|
||||
LayerType GetType();
|
||||
Layer* GetLayer();
|
||||
virtual PRBool IsEmpty();
|
||||
virtual void RenderLayer(int aPreviousFrameBuffer);
|
||||
virtual void RenderLayer(int aPreviousFrameBuffer,
|
||||
DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
/** ThebesLayerOGL */
|
||||
const nsIntRect &GetVisibleRect();
|
||||
|
@ -83,16 +81,6 @@ private:
|
|||
* Currently invalidated rectangular area.
|
||||
*/
|
||||
nsIntRect mInvalidatedRect;
|
||||
/**
|
||||
* Destination surface used for this layer's drawing operation. This is
|
||||
* created on BeginDrawing() and should be removed on EndDrawing().
|
||||
*/
|
||||
nsRefPtr<gfxASurface> mDestinationSurface;
|
||||
|
||||
/**
|
||||
* We hold the reference to the context.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mContext;
|
||||
|
||||
/**
|
||||
* OpenGL Texture
|
||||
|
|
|
@ -179,6 +179,7 @@ public:
|
|||
PRUint32 GetNumRects () const { return mRectCount; }
|
||||
const nsRect& GetBounds () const { return mBoundRect; }
|
||||
nsIntRegion ToOutsidePixels (nscoord aAppUnitsPerPixel) const;
|
||||
nsRect GetLargestRectangle () const;
|
||||
|
||||
/**
|
||||
* Make sure the region has at most aMaxRects by adding area to it
|
||||
|
@ -409,6 +410,7 @@ public:
|
|||
}
|
||||
PRUint32 GetNumRects () const { return mImpl.GetNumRects (); }
|
||||
nsIntRect GetBounds () const { return FromRect (mImpl.GetBounds ()); }
|
||||
nsIntRect GetLargestRectangle () const { return FromRect (mImpl.GetLargestRectangle()); }
|
||||
|
||||
/**
|
||||
* Make sure the region has at most aMaxRects by adding area to it
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "prlock.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
/*
|
||||
* The SENTINEL values below guaranties that a < or >
|
||||
|
@ -1299,6 +1300,252 @@ nsIntRegion nsRegion::ToOutsidePixels(nscoord aAppUnitsPerPixel) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
// This algorithm works in three phases:
|
||||
// 1) Convert the region into a grid by adding vertical/horizontal lines for
|
||||
// each edge of each rectangle in the region.
|
||||
// 2) For each rectangle in the region, for each cell it contains, set that
|
||||
// cells's value to the area of the subrectangle it corresponds to. Cells
|
||||
// that are not contained by any rectangle have the value 0.
|
||||
// 3) Calculate the submatrix with the largest sum such that none of its cells
|
||||
// contain any 0s (empty regions). The rectangle represented by the
|
||||
// submatrix is the largest rectangle in the region.
|
||||
//
|
||||
// Let k be the number of rectangles in the region.
|
||||
// Let m be the height of the grid generated in step 1.
|
||||
// Let n be the width of the grid generated in step 1.
|
||||
//
|
||||
// Step 1 is O(k) in time and O(m+n) in space for the sparse grid.
|
||||
// Step 2 is O(mn) in time and O(mn) in additional space for the full grid.
|
||||
// Step 3 is O(m^2 n) in time and O(mn) in additional space
|
||||
//
|
||||
// The implementation of steps 1 and 2 are rather straightforward. However our
|
||||
// implementation of step 3 uses dynamic programming to achieve its efficiency.
|
||||
//
|
||||
// Psuedo code for step 3 is as follows where G is the grid from step 1 and A
|
||||
// is the array from step 2:
|
||||
// Phase3 = function (G, A, m, n) {
|
||||
// let (t,b,l,r,_) = MaxSum2D(A,m,n)
|
||||
// return rect(G[t],G[l],G[r],G[b]);
|
||||
// }
|
||||
// MaxSum2D = function (A, m, n) {
|
||||
// S = array(m+1,n+1)
|
||||
// S[0][i] = 0 for i in [0,n]
|
||||
// S[j][0] = 0 for j in [0,m]
|
||||
// S[j][i] = (if A[j-1][i-1] = 0 then some large negative number else A[j-1][i-1])
|
||||
// + S[j-1][n] + S[j][i-1] - S[j-1][i-1]
|
||||
//
|
||||
// // top, bottom, left, right, area
|
||||
// var maxRect = (-1, -1, -1, -1, 0);
|
||||
//
|
||||
// for all (m',m'') in [0, m]^2 {
|
||||
// let B = { S[m'][i] - S[m''][i] | 0 <= i <= n }
|
||||
// let ((l,r),area) = MaxSum1D(B,n+1)
|
||||
// if (area > maxRect.area) {
|
||||
// maxRect := (m', m'', l, r, area)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return maxRect;
|
||||
// }
|
||||
//
|
||||
// Originally taken from Improved algorithms for the k-maximum subarray problem
|
||||
// for small k - SE Bae, T Takaoka but modified to show the explicit tracking
|
||||
// of indices and we already have the prefix sums from our one call site so
|
||||
// there's no need to construct them.
|
||||
// MaxSum1D = function (A,n) {
|
||||
// var minIdx = 0;
|
||||
// var min = 0;
|
||||
// var maxIndices = (0,0);
|
||||
// var max = 0;
|
||||
// for i in range(n) {
|
||||
// let cand = A[i] - min;
|
||||
// if (cand > max) {
|
||||
// max := cand;
|
||||
// maxIndices := (minIdx, i)
|
||||
// }
|
||||
// if (min > A[i]) {
|
||||
// min := A[i];
|
||||
// minIdx := i;
|
||||
// }
|
||||
// }
|
||||
// return (minIdx, maxIdx, max);
|
||||
// }
|
||||
|
||||
namespace {
|
||||
// This class represents a partitioning of an axis delineated by coordinates.
|
||||
// It internally maintains a sorted array of coordinates.
|
||||
class AxisPartition {
|
||||
public:
|
||||
// Adds a new partition at the given coordinate to this partitioning. If
|
||||
// the coordinate is already present in the partitioning, this does nothing.
|
||||
void InsertCoord(nscoord c) {
|
||||
PRUint32 i;
|
||||
if (!mStops.GreatestIndexLtEq(c, i)) {
|
||||
mStops.InsertElementAt(i, c);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the array index of the given partition point. The partition
|
||||
// point must already be present in the partitioning.
|
||||
PRInt32 IndexOf(nscoord p) const {
|
||||
return mStops.BinaryIndexOf(p);
|
||||
}
|
||||
|
||||
// Returns the partition at the given index which must be non-zero and
|
||||
// less than the number of partitions in this partitioning.
|
||||
nscoord StopAt(PRInt32 index) const {
|
||||
return mStops[index];
|
||||
}
|
||||
|
||||
// Returns the size of the gap between the partition at the given index and
|
||||
// the next partition in this partitioning. If the index is the last index
|
||||
// in the partitioning, the result is undefined.
|
||||
nscoord StopSize(PRInt32 index) const {
|
||||
return mStops[index+1] - mStops[index];
|
||||
}
|
||||
|
||||
// Returns the number of partitions in this partitioning.
|
||||
PRInt32 GetNumStops() const { return mStops.Length(); }
|
||||
|
||||
private:
|
||||
nsTArray<nscoord> mStops;
|
||||
};
|
||||
|
||||
const PRInt64 kVeryLargeNegativeNumber = 0xffff000000000000ll;
|
||||
|
||||
// Returns the sum and indices of the subarray with the maximum sum of the
|
||||
// given array (A,n), assuming the array is already in prefix sum form.
|
||||
PRInt64 MaxSum1D(const nsTArray<PRInt64> &A, PRInt32 n,
|
||||
PRInt32 *minIdx, PRInt32 *maxIdx) {
|
||||
// The min/max indicies of the largest subarray found so far
|
||||
PRInt64 min = 0,
|
||||
max = 0;
|
||||
PRInt32 currentMinIdx = 0;
|
||||
|
||||
*minIdx = 0;
|
||||
*maxIdx = 0;
|
||||
|
||||
// Because we're given the array in prefix sum form, we know the first
|
||||
// element is 0
|
||||
for(PRInt32 i = 1; i < n; i++) {
|
||||
PRInt64 cand = A[i] - min;
|
||||
if (cand > max) {
|
||||
max = cand;
|
||||
*minIdx = currentMinIdx;
|
||||
*maxIdx = i;
|
||||
}
|
||||
if (min > A[i]) {
|
||||
min = A[i];
|
||||
currentMinIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
nsRect nsRegion::GetLargestRectangle () const {
|
||||
nsRect bestRect;
|
||||
|
||||
if (!mRectCount)
|
||||
return bestRect;
|
||||
|
||||
AxisPartition xaxis, yaxis;
|
||||
|
||||
// Step 1: Calculate the grid lines
|
||||
nsRegionRectIterator iter(*this);
|
||||
const nsRect *currentRect;
|
||||
while ((currentRect = iter.Next())) {
|
||||
xaxis.InsertCoord(currentRect->x);
|
||||
xaxis.InsertCoord(currentRect->XMost());
|
||||
yaxis.InsertCoord(currentRect->y);
|
||||
yaxis.InsertCoord(currentRect->YMost());
|
||||
}
|
||||
|
||||
// Step 2: Fill out the grid with the areas
|
||||
// Note: due to the ordering of rectangles in the region, it is not always
|
||||
// possible to combine steps 2 and 3 so we don't try to be clever.
|
||||
PRInt32 matrixHeight = yaxis.GetNumStops() - 1;
|
||||
PRInt32 matrixWidth = xaxis.GetNumStops() - 1;
|
||||
PRInt32 matrixSize = matrixHeight * matrixWidth;
|
||||
nsTArray<PRInt64> areas(matrixSize);
|
||||
areas.SetLength(matrixSize);
|
||||
memset(areas.Elements(), 0, matrixSize * sizeof(PRInt64));
|
||||
|
||||
iter.Reset();
|
||||
while ((currentRect = iter.Next())) {
|
||||
PRInt32 xstart = xaxis.IndexOf(currentRect->x);
|
||||
PRInt32 xend = xaxis.IndexOf(currentRect->XMost());
|
||||
PRInt32 y = yaxis.IndexOf(currentRect->y);
|
||||
PRInt32 yend = yaxis.IndexOf(currentRect->YMost());
|
||||
|
||||
for (; y < yend; y++) {
|
||||
nscoord height = yaxis.StopSize(y);
|
||||
for (PRInt32 x = xstart; x < xend; x++) {
|
||||
nscoord width = xaxis.StopSize(x);
|
||||
areas[y*matrixWidth+x] = width*PRInt64(height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Find the maximum submatrix sum that does not contain a rectangle
|
||||
{
|
||||
// First get the prefix sum array
|
||||
PRInt32 m = matrixHeight + 1;
|
||||
PRInt32 n = matrixWidth + 1;
|
||||
nsTArray<PRInt64> pareas(m*n);
|
||||
pareas.SetLength(m*n);
|
||||
// Zero out the first row
|
||||
for (PRInt32 x = 0; x < n; x++)
|
||||
pareas[x] = 0;
|
||||
for (PRInt32 y = 1; y < m; y++) {
|
||||
// Zero out the left column
|
||||
pareas[y*n] = 0;
|
||||
for (PRInt32 x = 1; x < n; x++) {
|
||||
PRInt64 area = areas[(y-1)*matrixWidth+x-1];
|
||||
if (!area)
|
||||
area = kVeryLargeNegativeNumber;
|
||||
area += pareas[ y*n+x-1]
|
||||
+ pareas[(y-1)*n+x ]
|
||||
- pareas[(y-1)*n+x-1];
|
||||
pareas[y*n+x] = area;
|
||||
}
|
||||
}
|
||||
|
||||
// No longer need the grid
|
||||
areas.SetLength(0);
|
||||
|
||||
PRInt64 bestArea = 0;
|
||||
struct {
|
||||
PRInt32 left, top, right, bottom;
|
||||
} bestRectIndices = { 0, 0, 0, 0 };
|
||||
for (PRInt32 m1 = 0; m1 < m; m1++) {
|
||||
for (PRInt32 m2 = m1+1; m2 < m; m2++) {
|
||||
nsTArray<PRInt64> B;
|
||||
B.SetLength(n);
|
||||
for (PRInt32 i = 0; i < n; i++)
|
||||
B[i] = pareas[m2*n+i] - pareas[m1*n+i];
|
||||
PRInt32 minIdx, maxIdx;
|
||||
PRInt64 area = MaxSum1D(B, n, &minIdx, &maxIdx);
|
||||
if (area > bestArea) {
|
||||
bestRectIndices.left = minIdx;
|
||||
bestRectIndices.top = m1;
|
||||
bestRectIndices.right = maxIdx;
|
||||
bestRectIndices.bottom = m2;
|
||||
bestArea = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bestRect.MoveTo(xaxis.StopAt(bestRectIndices.left),
|
||||
yaxis.StopAt(bestRectIndices.top));
|
||||
bestRect.SizeTo(xaxis.StopAt(bestRectIndices.right) - bestRect.x,
|
||||
yaxis.StopAt(bestRectIndices.bottom) - bestRect.y);
|
||||
}
|
||||
|
||||
return bestRect;
|
||||
}
|
||||
|
||||
void nsRegion::SimplifyOutward (PRUint32 aMaxRects)
|
||||
{
|
||||
NS_ASSERTION(aMaxRects >= 1, "Invalid max rect count");
|
||||
|
|
|
@ -50,6 +50,7 @@ MOZILLA_INTERNAL_API = 1
|
|||
CPP_UNIT_TESTS = \
|
||||
TestColorNames.cpp \
|
||||
TestRect.cpp \
|
||||
TestRegion.cpp \
|
||||
$(NULL)
|
||||
|
||||
LIBS = \
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Rob Arnold <robarnold@cs.cmu.edu>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "TestHarness.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
class TestLargestRegion {
|
||||
static PRBool TestSingleRect(nsRect r) {
|
||||
nsRegion region(r);
|
||||
if (region.GetLargestRectangle() != r) {
|
||||
fail("largest rect of singleton %d %d %d %d", r.x, r.y, r.width, r.height);
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
// Construct a rectangle, remove part of it, then check the remainder
|
||||
static PRBool TestNonRectangular() {
|
||||
nsRegion r(nsRect(0, 0, 30, 30));
|
||||
|
||||
const int nTests = 19;
|
||||
struct {
|
||||
nsRect rect;
|
||||
PRInt64 expectedArea;
|
||||
} tests[nTests] = {
|
||||
// Remove a 20x10 chunk from the square
|
||||
{ nsRect(0, 0, 20, 10), 600 },
|
||||
{ nsRect(10, 0, 20, 10), 600 },
|
||||
{ nsRect(10, 20, 20, 10), 600 },
|
||||
{ nsRect(0, 20, 20, 10), 600 },
|
||||
// Remove a 10x20 chunk from the square
|
||||
{ nsRect(0, 0, 10, 20), 600 },
|
||||
{ nsRect(20, 0, 10, 20), 600 },
|
||||
{ nsRect(20, 10, 10, 20), 600 },
|
||||
{ nsRect(0, 10, 10, 20), 600 },
|
||||
// Remove the center 10x10
|
||||
{ nsRect(10, 10, 10, 10), 300 },
|
||||
// Remove the middle column
|
||||
{ nsRect(10, 0, 10, 30), 300 },
|
||||
// Remove the middle row
|
||||
{ nsRect(0, 10, 30, 10), 300 },
|
||||
// Remove the corners 10x10
|
||||
{ nsRect(0, 0, 10, 10), 600 },
|
||||
{ nsRect(20, 20, 10, 10), 600 },
|
||||
{ nsRect(20, 0, 10, 10), 600 },
|
||||
{ nsRect(0, 20, 10, 10), 600 },
|
||||
// Remove the corners 20x20
|
||||
{ nsRect(0, 0, 20, 20), 300 },
|
||||
{ nsRect(10, 10, 20, 20), 300 },
|
||||
{ nsRect(10, 0, 20, 20), 300 },
|
||||
{ nsRect(0, 10, 20, 20), 300 }
|
||||
};
|
||||
|
||||
PRBool success = PR_TRUE;
|
||||
for (PRInt32 i = 0; i < nTests; i++) {
|
||||
nsRegion r2;
|
||||
r2.Sub(r, tests[i].rect);
|
||||
|
||||
if (!r2.IsComplex())
|
||||
fail("nsRegion code got unexpectedly smarter!");
|
||||
|
||||
nsRect largest = r2.GetLargestRectangle();
|
||||
if (largest.width * largest.height != tests[i].expectedArea) {
|
||||
fail("Did not succesfully find largest rectangle in non-rectangular region on iteration %d", i);
|
||||
success = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
static PRBool TwoRectTest() {
|
||||
nsRegion r(nsRect(0, 0, 100, 100));
|
||||
const int nTests = 4;
|
||||
struct {
|
||||
nsRect rect1, rect2;
|
||||
PRInt64 expectedArea;
|
||||
} tests[nTests] = {
|
||||
{ nsRect(0, 0, 75, 40), nsRect(0, 60, 75, 40), 2500 },
|
||||
{ nsRect(25, 0, 75, 40), nsRect(25, 60, 75, 40), 2500 },
|
||||
{ nsRect(25, 0, 75, 40), nsRect(0, 60, 75, 40), 2000 },
|
||||
{ nsRect(0, 0, 75, 40), nsRect(25, 60, 75, 40), 2000 },
|
||||
};
|
||||
PRBool success = PR_TRUE;
|
||||
for (PRInt32 i = 0; i < nTests; i++) {
|
||||
nsRegion r2;
|
||||
|
||||
r2.Sub(r, tests[i].rect1);
|
||||
r2.Sub(r2, tests[i].rect2);
|
||||
|
||||
if (!r2.IsComplex())
|
||||
fail("nsRegion code got unexpectedly smarter!");
|
||||
|
||||
nsRect largest = r2.GetLargestRectangle();
|
||||
if (largest.width * largest.height != tests[i].expectedArea) {
|
||||
fail("Did not succesfully find largest rectangle in two-rect-subtract region on iteration %d", i);
|
||||
success = PR_FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
public:
|
||||
static PRBool Test() {
|
||||
if (!TestSingleRect(nsRect(0, 52, 720, 480)) ||
|
||||
!TestSingleRect(nsRect(-20, 40, 50, 20)) ||
|
||||
!TestSingleRect(nsRect(-20, 40, 10, 8)) ||
|
||||
!TestSingleRect(nsRect(-20, -40, 10, 8)) ||
|
||||
!TestSingleRect(nsRect(-10, -10, 20, 20)))
|
||||
return PR_FALSE;
|
||||
if (!TestNonRectangular())
|
||||
return PR_FALSE;
|
||||
if (!TwoRectTest())
|
||||
return PR_FALSE;
|
||||
passed("TestLargestRegion");
|
||||
return PR_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
ScopedXPCOM xpcom("TestRegion");
|
||||
if (xpcom.failed())
|
||||
return -1;
|
||||
if (NS_FAILED(nsRegion::InitStatic())) {
|
||||
fail("Could not initialize region statics");
|
||||
return -1;
|
||||
}
|
||||
if (!TestLargestRegion::Test())
|
||||
return -1;
|
||||
nsRegion::ShutdownStatic();
|
||||
return 0;
|
||||
}
|
|
@ -62,7 +62,7 @@ public:
|
|||
};
|
||||
|
||||
ContextFormat(const StandardContextFormat cf) {
|
||||
memset(this, sizeof(ContextFormat), 0);
|
||||
memset(this, 0, sizeof(ContextFormat));
|
||||
|
||||
switch (cf) {
|
||||
case BasicRGBA32:
|
||||
|
|
|
@ -195,6 +195,10 @@ public:
|
|||
|
||||
if (!MakeCurrent()) return PR_FALSE;
|
||||
if (!SetupLookupFunction()) return PR_FALSE;
|
||||
|
||||
// OSMesa's different from the other GL providers, it renders to an image surface, not to a pbuffer
|
||||
sOSMesaLibrary.fPixelStore(OSMESA_Y_UP, 0);
|
||||
|
||||
return InitWithPrefix("gl", PR_TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ sub read_input
|
|||
my ($u, $comment) = split /\s+/, $1, 2;
|
||||
$u =~ s/,//g;
|
||||
$u =~ tr/A-Z/a-z/;
|
||||
next if /^0x.*[^0-9a-f]+.*/;
|
||||
next if $u =~ /^0x.*[^0-9a-f]+.*/;
|
||||
|
||||
my $usv = oct $u;
|
||||
if ( 0xd800 <= $usv && $usv <= 0xdfff || # surrogate code points
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
open $f, 'UnicodeData-Latest.txt' or die $!;
|
||||
while (<$f>) {
|
||||
@columns = split(/;/);
|
||||
# print "$columns[0] : $columns[1]\n";
|
||||
$names{hex($columns[0])} = $columns[1];
|
||||
}
|
||||
close $f;
|
||||
|
||||
open $f, 'DerivedCoreProperties.txt' or die $!;
|
||||
$re = '[';
|
||||
while (<$f>) {
|
||||
next unless /Default_Ignorable_Code_Point/;
|
||||
next unless /^([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))?/;
|
||||
|
||||
($start, $end) = (hex($1), hex($2));
|
||||
$end = $start unless $end;
|
||||
|
||||
for ($c = $start; $c <= $end; $c++) {
|
||||
printf "0x%04X", $c;
|
||||
printf " // $names{$c}" if $names{$c};
|
||||
print "\n";
|
||||
}
|
||||
|
||||
if (!$prevend || $start > $prevend + 1) {
|
||||
$re .= make_unicode_range($prevstart, $prevend) if $prevstart;
|
||||
$prevstart = $start;
|
||||
}
|
||||
$prevend = $end;
|
||||
}
|
||||
$re .= make_unicode_range($prevstart, $prevend).']';
|
||||
print STDERR $re;
|
||||
close $f;
|
||||
|
||||
sub make_unicode_range
|
||||
{
|
||||
my ($start, $end) = @_;
|
||||
|
||||
if ($start > 0xffff) {
|
||||
my $starths = ($start - 0x10000) >> 10 | 0xd800;
|
||||
my $startls = ($start - 0x10000) & 0x3ff | 0xdc00;
|
||||
my $endhs = ($end - 0x10000) >> 10 | 0xd800;
|
||||
my $endls = ($end - 0x10000) & 0x3ff | 0xdc00;
|
||||
if ($starths == $endhs) {
|
||||
return sprintf("]|\\u%04x[\\u%04x-\\u%04x", $starths, $startls, $endls)
|
||||
}
|
||||
my $re = '';
|
||||
if ($startls > 0xdc00) {
|
||||
$re .= sprintf("]|\\u%04x[\\u%04x-\\udfff", $starths, $startls);
|
||||
$starths++;
|
||||
}
|
||||
if ($endhs > $starths) {
|
||||
$endhs-- if ($endls < 0xdfff);
|
||||
$re .= sprintf("]|[\\u%04x-\\u%04x][\\udc00-\\udfff", $starths, $endhs);
|
||||
}
|
||||
if ($endls < 0xdfff) {
|
||||
$re .= sprintf("]|\\u%04x[\\udc00-\\u%04x", $endhs, $endls);
|
||||
}
|
||||
return $re;
|
||||
} elsif ($start == $end) {
|
||||
return sprintf("\\u%04x", $start);
|
||||
} else {
|
||||
return sprintf("\\u%04x-\\u%04x", $start, $end);
|
||||
}
|
||||
}
|
|
@ -74,12 +74,6 @@ vpath %.mm \
|
|||
$(srcdir)/src/chrome/common \
|
||||
$(NULL)
|
||||
|
||||
# TODO: remove this hack when we switch to GCC 4.3! GCC 4.1
|
||||
# instantiates template declarations in wrapped system headers with
|
||||
# the wrong visibility, which is causing the Linux tinderboxen to die in
|
||||
# std::string internals.
|
||||
VISIBILITY_FLAGS=
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
||||
|
|
|
@ -1518,7 +1518,7 @@ normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
|
|||
else
|
||||
# assume MSYS
|
||||
# We use 'pwd -W' to get DOS form of the path. However, since the given path
|
||||
# could be a file or a non-existent path, we cannot call 'pwd -W' directly
|
||||
# could be a file or a nonexistent path, we cannot call 'pwd -W' directly
|
||||
# on the path. Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
|
||||
# on it, then merge with the rest of the path.
|
||||
root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
|
||||
|
|
|
@ -212,6 +212,7 @@ dbus/dbus-glib.h
|
|||
dbus/dbus-glib-lowlevel.h
|
||||
ddeml.h
|
||||
Debug.h
|
||||
deque
|
||||
dem.h
|
||||
descrip.h
|
||||
Devices.h
|
||||
|
@ -274,6 +275,7 @@ freetype/tttables.h
|
|||
freetype/t1tables.h
|
||||
fribidi/fribidi.h
|
||||
FSp_fopen.h
|
||||
fstream
|
||||
fstream.h
|
||||
ft2build.h
|
||||
fts.h
|
||||
|
@ -329,6 +331,7 @@ IOKit/pwr_mgt/IOPMLib.h
|
|||
iomanip
|
||||
iostream
|
||||
iostream.h
|
||||
iterator
|
||||
jar.h
|
||||
JavaControl.h
|
||||
JavaEmbedding/JavaControl.h
|
||||
|
@ -607,6 +610,7 @@ pthread.h
|
|||
pwd.h
|
||||
Python.h
|
||||
QDOffscreen.h
|
||||
queue
|
||||
Quickdraw.h
|
||||
QuickDraw.h
|
||||
QuickTimeComponents.h
|
||||
|
@ -641,6 +645,7 @@ security.h
|
|||
secutil.h
|
||||
semaphore.h
|
||||
servprov.h
|
||||
set
|
||||
setjmp.h
|
||||
SFNTLayoutTypes.h
|
||||
SFNTTypes.h
|
||||
|
@ -834,6 +839,7 @@ UReanimator.h
|
|||
URegions.h
|
||||
URegistrar.h
|
||||
UResourceMgr.h
|
||||
utility
|
||||
urlhist.h
|
||||
urlmon.h
|
||||
UScrap.h
|
||||
|
|
|
@ -4999,7 +4999,6 @@ AC_SUBST(MOZ_JPROF)
|
|||
AC_SUBST(MOZ_SHARK)
|
||||
AC_SUBST(MOZ_CALLGRIND)
|
||||
AC_SUBST(MOZ_VTUNE)
|
||||
AC_SUBST(MOZ_XPCTOOLS)
|
||||
AC_SUBST(MOZ_JSLOADER)
|
||||
AC_SUBST(MOZ_QUANTIFY)
|
||||
AC_SUBST(LIBICONV)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче