Merge last green PGO changeset from mozilla-inbound to mozilla-central

This commit is contained in:
Marco Bonardo 2011-12-19 12:47:41 +01:00
Родитель e3ce373803 9098fa4182
Коммит f0d8a7f557
130 изменённых файлов: 5486 добавлений и 4136 удалений

Просмотреть файл

@ -62,6 +62,7 @@ tier_base_dirs = \
config \
build \
probes \
mfbt \
$(NULL)
ifndef LIBXUL_SDK

Просмотреть файл

@ -62,7 +62,6 @@ NS_ConstructAccessibilityService(nsISupports *aOuter, REFNSIID aIID, void **aRes
}
NS_DEFINE_NAMED_CID(NS_ACCESSIBILITY_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_ACCESSIBLE_RETRIEVAL_CID);
static const mozilla::Module::CIDEntry kA11yCIDs[] = {
{ &kNS_ACCESSIBILITY_SERVICE_CID, false, NULL, NS_ConstructAccessibilityService },

Просмотреть файл

@ -440,7 +440,8 @@ nsAccUtils::GetTextAccessibleFromSelection(nsISelection* aSelection)
if (textAcc)
return textAcc;
} while (accessible = accessible->Parent());
accessible = accessible->Parent();
} while (accessible);
NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!");
return nsnull;

Просмотреть файл

@ -1565,14 +1565,14 @@ nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
if (relAttr == nsGkAtoms::_for) {
if (!aRelProvider->GetContent()->IsHTML() ||
aRelProvider->GetContent()->Tag() != nsGkAtoms::label &&
aRelProvider->GetContent()->Tag() != nsGkAtoms::output)
(aRelProvider->GetContent()->Tag() != nsGkAtoms::label &&
aRelProvider->GetContent()->Tag() != nsGkAtoms::output))
continue;
} else if (relAttr == nsGkAtoms::control) {
if (!aRelProvider->GetContent()->IsXUL() ||
aRelProvider->GetContent()->Tag() != nsGkAtoms::label &&
aRelProvider->GetContent()->Tag() != nsGkAtoms::description)
(aRelProvider->GetContent()->Tag() != nsGkAtoms::label &&
aRelProvider->GetContent()->Tag() != nsGkAtoms::description))
continue;
}

Просмотреть файл

@ -1252,8 +1252,12 @@ nsXULTreeGridCellAccessible::GetColumnIndex() const
{
PRInt32 index = 0;
nsCOMPtr<nsITreeColumn> column = mColumn;
while (column = nsCoreUtils::GetPreviousSensibleColumn(column))
while (true) {
column = nsCoreUtils::GetPreviousSensibleColumn(column);
if (!column)
break;
index++;
}
return index;
}

Просмотреть файл

@ -93,6 +93,7 @@
<preference id="privacy.cpd.cookies" name="privacy.cpd.cookies" type="bool"/>
<preference id="privacy.cpd.cache" name="privacy.cpd.cache" type="bool"/>
<preference id="privacy.cpd.sessions" name="privacy.cpd.sessions" type="bool"/>
<preference id="privacy.cpd.offlineApps" name="privacy.cpd.offlineApps" type="bool"/>
<preference id="privacy.cpd.siteSettings" name="privacy.cpd.siteSettings" type="bool"/>
</preferences>
@ -175,7 +176,7 @@
accesskey="&detailsProgressiveDisclosure.accesskey;"
control="detailsExpander"/>
</hbox>
<listbox id="itemList" rows="6" collapsed="true" persist="collapsed">
<listbox id="itemList" rows="7" collapsed="true" persist="collapsed">
<listitem label="&itemHistoryAndDownloads.label;"
type="checkbox"
accesskey="&itemHistoryAndDownloads.accesskey;"
@ -201,6 +202,11 @@
accesskey="&itemActiveLogins.accesskey;"
preference="privacy.cpd.sessions"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemOfflineApps.label;"
type="checkbox"
accesskey="&itemOfflineApps.accesskey;"
preference="privacy.cpd.offlineApps"
onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
<listitem label="&itemSitePreferences.label;"
type="checkbox"
accesskey="&itemSitePreferences.accesskey;"

Просмотреть файл

@ -463,6 +463,108 @@ var gAllTests = [
this.cancelDialog();
};
wh.open();
},
function () {
// Test for offline apps data and cache deletion
// Prepare stuff, we will work with www.example.com
var URL = "http://www.example.com";
var ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var URI = ios.newURI(URL, null, null);
var sm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
var principal = sm.getCodebasePrincipal(URI);
// Give www.example.com privileges to store offline data
var pm = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
pm.add(URI, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION);
pm.add(URI, "offline-app", Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
// Store some user data to localStorage
var dsm = Cc["@mozilla.org/dom/storagemanager;1"]
.getService(Ci.nsIDOMStorageManager);
var localStorage = dsm.getLocalStorageForPrincipal(principal, URL);
localStorage.setItem("test", "value");
// Store something to the offline cache
const nsICache = Components.interfaces.nsICache;
var cs = Components.classes["@mozilla.org/network/cache-service;1"]
.getService(Components.interfaces.nsICacheService);
var session = cs.createSession(URL + "/manifest", nsICache.STORE_OFFLINE, nsICache.STREAM_BASED);
var cacheEntry = session.openCacheEntry(URL, nsICache.ACCESS_READ_WRITE, false);
var stream = cacheEntry.openOutputStream(0);
var content = "content";
stream.write(content, content.length);
stream.close();
cacheEntry.close();
// Open the dialog
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
// Show details
this.toggleDetails();
// Clear only offlineApps
this.uncheckAllCheckboxes();
this.checkPrefCheckbox("offlineApps", true);
this.acceptDialog();
// Check all has been deleted (data, cache)
is(localStorage.length, 0, "DOM storage cleared");
var size = -1;
var visitor = {
visitDevice: function (deviceID, deviceInfo)
{
if (deviceID == "offline")
size = deviceInfo.totalSize;
// Do not enumerate entries
return false;
},
visitEntry: function (deviceID, entryInfo)
{
// Do not enumerate entries.
return false;
}
};
cs.visitEntries(visitor);
is(size, 0, "offline application cache entries evicted");
};
wh.open();
},
function () {
// Test for offline apps permission deletion
// Prepare stuff, we will work with www.example.com
var URL = "http://www.example.com";
var ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var URI = ios.newURI(URL, null, null);
// Open the dialog
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
// Show details
this.toggleDetails();
// Clear only offlineApps
this.uncheckAllCheckboxes();
this.checkPrefCheckbox("siteSettings", true);
this.acceptDialog();
// Check all has been deleted (privileges, data, cache)
var pm = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
is(pm.testPermission(URI, "offline-app"), 0, "offline-app permissions removed");
};
wh.open();
}
];
@ -557,16 +659,24 @@ WindowHelper.prototype = {
/**
* Makes sure all the checkboxes are checked.
*/
checkAllCheckboxes: function () {
_checkAllCheckboxesCustom: function (check) {
var cb = this.win.document.querySelectorAll("#itemList > [preference]");
ok(cb.length > 1, "found checkboxes for preferences");
for (var i = 0; i < cb.length; ++i) {
var pref = this.win.document.getElementById(cb[i].getAttribute("preference"));
if (!pref.value)
if (!!pref.value ^ check)
cb[i].click();
}
},
checkAllCheckboxes: function () {
this._checkAllCheckboxesCustom(true);
},
uncheckAllCheckboxes: function () {
this._checkAllCheckboxesCustom(false);
},
/**
* @return The details progressive disclosure button
*/

Просмотреть файл

@ -180,7 +180,7 @@ then
fi
MOZ_BUILD_ROOT=`pwd`
dnl Default to MSVC for win32 and gcc-4.2 for darwin
dnl Default to MSVC for win32 and gcc for darwin
dnl ==============================================================
if test -z "$CROSS_COMPILE"; then
case "$target" in
@ -203,8 +203,10 @@ case "$target" in
if test -z "$MIDL"; then MIDL=midl; fi
;;
*-darwin*)
if test -z "$CC"; then CC=gcc-4.2; fi
if test -z "$CXX"; then CXX=g++-4.2; fi
# we prefer gcc-4.2 over gcc on older darwin, so
# use that specific version if it's available.
MOZ_PATH_PROGS(CC, $CC gcc-4.2 gcc)
MOZ_PATH_PROGS(CXX, $CXX g++-4.2 g++)
;;
esac
fi
@ -4139,13 +4141,6 @@ AC_CACHE_CHECK(for __attribute__((warn_unused_result)),
ac_cv_attribute_warn_unused=yes,
ac_cv_attribute_warn_unused=no)])
AC_CACHE_CHECK(for __attribute__((noreturn)),
ac_cv_attribute_noreturn,
[AC_TRY_COMPILE([void f(void) __attribute__((noreturn));],
[],
ac_cv_attribute_noreturn=yes,
ac_cv_attribute_noreturn=no)])
dnl End of C++ language/feature checks
AC_LANG_C
@ -4201,12 +4196,6 @@ else
AC_DEFINE(NS_WARN_UNUSED_RESULT,)
fi
if test "$ac_cv_attribute_noreturn" = yes ; then
AC_DEFINE(NS_NORETURN, [__attribute__((noreturn))])
else
AC_DEFINE(NS_NORETURN,)
fi
dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
dnl features that Windows actually does support.

Просмотреть файл

@ -953,7 +953,8 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
nsresult rv = docshell->GetAppType(&appType);
if (NS_FAILED(rv) || appType == nsIDocShell::APP_TYPE_MAIL)
return; // do not prefetch from mailnews
if (treeItem = do_QueryInterface(docshell)) {
treeItem = do_QueryInterface(docshell);
if (treeItem) {
treeItem->GetParent(getter_AddRefs(parentItem));
if (parentItem) {
treeItem = parentItem;

Просмотреть файл

@ -8627,40 +8627,6 @@ nsDocument::IsFullScreenDoc()
return GetFullScreenElement() != nsnull;
}
static nsIDocument*
GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
{
if (!aDoc1 || !aDoc2) {
return nsnull;
}
nsIDocument* doc1 = aDoc1;
nsIDocument* doc2 = aDoc2;
nsAutoTArray<nsIDocument*, 30> parents1, parents2;
do {
parents1.AppendElement(doc1);
doc1 = doc1->GetParentDocument();
} while (doc1);
do {
parents2.AppendElement(doc2);
doc2 = doc2->GetParentDocument();
} while (doc2);
PRUint32 pos1 = parents1.Length();
PRUint32 pos2 = parents2.Length();
nsIDocument* parent = nsnull;
PRUint32 len;
for (len = NS_MIN(pos1, pos2); len > 0; --len) {
nsIDocument* child1 = parents1.ElementAt(--pos1);
nsIDocument* child2 = parents2.ElementAt(--pos2);
if (child1 != child2) {
break;
}
parent = child1;
}
return parent;
}
class nsCallRequestFullScreen : public nsRunnable
{
public:
@ -8801,6 +8767,50 @@ nsDocument::FullScreenStackTop()
return element;
}
// Returns true if aDoc is in the focused tab in the active window.
static bool
IsInActiveTab(nsIDocument* aDoc)
{
nsCOMPtr<nsISupports> container = aDoc->GetContainer();
nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(container);
if (!docshell) {
return false;
}
bool isActive = false;
docshell->GetIsActive(&isActive);
if (!isActive) {
return false;
}
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
if (!dsti) {
return false;
}
nsCOMPtr<nsIDocShellTreeItem> rootItem;
dsti->GetRootTreeItem(getter_AddRefs(rootItem));
if (!rootItem) {
return false;
}
nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
if (!rootWin) {
return false;
}
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
return false;
}
nsCOMPtr<nsIDOMWindow> activeWindow;
fm->GetActiveWindow(getter_AddRefs(activeWindow));
if (!activeWindow) {
return false;
}
return activeWindow == rootWin;
}
void
nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
{
@ -8832,6 +8842,25 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
return;
}
if (!nsContentUtils::IsChromeDoc(this) && !IsInActiveTab(this)) {
LogFullScreenDenied(true, "FullScreenDeniedNotFocusedTab", this);
return;
}
// Deny requests when a windowed plugin is focused.
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
NS_WARNING("Failed to retrieve focus manager in full-screen request.");
return;
}
nsCOMPtr<nsIDOMElement> focusedElement;
fm->GetFocusedElement(getter_AddRefs(focusedElement));
if (focusedElement) {
nsCOMPtr<nsIContent> content = do_QueryInterface(focusedElement);
if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(content)) {
LogFullScreenDenied(true, "FullScreenDeniedFocusedPlugin", this);
return;
}
}
// Stores a list of documents which we must dispatch "mozfullscreenchange"
// too. We're required by the spec to dispatch the events in root-to-leaf
@ -8840,16 +8869,6 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
// as specified.
nsAutoTArray<nsIDocument*, 8> changed;
// If another top-level window is full-screen. Exit it from full-screen.
nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
nsIDocument* commonAncestor = GetCommonAncestor(fullScreenDoc, this);
if (fullScreenDoc && !commonAncestor) {
// A document which doesn't have a common ancestor is full-screen, this
// must be in a separate browser window. Fully exit full-screen, to move
// the other browser window/doctree out of full-screen.
nsIDocument::ExitFullScreen(false);
}
// Remember the root document, so that if a full-screen document is hidden
// we can reset full-screen state in the remaining visible full-screen documents.
sFullScreenRootDoc = do_GetWeakReference(nsContentUtils::GetRootDocument(this));
@ -8874,8 +8893,6 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
changed.AppendElement(parent);
child = parent;
} else {
NS_ASSERTION(!commonAncestor || child == commonAncestor,
"Should finish loop at common ancestor (or null)");
// We've reached either the root, or a point in the doctree where the
// new full-screen element container is the same as the previous
// full-screen element's container. No more changes need to be made
@ -8988,10 +9005,6 @@ nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
LogFullScreenDenied(aLogFailure, "FullScreenDeniedDisabled", this);
return false;
}
if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
LogFullScreenDenied(aLogFailure, "FullScreenDeniedPlugins", this);
return false;
}
if (!IsVisible()) {
LogFullScreenDenied(aLogFailure, "FullScreenDeniedHidden", this);
return false;

Просмотреть файл

@ -2691,8 +2691,8 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
// can run script that would try to restart this request, and that could end
// up doing our AsyncOpen on a null channel if the reentered AsyncOpen fails.
ChangeState(XML_HTTP_REQUEST_SENT);
if (!mUploadComplete &&
HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
if ((!mUploadComplete &&
HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR))) ||
(mUpload && mUpload->HasListenersFor(NS_LITERAL_STRING(PROGRESS_STR)))) {
StartProgressEventTimer();
}

Просмотреть файл

@ -496,8 +496,10 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
Preferences::GetBool("webgl.force_osmesa", false);
bool preferEGL =
Preferences::GetBool("webgl.prefer-egl", false);
#ifdef XP_WIN
bool preferOpenGL =
Preferences::GetBool("webgl.prefer-native-gl", false);
#endif
bool forceEnabled =
Preferences::GetBool("webgl.force-enabled", false);
bool disabled =

Просмотреть файл

@ -378,8 +378,8 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
nsKeyEvent * keyEvent = (nsKeyEvent *)aVisitor.mEvent;
if ((keyEvent->keyCode == NS_VK_RETURN &&
NS_KEY_PRESS == aVisitor.mEvent->message) ||
keyEvent->keyCode == NS_VK_SPACE &&
NS_KEY_UP == aVisitor.mEvent->message) {
(keyEvent->keyCode == NS_VK_SPACE &&
NS_KEY_UP == aVisitor.mEvent->message)) {
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),

Просмотреть файл

@ -471,7 +471,7 @@ nsHTMLMenuItemElement::WalkRadioGroup(Visitor* aVisitor)
bool info2Empty = !info2.mValue || info2.mValue->IsEmptyString();
if (info1Empty != info2Empty ||
info1.mValue && info2.mValue && !info1.mValue->Equals(*info2.mValue)) {
(info1.mValue && info2.mValue && !info1.mValue->Equals(*info2.mValue))) {
continue;
}

Просмотреть файл

@ -290,20 +290,6 @@ nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
}
#ifndef XP_MACOSX
if (aDocument &&
aDocument->IsFullScreenDoc() &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
// This content contains a windowed plugin for which we don't control
// event dispatch, and we're in full-screen mode. Exit full-screen mode
// to prevent phishing attacks.
nsIDocument::ExitFullScreen(true);
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
"DOM", aDocument,
nsContentUtils::eDOM_PROPERTIES,
"AddedWindowedPluginWhileFullScreen");
}
#endif
return NS_OK;
}

Просмотреть файл

@ -1142,7 +1142,7 @@ nsHTMLTextAreaElement::IntrinsicState() const
// error and never applies if novalidate is set on the form owner.
if ((!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) &&
(GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
mCanShowInvalidUI && ShouldShowValidityUI())) {
(mCanShowInvalidUI && ShouldShowValidityUI()))) {
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
}
}

Просмотреть файл

@ -23,11 +23,12 @@ Test plugins with DOM full-screen API:
</head>
<body onload="scheduleTest();">
<!-- Windowed plugin, should prevent first full-screen request. -->
<!-- Windowed plugin, focusing should revoke full-screen. -->
<embed id="windowed-plugin" type="application/x-test" style="width:200px;height:100px;" wmode="window"></embed>
<!-- Windowless plugin, should not prevent full-screen requests. -->
<embed type="application/x-test" style="width:200px;height:100px;"></embed>
<!-- Windowless plugin, focusing should not revoke full-screen. -->
<embed id="windowless-plugin" type="application/x-test" style="width:200px;height:100px;"></embed>
<!-- iframe contents:
@ -50,9 +51,11 @@ function is(a, b, msg) {
opener.is(a, b, "[plugins] " + msg);
}
const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
function e(id) {
return document.getElementById(id);
}
document.addEventListener("mozfullscreenchange", isMacOs ? macFullScreenChange : fullScreenChange, false);
const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
var windowedPlugin = null;
@ -70,9 +73,14 @@ function startTest() {
ok(!document.mozFullScreen, "Should not be in full-screen mode initially");
document.body.mozRequestFullScreen();
// Focus the windowed plugin. On MacOS we should still enter full-screen mode,
// on windows the pending request for full-screen should be denied.
e("windowed-plugin").focus();
if (isMacOs) {
// Running on MacOS, all plugins are effectively windowless, request for full-screen should be granted.
// Continue test in the (mac-specific) "mozfullscreenchange" handler.
document.addEventListener("mozfullscreenchange", macFullScreenChange, false);
return;
} else {
// Non-MacOS, request should be denied, carry on the test after receiving error event.
@ -82,24 +90,25 @@ function startTest() {
function nonMacTest() {
document.removeEventListener("mozfullscreenerror", nonMacTest, false);
ok(!document.mozFullScreen, "Request for full-screen from a document containing windowed plugin should be denied.");
ok(!document.mozFullScreen, "Request for full-screen with focused windowed plugin should be denied.");
// Remove plugin in this document. Should still be a windowed plugin in sub-document.
windowedPlugin = document.getElementById("windowed-plugin");
windowedPlugin.parentNode.removeChild(windowedPlugin);
document.addEventListener("mozfullscreenerror", nonMacTest2, false);
// Focus a regular html element, and re-request full-screen, request should be granted.
e("windowless-plugin").focus();
document.addEventListener("mozfullscreenchange", nonMacTest2, false);
document.body.mozRequestFullScreen();
}
function nonMacTest2() {
document.removeEventListener("mozfullscreenerror", nonMacTest2, false);
ok(!document.mozFullScreen, "Request for full-screen from a document with subdocument containing windowed plugin should be denied.");
// Remove subdoc which contains windowed plugin, request full-screen, request should be granted.
// Continue test in "mozfullscreenchange" handler.
var f = document.getElementById("subdoc-plugin");
f.parentNode.removeChild(f);
document.body.mozRequestFullScreen();
document.removeEventListener("mozfullscreenchange", nonMacTest2, false);
ok(document.mozFullScreen, "Request for full-screen with non-plugin focused should be granted.");
// Focus a windowed plugin, full-screen should be revoked.
document.addEventListener("mozfullscreenchange", nonMacTest3, false);
e("windowed-plugin").focus();
}
function nonMacTest3() {
ok(!document.mozFullScreen, "Full-screen should have been revoked when windowed-plugin was focused.");
opener.nextTest();
}
var fullScreenChangeCount = 0;
@ -114,15 +123,18 @@ function createWindowedPlugin() {
function macFullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
ok(document.mozFullScreen, "Requests for full-screen on pages with plugins should be granted on MacOS");
ok(document.mozFullScreen, "Requests for full-screen with focused windowed plugins should be granted on MacOS");
// Create a new windowed plugin, and add that to the document. Should *not* exit full-screen mode on MacOS.
windowedPlugin = createWindowedPlugin();
document.body.appendChild(windowedPlugin);
// Focus windowed plugin. Should not exit full-screen mode on MacOS.
windowedPlugin.focus();
setTimeout(
function() {
ok(document.mozFullScreen, "Adding windowed plugin to document should not cause full-screen to exit on MacOS.");
ok(document.mozFullScreen, "Adding & focusing a windowed plugin to document should not cause full-screen to exit on MacOS.");
document.mozCancelFullScreen();
}, 0);
@ -140,52 +152,6 @@ function macFullScreenChange(event) {
fullScreenChangeCount++;
}
function fullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
ok(document.mozFullScreen, "Request for full-screen with document containing windowless plugin should be granted");
is(document.mozFullScreenElement, document.body, "FSE should be body.");
// Add windowed plugin to document, should cause full-screen mode to exit.
document.body.appendChild(windowedPlugin);
break;
}
case 1: {
ok(!document.mozFullScreen, "Should have left full-screen mode after re-adding windowed plugin to document");
windowedPlugin.parentNode.removeChild(windowedPlugin);
document.body.mozRequestFullScreen();
break;
}
case 2: {
ok(document.mozFullScreen, "Should have reentered full-screen mode");
// Create a new windowed plugin, and add that to the document. Should exit full-screen mode.
windowedPlugin = createWindowedPlugin();
document.body.appendChild(windowedPlugin);
break;
}
case 3: {
ok(!document.mozFullScreen, "Should have left full-screen mode after adding windowed plugin created after going full-screen to document");
windowedPlugin.parentNode.removeChild(windowedPlugin);
windowedPlugin = createWindowedPlugin();
document.body.mozRequestFullScreen();
break;
}
case 4: {
ok(document.mozFullScreen, "Should have (again) reentered full-screen mode");
document.body.appendChild(windowedPlugin);
break;
}
case 5: {
ok(!document.mozFullScreen, "Should have left full-screen mode after adding windowed plugin created before going full-screen to document");
opener.nextTest();
break;
}
default: {
ok(false, "Should not receive any more fullscreenchange events!");
}
}
fullScreenChangeCount++;
}
</script>
</pre>
</body>

Просмотреть файл

@ -2173,7 +2173,6 @@ nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
}
PRInt32 bytes;
PRUint32 channelBlock = PRUint32(mChannelOffset/BLOCK_SIZE);
PRInt32 cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
if (cacheBlock < 0) {
// We don't have a complete cached block here.

Просмотреть файл

@ -641,9 +641,9 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute,
// xbl:text set on us.
if ((dstAttr == nsGkAtoms::text && dstNs == kNameSpaceID_XBL) ||
realElement->NodeInfo()->Equals(nsGkAtoms::html,
kNameSpaceID_XUL) &&
dstAttr == nsGkAtoms::value) {
(realElement->NodeInfo()->Equals(nsGkAtoms::html,
kNameSpaceID_XUL) &&
dstAttr == nsGkAtoms::value)) {
// Flush out all our kids.
PRUint32 childCount = realElement->GetChildCount();
for (PRUint32 i = 0; i < childCount; i++)

Просмотреть файл

@ -83,6 +83,7 @@
#include "mozAutoDocUpdate.h"
#include "mozilla/Preferences.h"
#include "mozilla/LookAndFeel.h"
#include "nsIScriptError.h"
#ifdef MOZ_XUL
#include "nsIDOMXULTextboxElement.h"
@ -1183,6 +1184,24 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags,
isElementInActiveWindow, isElementInFocusedWindow);
#endif
// Exit full-screen if we're focusing a windowed plugin on a non-MacOSX
// system. We don't control event dispatch to windowed plugins on non-MacOSX,
// so we can't display the "Press ESC to leave full-screen mode" warning on
// key input if a windowed plugin is focused, so just exit full-screen
// to guard against phishing.
#ifndef XP_MACOSX
if (contentToFocus &&
nsContentUtils::GetRootDocument(contentToFocus->OwnerDoc())->IsFullScreenDoc() &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
"DOM",
contentToFocus->OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
"FocusedWindowedPluginWhileFullScreen");
nsIDocument::ExitFullScreen(true);
}
#endif
// if the FLAG_NOSWITCHFRAME flag is used, only allow the focus to be
// shifted away from the current element if the new shell to focus is
// the same or an ancestor shell of the currently focused shell.

Просмотреть файл

@ -40,6 +40,7 @@
#ifndef mozilla_dom_ContentChild_h
#define mozilla_dom_ContentChild_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/PContentChild.h"
#include "nsTArray.h"
@ -194,7 +195,7 @@ private:
* Exit *now*. Do not shut down XPCOM, do not pass Go, do not run
* static destructors, do not collect $200.
*/
NS_NORETURN void QuickExit();
MOZ_NORETURN void QuickExit();
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
nsRefPtr<ConsoleListener> mConsoleListener;

Просмотреть файл

@ -118,7 +118,7 @@ GlobalStorageWarning=Use of globalStorage is deprecated. Please use localStorage
# LOCALIZATION NOTE: Do not translate "MozBeforePaint" and "mozRequestAnimationFrame"
MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument.
FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference.
FullScreenDeniedPlugins=Request for full-screen was denied because a document on this page contains a windowed plugin.
FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused.
FullScreenDeniedHidden=Request for full-screen was denied because the document is no longer visible.
FullScreenDeniedIframeDisallowed=Request for full-screen was denied because at least one of the document's containing iframes does not have a "mozallowfullscreen" attribute.
FullScreenDeniedNotInputDriven=Request for full-screen was denied because Element.mozRequestFullScreen() was not called from inside a short running user-generated event handler.
@ -127,8 +127,9 @@ FullScreenDeniedMovedDocument=Request for full-screen was denied because request
FullScreenDeniedLostWindow=Request for full-screen was denied because we no longer have a window.
FullScreenDeniedSubDocFullScreen=Request for full-screen was denied because a subdocument of the document requesting full-screen is already full-screen.
FullScreenDeniedNotDescendant=Request for full-screen was denied because requesting element is not a descendant of the current full-screen element.
FullScreenDeniedNotFocusedTab=Request for full-screen was denied because requesting element is not in the currently focused tab.
RemovedFullScreenElement=Exited full-screen because full-screen element was removed from document.
AddedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was added to document.
FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.

Просмотреть файл

@ -3311,11 +3311,6 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
bool windowless = false;
mInstance->IsWindowless(&windowless);
nsIDocument *doc = mContent ? mContent->OwnerDoc() : nsnull;
#ifndef XP_MACOSX
if (!windowless && doc && doc->IsFullScreenDoc()) {
nsIDocument::ExitFullScreen(true);
}
#endif
// always create widgets in Twips, not pixels
nsPresContext* context = mObjectFrame->PresContext();
rv = mObjectFrame->CreateWidget(context->DevPixelsToAppUnits(mPluginWindow->width),

Просмотреть файл

@ -40,6 +40,8 @@
#ifndef dom_plugins_PluginModuleChild_h
#define dom_plugins_PluginModuleChild_h 1
#include "mozilla/Attributes.h"
#include <string>
#include <vector>
@ -192,7 +194,7 @@ protected:
virtual void
ActorDestroy(ActorDestroyReason why);
NS_NORETURN void QuickExit();
MOZ_NORETURN void QuickExit();
NS_OVERRIDE virtual bool
RecvProcessNativeEventsInRPCCall();

Просмотреть файл

@ -8,6 +8,7 @@
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"><![CDATA[
// List of key codes, and whether they should cause a warning in full-screen mode.
@ -245,9 +246,13 @@ window.addEventListener("keyup", keyHandler, true);
window.addEventListener("keypress", keyHandler, true);
function start() {
gBrowser = document.getElementById("browser");
gBrowser.contentDocument.body.mozRequestFullScreen();
setTimeout(startNextTest, 0);
SimpleTest.waitForFocus(
function() {
gBrowser = document.getElementById("browser");
gBrowser.contentWindow.focus();
gBrowser.contentDocument.body.mozRequestFullScreen();
setTimeout(startNextTest, 0);
});
}
]]>

Просмотреть файл

@ -6,8 +6,7 @@
-->
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="400" height="400">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -1566,19 +1566,19 @@ XMLHttpRequestPrivate::GetAllResponseHeaders(JSContext* aCx)
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
return nsnull;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
return nsnull;
}
nsCString responseHeaders;
nsRefPtr<GetAllResponseHeadersRunnable> runnable =
new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders);
if (!runnable->Dispatch(aCx)) {
return false;
return nsnull;
}
return JS_NewStringCopyN(aCx, responseHeaders.get(),
@ -1591,17 +1591,17 @@ XMLHttpRequestPrivate::GetResponseHeader(JSContext* aCx, JSString* aHeader)
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
return nsnull;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
return nsnull;
}
nsDependentJSString header;
if (!header.init(aCx, aHeader)) {
return false;
return nsnull;
}
nsCString value;
@ -1609,7 +1609,7 @@ XMLHttpRequestPrivate::GetResponseHeader(JSContext* aCx, JSString* aHeader)
new GetResponseHeaderRunnable(mWorkerPrivate, mProxy,
NS_ConvertUTF16toUTF8(header), value);
if (!runnable->Dispatch(aCx)) {
return false;
return nsnull;
}
return JS_NewStringCopyN(aCx, value.get(), value.Length());

Просмотреть файл

@ -948,7 +948,7 @@ nsHTMLEditor::GetBlockNodeParent(nsIDOMNode *aNode)
if (!aNode)
{
NS_NOTREACHED("null node passed to GetBlockNodeParent()");
return false;
return nsnull;
}
nsCOMPtr<nsIDOMNode> p;
@ -5680,7 +5680,7 @@ nsHTMLEditor::IsActiveInDOMWindow()
nsIContent*
nsHTMLEditor::GetActiveEditingHost()
{
NS_ENSURE_TRUE(mDocWeak, false);
NS_ENSURE_TRUE(mDocWeak, nsnull);
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
NS_ENSURE_TRUE(doc, nsnull);

Просмотреть файл

@ -195,8 +195,8 @@ float JapaneseContextAnalysis::GetConfidence(void)
PRInt32 SJISContextAnalysis::GetOrder(const char* str, PRUint32 *charLen)
{
//find out current char's byte length
if ((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f ||
(unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xfc )
if (((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f) ||
((unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xfc) )
*charLen = 2;
else
*charLen = 1;

Просмотреть файл

@ -1,6 +1,6 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/
Current revision: r901
Current revision: r924
== Applied local patches ==

Просмотреть файл

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 8540788b2b719f35fe3991b913d3b696f98de730
# Parent 2cefa41bd95ba8875964dde3829559fd70b8101d
diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp

Просмотреть файл

@ -1,26 +1,5 @@
# HG changeset patch
# Parent 099e4d30cde1424e15dd9a72fb4b2589754ceaa0
diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -2,16 +2,17 @@ This is the ANGLE project, from http://c
Current revision: r885
== Applied local patches ==
In this order:
angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
+ angle-limit-identifiers-to-250-chars.patch - see bug 675625
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
== How to update this ANGLE copy ==
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
# Parent 60ae9443af647dc56c76bf9c7a5958f2ff176fb8
diff --git a/gfx/angle/src/compiler/preprocessor/length_limits.h b/gfx/angle/src/compiler/preprocessor/length_limits.h
--- a/gfx/angle/src/compiler/preprocessor/length_limits.h
+++ b/gfx/angle/src/compiler/preprocessor/length_limits.h

Просмотреть файл

@ -1,9 +1,10 @@
# HG changeset patch
# Parent b6f65ca6027d397ca50783d7164a6a8fa59eef4c
# Parent 7e7cd80ef724c094b88ed8bb35f3af0ce9a9cfee
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -73,17 +73,17 @@ CPPSRCS = \
@@ -75,17 +75,17 @@ CPPSRCS = \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
@ -22,6 +23,51 @@ diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
BuiltInFunctionEmulator.cpp \
$(NULL)
diff --git a/gfx/angle/angle-renaming-debug.patch b/gfx/angle/angle-renaming-debug.patch
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,14 +1,14 @@
# HG changeset patch
-# Parent b6f65ca6027d397ca50783d7164a6a8fa59eef4c
+# Parent 1879d857ef07dc5797704516caea99b231d7590a
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
-@@ -73,17 +73,17 @@ CPPSRCS = \
+@@ -75,17 +75,17 @@ CPPSRCS = \
parseConst.cpp \
ParseHelper.cpp \
PoolAlloc.cpp \
QualifierAlive.cpp \
RemoveTree.cpp \
ShaderLang.cpp \
SymbolTable.cpp \
VariableInfo.cpp \
@@ -163,22 +163,22 @@ diff --git a/gfx/angle/src/compiler/prep
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "compiler/debug.h"
+#include "compiler/compilerdebug.h"
#include "compiler/preprocessor/slglobals.h"
+ #include "../../../../../memory/mozalloc/mozalloc.h"
+
#undef malloc
#undef realloc
#undef free
- ///////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////// String table: //////////////////////////////////////
diff --git a/gfx/angle/src/compiler/preprocessor/tokens.c b/gfx/angle/src/compiler/preprocessor/tokens.c
--- a/gfx/angle/src/compiler/preprocessor/tokens.c
+++ b/gfx/angle/src/compiler/preprocessor/tokens.c
@@ -45,17 +45,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
// tokens.c
//
#include <stdlib.h>
diff --git a/gfx/angle/src/compiler/OutputGLSLBase.cpp b/gfx/angle/src/compiler/OutputGLSLBase.cpp
--- a/gfx/angle/src/compiler/OutputGLSLBase.cpp
+++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp

Просмотреть файл

@ -1,9 +1,10 @@
# HG changeset patch
# Parent 31d1c6ebb61eb118868ca924769a2fa3a50d54ef
# Parent bc7188c29ec5b942046c0589ce959d7985f7ad6e
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -127,16 +127,18 @@ CSRCS = \
@@ -129,16 +129,18 @@ CSRCS = \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
@ -22,27 +23,75 @@ diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
libs::
expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -3,16 +3,17 @@ This is the ANGLE project, from http://c
Current revision: r885
== Applied local patches ==
In this order:
angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-limit-identifiers-to-250-chars.patch - see bug 675625
+ angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
== How to update this ANGLE copy ==
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
diff --git a/gfx/angle/angle-use-xmalloc.patch b/gfx/angle/angle-use-xmalloc.patch
--- a/gfx/angle/angle-use-xmalloc.patch
+++ b/gfx/angle/angle-use-xmalloc.patch
@@ -1,14 +1,14 @@
# HG changeset patch
-# Parent 31d1c6ebb61eb118868ca924769a2fa3a50d54ef
+# Parent 6a1ee30b3a60564c165795ecf79e9c2081ee80ab
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
-@@ -127,16 +127,18 @@ CSRCS = \
+@@ -129,16 +129,18 @@ CSRCS = \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
#these defines are from ANGLE's build_angle.gyp
DEFINES += -DANGLE_DISABLE_TRACE
DEFINES += -DANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0
@@ -17,47 +17,26 @@ diff --git a/gfx/angle/Makefile.in b/gfx
ifdef MOZ_ANGLE
# libEGL depends on (links against!) libGLESv2!
DIRS = src/libGLESv2 src/libEGL
libs::
expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
-diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
---- a/gfx/angle/README.mozilla
-+++ b/gfx/angle/README.mozilla
-@@ -3,16 +3,17 @@ This is the ANGLE project, from http://c
- Current revision: r885
-
- == Applied local patches ==
-
- In this order:
- angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
- angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
- angle-limit-identifiers-to-250-chars.patch - see bug 675625
-+ angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
-
- In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
-
- == How to update this ANGLE copy ==
-
- 1. Unapply patches
- 2. Apply diff with new ANGLE version
- 3. Reapply patches.
diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
--- a/gfx/angle/src/compiler/preprocessor/atom.c
+++ b/gfx/angle/src/compiler/preprocessor/atom.c
@@ -48,16 +48,18 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
- #include "compiler/compilerdebug.h"
+ #include "compiler/debug.h"
#include "compiler/preprocessor/slglobals.h"
+#include "../../../../../memory/mozalloc/mozalloc.h"
+
#undef malloc
#undef realloc
#undef free
diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
--- a/gfx/angle/src/compiler/preprocessor/atom.c
+++ b/gfx/angle/src/compiler/preprocessor/atom.c

Просмотреть файл

@ -159,6 +159,14 @@
'gles2_book/TextureWrap/TextureWrap.c',
],
},
{
'target_name': 'post_sub_buffer',
'type': 'executable',
'dependencies': ['es_util'],
'sources': [
'gles2_book/PostSubBuffer/PostSubBuffer.c',
],
},
],
}],
],

Просмотреть файл

@ -22,10 +22,16 @@
#include <stdlib.h>
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "esUtil.h"
#include "esUtil_win.h"
///
// Extensions
//
PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
///
@ -35,7 +41,7 @@
//
EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
EGLContext* eglContext, EGLSurface* eglSurface,
EGLint attribList[])
EGLint* configAttribList, EGLint* surfaceAttribList)
{
EGLint numConfigs;
EGLint majorVersion;
@ -45,7 +51,7 @@ EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
EGLSurface surface;
EGLConfig config;
EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
// Get Display
display = eglGetDisplay(GetDC(hWnd));
if ( display == EGL_NO_DISPLAY )
@ -59,6 +65,9 @@ EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
return EGL_FALSE;
}
// Bind to extensions
eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC) eglGetProcAddress("eglPostSubBufferNV");
// Get configs
if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )
{
@ -66,13 +75,13 @@ EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
}
// Choose config
if ( !eglChooseConfig(display, attribList, &config, 1, &numConfigs) )
if ( !eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) )
{
return EGL_FALSE;
}
// Create a surface
surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL);
surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, surfaceAttribList);
if ( surface == EGL_NO_SURFACE )
{
return EGL_FALSE;
@ -128,10 +137,11 @@ void ESUTIL_API esInitContext ( ESContext *esContext )
// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
// ES_WINDOW_POST_SUB_BUFFER_SUPPORTED - specifies that EGL_POST_SUB_BUFFER_NV is supported.
//
GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint width, GLint height, GLuint flags )
{
EGLint attribList[] =
EGLint configAttribList[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
@ -142,6 +152,11 @@ GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint
EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
EGL_NONE
};
EGLint surfaceAttribList[] =
{
EGL_POST_SUB_BUFFER_SUPPORTED_NV, flags & (ES_WINDOW_POST_SUB_BUFFER_SUPPORTED) ? EGL_TRUE : EGL_FALSE,
EGL_NONE, EGL_NONE
};
if ( esContext == NULL )
{
@ -161,7 +176,8 @@ GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint
&esContext->eglDisplay,
&esContext->eglContext,
&esContext->eglSurface,
attribList) )
configAttribList,
surfaceAttribList ) )
{
return GL_FALSE;
}

Просмотреть файл

@ -22,6 +22,7 @@
//
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#ifdef __cplusplus
@ -44,9 +45,10 @@ extern "C" {
#define ES_WINDOW_DEPTH 2
/// esCreateWindow flag - stencil buffer
#define ES_WINDOW_STENCIL 4
/// esCreateWindow flat - multi-sample buffer
/// esCreateWindow flag - multi-sample buffer
#define ES_WINDOW_MULTISAMPLE 8
/// esCreateWindow flag - EGL_POST_SUB_BUFFER_NV supported.
#define ES_WINDOW_POST_SUB_BUFFER_SUPPORTED 16
///
// Types
@ -87,6 +89,13 @@ typedef struct
} ESContext;
///
// Extensions
//
extern PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
///
// Public Functions
//
@ -110,6 +119,7 @@ void ESUTIL_API esInitContext ( ESContext *esContext );
/// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
/// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
/// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
/// ES_WINDOW_POST_SUB_BUFFER_SUPPORTED - specifies that EGL_POST_SUB_BUFFER_NV is supported.
/// \return GL_TRUE if window creation is succesful, GL_FALSE otherwise
GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, LPCTSTR title, GLint width, GLint height, GLuint flags );

Просмотреть файл

@ -0,0 +1,204 @@
// Based on a sample from:
//
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
//
// PostSubBuffer.c
//
// This is a simple example that draws a rotating cube in perspective
// using a vertex shader to transform the object, posting only a subrectangle
// to the window surface.
//
#include <stdlib.h>
#include "esUtil.h"
#define WINDOW_WIDTH 320
#define WINDOW_HEIGHT 240
typedef struct
{
// Handle to a program object
GLuint programObject;
// Attribute locations
GLint positionLoc;
// Uniform locations
GLint mvpLoc;
// Vertex daata
GLfloat *vertices;
GLushort *indices;
int numIndices;
// Rotation angle
GLfloat angle;
// MVP matrix
ESMatrix mvpMatrix;
} UserData;
///
// Initialize the shader and program object
//
int Init ( ESContext *esContext )
{
UserData *userData = esContext->userData;
GLbyte vShaderStr[] =
"uniform mat4 u_mvpMatrix; \n"
"attribute vec4 a_position; \n"
"void main() \n"
"{ \n"
" gl_Position = u_mvpMatrix * a_position; \n"
"} \n";
GLbyte fShaderStr[] =
"precision mediump float; \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); \n"
"} \n";
// Load the shaders and get a linked program object
userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
// Get the attribute locations
userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
// Get the uniform locations
userData->mvpLoc = glGetUniformLocation( userData->programObject, "u_mvpMatrix" );
// Generate the vertex data
userData->numIndices = esGenCube( 1.0, &userData->vertices,
NULL, NULL, &userData->indices );
// Starting rotation angle for the cube
userData->angle = 45.0f;
// Clear the whole window surface.
glClearColor ( 0.0f, 0.0f, 1.0f, 0.0f );
glClear ( GL_COLOR_BUFFER_BIT );
eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
return TRUE;
}
///
// Update MVP matrix based on time
//
void Update ( ESContext *esContext, float deltaTime )
{
UserData *userData = (UserData*) esContext->userData;
ESMatrix perspective;
ESMatrix modelview;
float aspect;
// Compute a rotation angle based on time to rotate the cube
userData->angle += ( deltaTime * 40.0f );
if( userData->angle >= 360.0f )
userData->angle -= 360.0f;
// Compute the window aspect ratio
aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
// Generate a perspective matrix with a 60 degree FOV
esMatrixLoadIdentity( &perspective );
esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f );
// Generate a model view matrix to rotate/translate the cube
esMatrixLoadIdentity( &modelview );
// Translate away from the viewer
esTranslate( &modelview, 0.0, 0.0, -2.0 );
// Rotate the cube
esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 );
// Compute the final MVP by multiplying the
// modevleiw and perspective matrices together
esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );
}
///
// Draw a triangle using the shader pair created in Init()
//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
// Set the viewport
glViewport ( 0, 0, esContext->width, esContext->height );
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
// Use the program object
glUseProgram ( userData->programObject );
// Load the vertex position
glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
GL_FALSE, 3 * sizeof(GLfloat), userData->vertices );
glEnableVertexAttribArray ( userData->positionLoc );
// Load the MVP matrix
glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] );
// Draw the cube
glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_SHORT, userData->indices );
eglPostSubBufferNV ( esContext->eglDisplay, esContext->eglSurface, 60, 60, WINDOW_WIDTH - 120, WINDOW_HEIGHT - 120 );
}
///
// Cleanup
//
void ShutDown ( ESContext *esContext )
{
UserData *userData = esContext->userData;
if ( userData->vertices != NULL )
{
free ( userData->vertices );
}
if ( userData->indices != NULL )
{
free ( userData->indices );
}
// Delete program object
glDeleteProgram ( userData->programObject );
}
int main ( int argc, char *argv[] )
{
ESContext esContext;
UserData userData;
esInitContext ( &esContext );
esContext.userData = &userData;
esCreateWindow ( &esContext, TEXT("Simple Vertex Shader"), WINDOW_WIDTH, WINDOW_HEIGHT, ES_WINDOW_RGB | ES_WINDOW_POST_SUB_BUFFER_SUPPORTED );
if ( !Init ( &esContext ) )
return 0;
esRegisterDrawFunc ( &esContext, Draw );
esRegisterUpdateFunc ( &esContext, Update );
esMainLoop ( &esContext );
ShutDown ( &esContext );
}

Просмотреть файл

@ -74,6 +74,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "essl_to_hlsl", "translator\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "translator_common", "..\src\compiler\translator_common.vcproj", "{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PostSubBuffer", "gles2_book\PostSubBuffer\PostSubBuffer.vcproj", "{667CE95F-5DD8-4495-8C18-5CA8A175B12D}"
ProjectSection(ProjectDependencies) = postProject
{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -140,6 +145,10 @@ Global
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.Build.0 = Debug|Win32
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.ActiveCfg = Release|Win32
{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.Build.0 = Release|Win32
{667CE95F-5DD8-4495-8C18-5CA8A175B12D}.Debug|Win32.ActiveCfg = Debug|Win32
{667CE95F-5DD8-4495-8C18-5CA8A175B12D}.Debug|Win32.Build.0 = Debug|Win32
{667CE95F-5DD8-4495-8C18-5CA8A175B12D}.Release|Win32.ActiveCfg = Release|Win32
{667CE95F-5DD8-4495-8C18-5CA8A175B12D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -1,7 +1,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 901
#define BUILD_REVISION 924
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

Просмотреть файл

@ -333,12 +333,12 @@ void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
out << "// BEGIN: Generated code for built-in function emulation\n\n";
if (withPrecision) {
out << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
<< "#define webgl_emulation_precision highp\n"
<< "#define webgl_emu_precision highp\n"
<< "#else\n"
<< "#define webgl_emulation_precision mediump\n"
<< "#define webgl_emu_precision mediump\n"
<< "#endif\n\n";
} else {
out << "#define webgl_emulation_precision\n\n";
out << "#define webgl_emu_precision\n\n";
}
for (size_t i = 0; i < mFunctions.size(); ++i) {
out << mFunctionSource[mFunctions[i]] << "\n\n";

Просмотреть файл

@ -447,13 +447,21 @@ bool Display::createDevice()
ASSERT(SUCCEEDED(result));
}
initializeDevice();
return true;
}
// do any one-time device initialization
// NOTE: this is also needed after a device lost/reset
// to reset the scene status and ensure the default states are reset.
void Display::initializeDevice()
{
// Permanent non-default states
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
mSceneStarted = false;
return true;
}
bool Display::resetDevice()
@ -497,12 +505,16 @@ bool Display::resetDevice()
return error(EGL_BAD_ALLOC, false);
}
// reset device defaults
initializeDevice();
return true;
}
EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
{
const Config *configuration = mConfigSet.get(config);
EGLint postSubBufferSupported = EGL_FALSE;
if (attribList)
{
@ -521,6 +533,9 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
postSubBufferSupported = attribList[1];
break;
case EGL_VG_COLORSPACE:
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
case EGL_VG_ALPHA_FORMAT:
@ -544,7 +559,7 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
return EGL_NO_SURFACE;
}
Surface *surface = new Surface(this, configuration, window);
Surface *surface = new Surface(this, configuration, window, postSubBufferSupported);
if (!surface->initialize())
{
@ -1039,7 +1054,8 @@ void Display::initExtensionString()
mExtensionString += "EGL_EXT_create_context_robustness ";
// ANGLE-specific extensions
if (isd3d9ex) {
if (isd3d9ex)
{
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}
@ -1047,13 +1063,16 @@ void Display::initExtensionString()
if (swiftShader)
{
mExtensionString += "EGL_ANGLE_software_display ";
mExtensionString += "EGL_ANGLE_software_display ";
}
if (isd3d9ex) {
if (isd3d9ex)
{
mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
}
mExtensionString += "EGL_NV_post_sub_buffer";
std::string::size_type end = mExtensionString.find_last_not_of(' ');
if (end != std::string::npos)
{

Просмотреть файл

@ -122,6 +122,7 @@ class Display
bool mDeviceLost;
bool createDevice();
void initializeDevice();
bool resetDevice();
void initExtensionString();

Просмотреть файл

@ -39,8 +39,8 @@ int getComparableOSVersion()
}
}
Surface::Surface(Display *display, const Config *config, HWND window)
: mDisplay(display), mConfig(config), mWindow(window)
Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
mSwapChain = NULL;
mDepthStencil = NULL;
@ -61,7 +61,7 @@ Surface::Surface(Display *display, const Config *config, HWND window)
}
Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
: mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height)
: mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
{
mSwapChain = NULL;
mDepthStencil = NULL;
@ -174,6 +174,13 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
return false;
}
IDirect3DSurface9* preservedRenderTarget = NULL;
if (mPostSubBufferSupported && mRenderTarget)
{
preservedRenderTarget = mRenderTarget;
preservedRenderTarget->AddRef();
}
// Evict all non-render target textures to system memory and release all resources
// before reallocating them to free up as much video memory as possible.
device->EvictManagedResources();
@ -212,6 +219,12 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
useFlipEx = false;
}
// D3DSWAPEFFECT_FLIPEX does not preserve the back buffer.
if (mPostSubBufferSupported)
{
useFlipEx = false;
}
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
// We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX.
// We do this because DirectX docs are a bit vague whether to set this to 1
@ -230,7 +243,7 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
if(useFlipEx)
presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX;
else
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD;
presentParameters.Windowed = TRUE;
presentParameters.BackBufferWidth = backbufferWidth;
presentParameters.BackBufferHeight = backbufferHeight;
@ -255,6 +268,13 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release();
if (preservedRenderTarget)
{
preservedRenderTarget->Release();
preservedRenderTarget = NULL;
}
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
@ -266,6 +286,44 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
}
}
if (mWindow)
{
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
if (!preservedRenderTarget)
{
InvalidateRect(mWindow, NULL, FALSE);
}
}
else
{
mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
}
if (preservedRenderTarget)
{
RECT rect =
{
0, 0,
mWidth, mHeight
};
if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth))
{
rect.right = presentParameters.BackBufferWidth;
}
if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight))
{
rect.bottom = presentParameters.BackBufferHeight;
}
mDisplay->endScene();
device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
preservedRenderTarget->Release();
preservedRenderTarget = NULL;
}
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
{
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
@ -282,13 +340,6 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
return error(EGL_BAD_ALLOC, false);
}
if (mWindow) {
mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget);
InvalidateRect(mWindow, NULL, FALSE);
} else {
mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
}
mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight;
@ -441,6 +492,64 @@ bool Surface::swap()
return true;
}
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (x < 0 || y < 0 || width < 0 || height < 0)
{
return error(EGL_BAD_PARAMETER, false);
}
if (!mPostSubBufferSupported)
{
// Spec is not clear about how this should be handled.
return true;
}
if (mSwapChain)
{
mDisplay->endScene();
RECT rect =
{
x, mHeight - y - height,
x + width, mHeight - y
};
if (rect.right > mWidth)
{
rect.right = mWidth;
}
if (rect.bottom > mHeight)
{
rect.bottom = mHeight;
}
if (rect.left == rect.right || rect.top == rect.bottom)
{
return true;
}
HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
return error(EGL_BAD_ALLOC, false);
}
if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED)
{
return error(EGL_CONTEXT_LOST, false);
}
ASSERT(SUCCEEDED(result));
checkForOutOfDateSwapChain();
}
return true;
}
EGLint Surface::getWidth() const
{
return mWidth;
@ -451,6 +560,11 @@ EGLint Surface::getHeight() const
return mHeight;
}
EGLint Surface::isPostSubBufferSupported() const
{
return mPostSubBufferSupported;
}
IDirect3DSurface9 *Surface::getRenderTarget()
{
if (mRenderTarget)

Просмотреть файл

@ -30,7 +30,7 @@ class Config;
class Surface
{
public:
Surface(Display *display, const egl::Config *config, HWND window);
Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
~Surface();
@ -41,10 +41,13 @@ class Surface
HWND getWindowHandle();
bool swap();
bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
virtual EGLint getWidth() const;
virtual EGLint getHeight() const;
virtual EGLint isPostSubBufferSupported() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual IDirect3DTexture9 *getOffscreenTexture();
@ -96,6 +99,8 @@ private:
// EGLenum vgAlphaFormat; // Alpha format for OpenVG
// EGLenum vgColorSpace; // Color space for OpenVG
EGLint mSwapInterval;
EGLint mPostSubBufferSupported;
DWORD mPresentInterval;
bool mPresentIntervalDirty;
gl::Texture2D *mTexture;

Просмотреть файл

@ -488,6 +488,9 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
case EGL_WIDTH:
*value = eglSurface->getWidth();
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
*value = eglSurface->isPostSubBufferSupported();
break;
default:
return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}
@ -1166,6 +1169,43 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
return EGL_FALSE;
}
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
{
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
if (!validateSurface(display, eglSurface))
{
return EGL_FALSE;
}
if (display->isDeviceLost())
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE)
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (eglSurface->postSubBuffer(x, y, width, height))
{
return success(EGL_TRUE);
}
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
{
EVENT("(const char *procname = \"%s\")", procname);
@ -1181,6 +1221,7 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char
static const Extension eglExtensions[] =
{
{"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE},
{"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV},
{"", NULL},
};

Просмотреть файл

@ -1668,15 +1668,11 @@ bool Context::applyRenderTarget(bool ignoreViewport)
return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
IDirect3DSurface9 *renderTarget = NULL;
IDirect3DSurface9 *depthStencil = NULL;
bool renderTargetChanged = false;
unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
renderTarget = framebufferObject->getRenderTarget();
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
if (!renderTarget)
{
return false; // Context must be lost
@ -1685,8 +1681,10 @@ bool Context::applyRenderTarget(bool ignoreViewport)
mAppliedRenderTargetSerial = renderTargetSerial;
mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
renderTargetChanged = true;
renderTarget->Release();
}
IDirect3DSurface9 *depthStencil = NULL;
unsigned int depthbufferSerial = 0;
unsigned int stencilbufferSerial = 0;
if (framebufferObject->getDepthbufferType() != GL_NONE)
@ -1724,17 +1722,14 @@ bool Context::applyRenderTarget(bool ignoreViewport)
if (!mRenderTargetDescInitialized || renderTargetChanged)
{
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
if (!renderTarget)
{
renderTarget = framebufferObject->getRenderTarget();
if (!renderTarget)
{
return false; // Context must be lost
}
return false; // Context must be lost
}
renderTarget->GetDesc(&mRenderTargetDesc);
mRenderTargetDescInitialized = true;
renderTarget->Release();
}
D3DVIEWPORT9 viewport;
@ -2248,7 +2243,6 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
}
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
if (!renderTarget)
{
return; // Context must be lost, return silently
@ -2260,6 +2254,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
{
UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target
renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
@ -2292,6 +2287,8 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
}
result = mDevice->GetRenderTargetData(renderTarget, systemSurface);
renderTarget->Release();
renderTarget = NULL;
if (FAILED(result))
{
@ -2600,7 +2597,6 @@ void Context::clear(GLbitfield mask)
int stencil = mState.stencilClearValue & 0x000000FF;
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
if (!renderTarget)
{
return; // Context must be lost, return silently
@ -2608,6 +2604,8 @@ void Context::clear(GLbitfield mask)
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
renderTarget->Release();
renderTarget = NULL;
bool alphaUnmasked = (dx2es::GetAlphaSize(desc.Format) == 0) || mState.colorMaskAlpha;
@ -2870,6 +2868,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
// Implements glFlush when block is false, glFinish when block is true
void Context::sync(bool block)
{
egl::Display *display = getDisplay();
IDirect3DQuery9 *eventQuery = NULL;
HRESULT result;
@ -2902,6 +2901,13 @@ void Context::sync(bool block)
{
// Keep polling, but allow other threads to do something useful first
Sleep(0);
// explicitly check for device loss
// some drivers seem to return S_FALSE even if the device is lost
// instead of D3DERR_DEVICELOST like they should
if (display->testDeviceLost())
{
result = D3DERR_DEVICELOST;
}
}
}
while(block && result == S_FALSE);
@ -3791,8 +3797,14 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (blitRenderTarget)
{
HRESULT result = mDevice->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect,
drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE);
IDirect3DSurface9* readRenderTarget = readFramebuffer->getRenderTarget();
IDirect3DSurface9* drawRenderTarget = drawFramebuffer->getRenderTarget();
HRESULT result = mDevice->StretchRect(readRenderTarget, &sourceTrimmedRect,
drawRenderTarget, &destTrimmedRect, D3DTEXF_NONE);
readRenderTarget->Release();
drawRenderTarget->Release();
if (FAILED(result))
{

Просмотреть файл

@ -35,6 +35,50 @@ namespace gl
{
unsigned int TextureStorage::mCurrentTextureSerial = 1;
static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type)
{
if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
return D3DFMT_DXT1;
}
else if (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
{
return D3DFMT_DXT3;
}
else if (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
{
return D3DFMT_DXT5;
}
else if (type == GL_FLOAT)
{
return D3DFMT_A32B32G32R32F;
}
else if (type == GL_HALF_FLOAT_OES)
{
return D3DFMT_A16B16G16R16F;
}
else if (type == GL_UNSIGNED_BYTE)
{
if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
{
return D3DFMT_L8;
}
else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures())
{
return D3DFMT_A8L8;
}
else if (format == GL_RGB)
{
return D3DFMT_X8R8G8B8;
}
return D3DFMT_A8R8G8B8;
}
return D3DFMT_A8R8G8B8;
}
Image::Image()
{
mWidth = 0;
@ -45,7 +89,9 @@ Image::Image()
mSurface = NULL;
mDirty = false;
mManaged = false;
mD3DPool = D3DPOOL_SYSTEMMEM;
mD3DFormat = D3DFMT_UNKNOWN;
}
Image::~Image()
@ -68,6 +114,8 @@ bool Image::redefine(GLenum format, GLsizei width, GLsizei height, GLenum type,
mHeight = height;
mFormat = format;
mType = type;
// compute the d3d format that will be used
mD3DFormat = ConvertTextureFormatType(mFormat, mType);
if (mSurface)
{
@ -90,6 +138,7 @@ void Image::createSurface()
IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL;
const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
if (mWidth != 0 && mHeight != 0)
{
@ -114,7 +163,7 @@ void Image::createSurface()
}
HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, getD3DFormat(),
D3DPOOL_SYSTEMMEM, &newTexture, NULL);
poolToUse, &newTexture, NULL);
if (FAILED(result))
{
@ -129,6 +178,7 @@ void Image::createSurface()
mSurface = newSurface;
mDirty = false;
mD3DPool = poolToUse;
}
HRESULT Image::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
@ -181,46 +231,11 @@ bool Image::isRenderable() const
D3DFORMAT Image::getD3DFormat() const
{
if (mFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
mFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
return D3DFMT_DXT1;
}
else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
{
return D3DFMT_DXT3;
}
else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
{
return D3DFMT_DXT5;
}
else if (mType == GL_FLOAT)
{
return D3DFMT_A32B32G32R32F;
}
else if (mType == GL_HALF_FLOAT_OES)
{
return D3DFMT_A16B16G16R16F;
}
else if (mType == GL_UNSIGNED_BYTE)
{
if (mFormat == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
{
return D3DFMT_L8;
}
else if (mFormat == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures())
{
return D3DFMT_A8L8;
}
else if (mFormat == GL_RGB)
{
return D3DFMT_X8R8G8B8;
}
// this should only happen if the image hasn't been redefined first
// which would be a bug by the caller
ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
return D3DFMT_A8R8G8B8;
}
return D3DFMT_A8R8G8B8;
return mD3DFormat;
}
IDirect3DSurface9 *Image::getSurface()
@ -238,8 +253,12 @@ void Image::setManagedSurface(IDirect3DSurface9 *surface)
mSurface->Release();
}
D3DSURFACE_DESC desc;
surface->GetDesc(&desc);
ASSERT(desc.Pool == D3DPOOL_MANAGED);
mSurface = surface;
mManaged = true;
mD3DPool = desc.Pool;
}
void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
@ -250,13 +269,14 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y
{
RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight);
if (mManaged)
if (mD3DPool == D3DPOOL_MANAGED)
{
HRESULT result = D3DXLoadSurfaceFromSurface(destSurface, NULL, &rect, sourceSurface, NULL, &rect, D3DX_FILTER_BOX, 0);
ASSERT(SUCCEEDED(result));
}
else
{
// UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
POINT point = {rect.left, rect.top};
HRESULT result = getDevice()->UpdateSurface(sourceSurface, &rect, destSurface, &point);
ASSERT(SUCCEEDED(result));
@ -1249,7 +1269,9 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
}
TextureStorage::TextureStorage(bool renderable)
: mRenderable(renderable), mManaged(getDisplay()->getBufferPool(renderable) == D3DPOOL_MANAGED), mTextureSerial(issueTextureSerial())
: mRenderable(renderable),
mD3DPool(getDisplay()->getTexturePool(renderable)),
mTextureSerial(issueTextureSerial())
{
}
@ -1264,7 +1286,12 @@ bool TextureStorage::isRenderable() const
bool TextureStorage::isManaged() const
{
return mManaged;
return (mD3DPool == D3DPOOL_MANAGED);
}
D3DPOOL TextureStorage::getPool() const
{
return mD3DPool;
}
unsigned int TextureStorage::getTextureSerial() const
@ -1647,11 +1674,10 @@ TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureS
TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderable) : TextureStorage(renderable), mRenderTargetSerial(RenderbufferStorage::issueSerial())
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
IDirect3DDevice9 *device = getDevice();
mTexture = NULL;
HRESULT result = device->CreateTexture(width, height, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, display->getTexturePool(renderable), &mTexture, NULL);
HRESULT result = device->CreateTexture(width, height, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL);
if (FAILED(result))
{
@ -1662,7 +1688,10 @@ TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, int width, int
TextureStorage2D::~TextureStorage2D()
{
mTexture->Release();
if (mTexture)
{
mTexture->Release();
}
}
IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level)
@ -1690,7 +1719,7 @@ unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const
Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexture = NULL;
mTexStorage = NULL;
mSurface = NULL;
}
@ -1698,8 +1727,8 @@ Texture2D::~Texture2D()
{
mColorbufferProxy.set(NULL);
delete mTexture;
mTexture = NULL;
delete mTexStorage;
mTexStorage = NULL;
if (mSurface)
{
@ -1750,15 +1779,15 @@ void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei
bool redefined = mImageArray[level].redefine(format, width, height, type, false);
if (mTexture && redefined)
if (mTexStorage && redefined)
{
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
mImageArray[i].markDirty();
}
delete mTexture;
mTexture = NULL;
delete mTexStorage;
mTexStorage = NULL;
mDirtyImages = true;
}
}
@ -1791,8 +1820,8 @@ void Texture2D::bindTexImage(egl::Surface *surface)
mImageArray[0].redefine(format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE, true);
delete mTexture;
mTexture = new TextureStorage2D(surface->getOffscreenTexture());
delete mTexStorage;
mTexStorage = new TextureStorage2D(surface->getOffscreenTexture());
mDirtyImages = true;
mSurface = surface;
@ -1806,10 +1835,10 @@ void Texture2D::releaseTexImage()
mSurface->setBoundTexture(NULL);
mSurface = NULL;
if (mTexture)
if (mTexStorage)
{
delete mTexture;
mTexture = NULL;
delete mTexStorage;
mTexStorage = NULL;
}
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
@ -1832,7 +1861,7 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
if (level < levelCount())
{
IDirect3DSurface9 *destLevel = mTexture->getSurfaceLevel(level);
IDirect3DSurface9 *destLevel = mTexStorage->getSurfaceLevel(level);
if (destLevel)
{
@ -1880,7 +1909,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
}
else
{
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
@ -1897,7 +1926,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
GLint destYOffset = transformPixelYOffset(0, height, mImageArray[level].getHeight());
IDirect3DSurface9 *dest = mTexture->getSurfaceLevel(level);
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level);
if (dest)
{
@ -1925,14 +1954,14 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_OUT_OF_MEMORY);
}
if (!mImageArray[level].isRenderable() || (!mTexture && !isSamplerComplete()))
if (!mImageArray[level].isRenderable() || (!mTexStorage && !isSamplerComplete()))
{
mImageArray[level].copy(xoffset, yoffset, x, y, width, height, renderTarget);
mDirtyImages = true;
}
else
{
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
@ -1949,7 +1978,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[level].getHeight());
IDirect3DSurface9 *dest = mTexture->getSurfaceLevel(level);
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level);
if (dest)
{
@ -1966,9 +1995,11 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
{
GLenum format = gl::ExtractFormat(internalformat);
GLenum type = gl::ExtractType(internalformat);
D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
const bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture;
mTexture = new TextureStorage2D(levels, mImageArray[0].getD3DFormat(), width, height, mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexStorage;
mTexStorage = new TextureStorage2D(levels, d3dfmt, width, height, renderable);
mImmutable = true;
for (int level = 0; level < levels; level++)
@ -1982,6 +2013,17 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
{
mImageArray[level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true);
}
if (mTexStorage->isManaged())
{
int levels = levelCount();
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level);
mImageArray[level].setManagedSurface(surface);
}
}
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
@ -2102,7 +2144,7 @@ bool Texture2D::isCompressed() const
IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const
{
return mTexture ? mTexture->getBaseTexture() : NULL;
return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
}
// Constructs a Direct3D 9 texture resource from the texture images
@ -2112,18 +2154,18 @@ void Texture2D::createTexture()
GLsizei height = mImageArray[0].getHeight();
GLint levels = creationLevels(width, height);
D3DFORMAT format = mImageArray[0].getD3DFormat();
bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
const bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture;
mTexture = new TextureStorage2D(levels, format, width, height, renderable);
delete mTexStorage;
mTexStorage = new TextureStorage2D(levels, format, width, height, renderable);
if (mTexture->isManaged())
if (mTexStorage->isManaged())
{
int levels = levelCount();
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexture->getSurfaceLevel(level);
IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level);
mImageArray[level].setManagedSurface(surface);
}
}
@ -2148,7 +2190,7 @@ void Texture2D::updateTexture()
void Texture2D::convertToRenderTarget()
{
TextureStorage2D *newTexture = NULL;
TextureStorage2D *newTexStorage = NULL;
if (mImageArray[0].getWidth() != 0 && mImageArray[0].getHeight() != 0)
{
@ -2157,19 +2199,19 @@ void Texture2D::convertToRenderTarget()
GLint levels = creationLevels(width, height);
D3DFORMAT format = mImageArray[0].getD3DFormat();
newTexture = new TextureStorage2D(levels, format, width, height, true);
newTexStorage = new TextureStorage2D(levels, format, width, height, true);
if (mTexture != NULL)
if (mTexStorage != NULL)
{
int levels = levelCount();
for (int i = 0; i < levels; i++)
{
IDirect3DSurface9 *source = mTexture->getSurfaceLevel(i);
IDirect3DSurface9 *dest = newTexture->getSurfaceLevel(i);
IDirect3DSurface9 *source = mTexStorage->getSurfaceLevel(i);
IDirect3DSurface9 *dest = newTexStorage->getSurfaceLevel(i);
if (!copyToRenderTarget(dest, source, mTexture->isManaged()))
if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
{
delete newTexture;
delete newTexStorage;
source->Release();
dest->Release();
return error(GL_OUT_OF_MEMORY);
@ -2181,8 +2223,8 @@ void Texture2D::convertToRenderTarget()
}
}
delete mTexture;
mTexture = newTexture;
delete mTexStorage;
mTexStorage = newTexStorage;
mDirtyImages = true;
}
@ -2207,12 +2249,12 @@ void Texture2D::generateMipmaps()
mImageArray[0].getType());
}
if (mTexture && mTexture->isRenderable())
if (mTexStorage && mTexStorage->isRenderable())
{
for (unsigned int i = 1; i <= q; i++)
{
IDirect3DSurface9 *upper = mTexture->getSurfaceLevel(i - 1);
IDirect3DSurface9 *lower = mTexture->getSurfaceLevel(i);
IDirect3DSurface9 *upper = mTexStorage->getSurfaceLevel(i - 1);
IDirect3DSurface9 *lower = mTexStorage->getSurfaceLevel(i);
if (upper != NULL && lower != NULL)
{
@ -2263,33 +2305,32 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
if (mTexture == NULL)
if (mTexStorage == NULL)
{
return NULL;
}
updateTexture();
return mTexture->getSurfaceLevel(0);
return mTexStorage->getSurfaceLevel(0);
}
TextureStorage *Texture2D::getStorage() const
{
return mTexture;
return mTexStorage;
}
TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderable) : TextureStorage(renderable), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials())
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
IDirect3DDevice9 *device = getDevice();
mTexture = NULL;
HRESULT result = device->CreateCubeTexture(size, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, display->getTexturePool(renderable), &mTexture, NULL);
HRESULT result = device->CreateCubeTexture(size, levels, renderable ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL);
if (FAILED(result))
{
@ -2300,7 +2341,10 @@ TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, int s
TextureStorageCubeMap::~TextureStorageCubeMap()
{
mTexture->Release();
if (mTexture)
{
mTexture->Release();
}
}
IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level)
@ -2328,7 +2372,7 @@ unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexture = NULL;
mTexStorage = NULL;
}
TextureCubeMap::~TextureCubeMap()
@ -2338,8 +2382,8 @@ TextureCubeMap::~TextureCubeMap()
mFaceProxies[i].set(NULL);
}
delete mTexture;
mTexture = NULL;
delete mTexStorage;
mTexStorage = NULL;
}
GLenum TextureCubeMap::getTarget() const
@ -2421,7 +2465,7 @@ void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoff
if (level < levelCount())
{
IDirect3DSurface9 *destLevel = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
IDirect3DSurface9 *destLevel = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
ASSERT(destLevel != NULL);
if (destLevel != NULL)
@ -2577,7 +2621,7 @@ bool TextureCubeMap::isCompressed() const
IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const
{
return mTexture ? mTexture->getBaseTexture() : NULL;
return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
}
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
@ -2586,12 +2630,12 @@ void TextureCubeMap::createTexture()
GLsizei size = mImageArray[0][0].getWidth();
GLint levels = creationLevels(size, 0);
D3DFORMAT format = mImageArray[0][0].getD3DFormat();
bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
const bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture;
mTexture = new TextureStorageCubeMap(levels, format, size, renderable);
delete mTexStorage;
mTexStorage = new TextureStorageCubeMap(levels, format, size, renderable);
if (mTexture->isManaged())
if (mTexStorage->isManaged())
{
int levels = levelCount();
@ -2599,12 +2643,12 @@ void TextureCubeMap::createTexture()
{
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
mImageArray[face][level].setManagedSurface(surface);
}
}
}
mDirtyImages = true;
}
@ -2627,7 +2671,7 @@ void TextureCubeMap::updateTexture()
void TextureCubeMap::convertToRenderTarget()
{
TextureStorageCubeMap *newTexture = NULL;
TextureStorageCubeMap *newTexStorage = NULL;
if (mImageArray[0][0].getWidth() != 0)
{
@ -2635,9 +2679,9 @@ void TextureCubeMap::convertToRenderTarget()
GLint levels = creationLevels(size, 0);
D3DFORMAT format = mImageArray[0][0].getD3DFormat();
newTexture = new TextureStorageCubeMap(levels, format, size, true);
newTexStorage = new TextureStorageCubeMap(levels, format, size, true);
if (mTexture != NULL)
if (mTexStorage != NULL)
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
@ -2647,12 +2691,12 @@ void TextureCubeMap::convertToRenderTarget()
{
for (int i = 0; i < levels; i++)
{
IDirect3DSurface9 *source = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *dest = newTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *source = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *dest = newTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
if (!copyToRenderTarget(dest, source, mTexture->isManaged()))
if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
{
delete newTexture;
delete newTexStorage;
source->Release();
dest->Release();
return error(GL_OUT_OF_MEMORY);
@ -2665,8 +2709,8 @@ void TextureCubeMap::convertToRenderTarget()
}
}
delete mTexture;
mTexture = newTexture;
delete mTexStorage;
mTexStorage = newTexStorage;
mDirtyImages = true;
}
@ -2693,7 +2737,7 @@ void TextureCubeMap::redefineImage(int face, GLint level, GLenum format, GLsizei
{
bool redefined = mImageArray[face][level].redefine(format, width, height, type, false);
if (mTexture && redefined)
if (mTexStorage && redefined)
{
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
@ -2703,8 +2747,8 @@ void TextureCubeMap::redefineImage(int face, GLint level, GLenum format, GLsizei
}
}
delete mTexture;
mTexture = NULL;
delete mTexStorage;
mTexStorage = NULL;
mDirtyImages = true;
}
@ -2730,7 +2774,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
}
else
{
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
@ -2749,7 +2793,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
GLint destYOffset = transformPixelYOffset(0, height, mImageArray[faceindex][level].getWidth());
IDirect3DSurface9 *dest = mTexture->getCubeMapSurface(target, level);
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level);
if (dest)
{
@ -2781,14 +2825,14 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
unsigned int faceindex = faceIndex(target);
if (!mImageArray[faceindex][level].isRenderable() || (!mTexture && !isSamplerComplete()))
if (!mImageArray[faceindex][level].isRenderable() || (!mTexStorage && !isSamplerComplete()))
{
mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget);
mDirtyImages = true;
}
else
{
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
@ -2805,7 +2849,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[faceindex][level].getWidth());
IDirect3DSurface9 *dest = mTexture->getCubeMapSurface(target, level);
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level);
if (dest)
{
@ -2822,12 +2866,14 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
{
GLenum format = gl::ExtractFormat(internalformat);
GLenum type = gl::ExtractType(internalformat);
D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
const bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture;
mTexture = new TextureStorageCubeMap(levels, mImageArray[0][0].getD3DFormat(), size, mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexStorage;
mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, size, renderable);
mImmutable = true;
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
for (int level = 0; level < levels; level++)
{
for (int face = 0; face < 6; face++)
{
@ -2843,6 +2889,20 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
mImageArray[face][level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true);
}
}
if (mTexStorage->isManaged())
{
int levels = levelCount();
for (int face = 0; face < 6; face++)
{
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
mImageArray[face][level].setManagedSurface(surface);
}
}
}
}
void TextureCubeMap::generateMipmaps()
@ -2873,14 +2933,14 @@ void TextureCubeMap::generateMipmaps()
}
}
if (mTexture && mTexture->isRenderable())
if (mTexStorage && mTexStorage->isRenderable())
{
for (unsigned int f = 0; f < 6; f++)
{
for (unsigned int i = 1; i <= q; i++)
{
IDirect3DSurface9 *upper = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i-1);
IDirect3DSurface9 *lower = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *upper = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i-1);
IDirect3DSurface9 *lower = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
if (upper != NULL && lower != NULL)
{
@ -2937,24 +2997,24 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
{
ASSERT(IsCubemapTextureTarget(target));
if (!mTexture || !mTexture->isRenderable())
if (!mTexStorage || !mTexStorage->isRenderable())
{
convertToRenderTarget();
}
if (mTexture == NULL)
if (mTexStorage == NULL)
{
return NULL;
}
updateTexture();
return mTexture->getCubeMapSurface(target, 0);
return mTexStorage->getCubeMapSurface(target, 0);
}
TextureStorage *TextureCubeMap::getStorage() const
{
return mTexture;
return mTexStorage;
}
}

Просмотреть файл

@ -134,7 +134,9 @@ class Image
GLenum mType;
bool mDirty;
bool mManaged;
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
D3DFORMAT mD3DFormat;
IDirect3DSurface9 *mSurface;
};
@ -148,6 +150,7 @@ class TextureStorage
bool isRenderable() const;
bool isManaged() const;
D3DPOOL getPool() const;
unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
@ -155,7 +158,7 @@ class TextureStorage
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
const bool mRenderable;
const bool mManaged;
const D3DPOOL mD3DPool;
const unsigned int mTextureSerial;
static unsigned int issueTextureSerial();
@ -317,7 +320,7 @@ class Texture2D : public Texture
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorage2D *mTexture;
TextureStorage2D *mTexStorage;
egl::Surface *mSurface;
BindingPointer<Renderbuffer> mColorbufferProxy;
@ -400,7 +403,7 @@ class TextureCubeMap : public Texture
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
TextureStorageCubeMap *mTexture;
TextureStorageCubeMap *mTexStorage;
BindingPointer<Renderbuffer> mFaceProxies[6];
};

Просмотреть файл

@ -2707,10 +2707,7 @@ GLenum __stdcall glGetError(void)
if (context)
{
if (context->isContextLost())
return GL_OUT_OF_MEMORY;
else
return context->getError();
return context->getError();
}
return GL_NO_ERROR;

Просмотреть файл

@ -98,9 +98,18 @@ Context *getNonLostContext()
{
Context *context = getContext();
if (context && !context->isContextLost())
return context;
if (context)
{
if (context->isContextLost())
{
error(GL_OUT_OF_MEMORY);
return NULL;
}
else
{
return context;
}
}
return NULL;
}

Просмотреть файл

@ -112,8 +112,9 @@ VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
outp.vPosition.y = position.y + aVertex.vPosition.y * size.y;
outp.vPosition = mul(mLayerTransform, outp.vPosition);
outp.vPosition = outp.vPosition / outp.vPosition.w;
outp.vPosition.xyz /= outp.vPosition.w;
outp.vPosition = outp.vPosition - vRenderTargetOffset;
outp.vPosition.xyz *= outp.vPosition.w;
outp.vPosition = mul(mProjection, outp.vPosition);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -35,15 +35,17 @@
mad r0, c2, v0.z, r0
mad r0, c3, v0.w, r0
rcp r1.x, r0.w
mad r0, r0, r1.x, -c8
add r0.xy, r0, c11.x
mul r0.xyz, r0, r1.x
add r0, r0, -c8
mad r0.xy, r0, r0.w, c11.x
mul r1, r0.y, c5
mad r1, c4, r0.x, r1
mad r1, c6, r0.z, r1
mul r0.x, r0.w, r0.z
mad r1, c6, r0.x, r1
mad oPos, c7, r0.w, r1
mad oT0.xy, v0, c9.zwzw, c9
// approximately 13 instruction slots used
// approximately 15 instruction slots used
#endif
const BYTE LayerQuadVS[] =
@ -125,29 +127,35 @@ const BYTE LayerQuadVS[] =
0, 0, 255, 144, 0, 0,
228, 128, 6, 0, 0, 2,
1, 0, 1, 128, 0, 0,
255, 128, 4, 0, 0, 4,
0, 0, 15, 128, 0, 0,
255, 128, 5, 0, 0, 3,
0, 0, 7, 128, 0, 0,
228, 128, 1, 0, 0, 128,
8, 0, 228, 161, 2, 0,
0, 3, 0, 0, 3, 128,
0, 0, 228, 128, 11, 0,
0, 160, 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, 192,
7, 0, 228, 160, 0, 0,
255, 128, 1, 0, 228, 128,
2, 0, 0, 3, 0, 0,
15, 128, 0, 0, 228, 128,
8, 0, 228, 161, 4, 0,
0, 4, 0, 0, 3, 128,
0, 0, 228, 128, 0, 0,
255, 128, 11, 0, 0, 160,
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,
5, 0, 0, 3, 0, 0,
1, 128, 0, 0, 255, 128,
0, 0, 170, 128, 4, 0,
0, 4, 1, 0, 15, 128,
6, 0, 228, 160, 0, 0,
0, 128, 1, 0, 228, 128,
4, 0, 0, 4, 0, 0,
3, 224, 0, 0, 228, 144,
9, 0, 238, 160, 9, 0,
228, 160, 255, 255, 0, 0
15, 192, 7, 0, 228, 160,
0, 0, 255, 128, 1, 0,
228, 128, 4, 0, 0, 4,
0, 0, 3, 224, 0, 0,
228, 144, 9, 0, 238, 160,
9, 0, 228, 160, 255, 255,
0, 0
};
#if 0
//

Просмотреть файл

@ -42,8 +42,9 @@ VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
outp.vPosition.y = position.y + outp.vPosition.y * size.y;
outp.vPosition = mul(mLayerTransform, outp.vPosition);
outp.vPosition = outp.vPosition / outp.vPosition.w;
outp.vPosition.xyz /= outp.vPosition.w;
outp.vPosition = outp.vPosition - vRenderTargetOffset;
outp.vPosition.xyz *= outp.vPosition.w;
// adjust our vertices to match d3d9's pixel coordinate system
// which has pixel centers at integer locations

Просмотреть файл

@ -112,8 +112,9 @@ void main()
vec4 finalPosition = aVertexCoord;
finalPosition = uLayerQuadTransform * finalPosition;
finalPosition = uLayerTransform * finalPosition;
finalPosition = finalPosition / finalPosition.w;
finalPosition.xyz /= finalPosition.w;
finalPosition = finalPosition - uRenderTargetOffset;
finalPosition.xyz *= finalPosition.w;
finalPosition = uMatrixProj * finalPosition;
vTexCoord = aTexCoord;

Просмотреть файл

@ -5,6 +5,26 @@
#ifndef OPENTYPE_SANITISER_H_
#define OPENTYPE_SANITISER_H_
#if defined(_WIN32) || defined(__CYGWIN__)
#define OTS_DLL_IMPORT __declspec(dllimport)
#define OTS_DLL_EXPORT __declspec(dllexport)
#else
#if __GNUC__ >= 4
#define OTS_DLL_IMPORT __attribute__((visibility ("default")))
#define OTS_DLL_EXPORT __attribute__((visibility ("default")))
#endif
#endif
#ifdef OTS_DLL
#ifdef OTS_DLL_EXPORTS
#define OTS_API OTS_DLL_EXPORT
#else
#define OTS_API OTS_DLL_IMPORT
#endif
#else
#define OTS_API
#endif
#if defined(_WIN32)
typedef signed char int8_t;
typedef unsigned char uint8_t;
@ -183,8 +203,8 @@ class OTSStream {
// length: the size, in bytes, of |input|
// preserve_graphite_tables: whether to preserve Graphite Layout tables
// -----------------------------------------------------------------------------
bool Process(OTSStream *output, const uint8_t *input, size_t length,
bool preserve_graphite_tables = false);
bool OTS_API Process(OTSStream *output, const uint8_t *input, size_t length,
bool preserve_graphite_tables = false);
// Force to disable debug output even when the library is compiled with
// -DOTS_DEBUG.

Просмотреть файл

@ -34,7 +34,13 @@ include $(DEPTH)/config/autoconf.mk
MODULE = ots
LIBRARY_NAME = mozots
FORCE_STATIC_LIB = 1
ifeq (WINNT,$(OS_TARGET))
VISIBILITY_FLAGS =
else
LIBXUL_LIBRARY = 1
endif
CSRCS = \
$(NULL)
@ -77,17 +83,18 @@ EXPORTS = \
../include/ots-memory-stream.h \
$(NULL)
LOCAL_INCLUDES += -I$(srcdir)
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
DEFINES += -DPACKAGE_VERSION="\"moz\""
DEFINES += -DPACKAGE_BUGREPORT="\"http://bugzilla.mozilla.org/\""
DEFINES += -DNOMINMAX
ifeq (WINNT,$(OS_TARGET))
DEFINES += -DOTS_DLL -DOTS_DLL_EXPORTS
endif
# Suppress ANSI strict warnings
# because Googlers don't care about comma-at-end-of-enumerator errors.
CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
CFLAGS := $(filter-out -pedantic,$(CFLAGS))

Просмотреть файл

@ -379,6 +379,10 @@ CSRCS += woff.c
DEFINES += -DIMPL_THEBES -DWOFF_MOZILLA_CLIENT
ifeq (WINNT,$(OS_TARGET))
DEFINES += -DOTS_DLL
endif
include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk

Просмотреть файл

@ -4509,10 +4509,10 @@ gfxTextRun::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
GlyphStorageAllocCount(mCharacterCount, mFlags));
if (mDetailedGlyphs) {
total += mDetailedGlyphs->SizeOf();
total += mDetailedGlyphs->SizeOfIncludingThis(aMallocSizeOf);
}
total += mGlyphRuns.SizeOf();
total += mGlyphRuns.SizeOfExcludingThis(aMallocSizeOf);
return total;
}

Просмотреть файл

@ -2273,9 +2273,10 @@ private:
return details;
}
PRUint32 SizeOf() {
return sizeof(DetailedGlyphStore) +
mDetails.SizeOf() + mOffsetToIndex.SizeOf();
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) {
return aMallocSizeOf(this, sizeof(DetailedGlyphStore)) +
mDetails.SizeOfExcludingThis(aMallocSizeOf) +
mOffsetToIndex.SizeOfExcludingThis(aMallocSizeOf);
}
private:

Просмотреть файл

@ -220,8 +220,9 @@ protected:
PRUint32 aEnd, PRUint32 aHash);
void Uninit();
static PLDHashOperator MaybeSizeOfEntry(CacheHashEntry *aEntry,
void *aUserData);
static size_t MaybeSizeOfEntryExcludingThis(CacheHashEntry *aEntry,
nsMallocSizeOfFun aMallocSizeOf,
void *aUserData);
static PLDHashOperator ResetSizeOfEntryAccountingFlags(CacheHashEntry *aEntry,
void *aUserData);
@ -915,22 +916,16 @@ TextRunWordCache::RemoveTextRun(gfxTextRun *aTextRun)
#endif
}
struct SizeOfEntryData {
nsMallocSizeOfFun mMallocSizeOf;
size_t mTotal;
SizeOfEntryData(nsMallocSizeOfFun mallocSizeOf)
: mMallocSizeOf(mallocSizeOf), mTotal(0) { }
};
/*static*/ PLDHashOperator
TextRunWordCache::MaybeSizeOfEntry(CacheHashEntry *aEntry, void *aUserData)
/*static*/ size_t
TextRunWordCache::MaybeSizeOfEntryExcludingThis(CacheHashEntry *aEntry,
nsMallocSizeOfFun aMallocSizeOf,
void *)
{
gfxTextRun *run = aEntry->mTextRun;
if (run) {
SizeOfEntryData *data = static_cast<SizeOfEntryData*>(aUserData);
data->mTotal += run->MaybeSizeOfIncludingThis(data->mMallocSizeOf);
return run->MaybeSizeOfIncludingThis(aMallocSizeOf);
}
return PL_DHASH_NEXT;
return 0;
}
/*static*/ PLDHashOperator
@ -946,11 +941,7 @@ TextRunWordCache::ResetSizeOfEntryAccountingFlags(CacheHashEntry *aEntry, void *
size_t
TextRunWordCache::MaybeSizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
{
size_t total = mCache.ShallowSizeOfExcludingThis(aMallocSizeOf);
SizeOfEntryData data(aMallocSizeOf);
mCache.EnumerateEntries(MaybeSizeOfEntry, &data);
total += data.mTotal;
return total;
return mCache.SizeOfExcludingThis(MaybeSizeOfEntryExcludingThis, aMallocSizeOf);
}
void

Просмотреть файл

@ -223,9 +223,15 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
: ((double)status.BatteryLifePercent) / 100.0;
aBatteryInfo->charging() = (status.ACLineStatus != 0);
if (status.ACLineStatus != 0) {
aBatteryInfo->remainingTime() =
status.BatteryFullLifeTime == (DWORD)-1 ? kUnknownRemainingTime
: status.BatteryFullLifeTime;
if (aBatteryInfo->level() == 1.0) {
// GetSystemPowerStatus API may returns -1 for BatteryFullLifeTime.
// So, if battery is 100%, set kDefaultRemainingTime at force.
aBatteryInfo->remainingTime() = kDefaultRemainingTime;
} else {
aBatteryInfo->remainingTime() =
status.BatteryFullLifeTime == (DWORD)-1 ? kUnknownRemainingTime
: status.BatteryFullLifeTime;
}
} else {
aBatteryInfo->remainingTime() =
status.BatteryLifeTime == (DWORD)-1 ? kUnknownRemainingTime

Просмотреть файл

@ -2,7 +2,7 @@ Hyphen - hyphenation library to use converted TeX hyphenation patterns
(C) 1998 Raph Levien
(C) 2001 ALTLinux, Moscow
(C) 2006, 2007, 2008, 2010 László Németh
(C) 2006, 2007, 2008, 2010, 2011 László Németh
This was part of libHnj library by Raph Levien.
@ -124,4 +124,4 @@ is released in binary form as jar files and in source form as zip files.
See http://sourceforge.net/project/showfiles.php?group_id=119136
László Németh
<nemeth (at) openoffice (dot) org>
<nemeth (at) numbertext (dot) org>

Просмотреть файл

@ -18,6 +18,16 @@ Description:
and NOHYPHEN with the comma separated character (or character sequence)
list forbid the (extra) hyphens at the hyphen and apostrophe characters.
Implicite NOHYPHEN declaration
Without explicite NEXTLEVEL declaration, Hyphen 2.8 uses the
previous settings, plus in UTF-8 encoding, endash (U+2013) and
typographical apostrophe (U+2019) are NOHYPHEN characters, too.
It's possible to enlarge the hyphenation distance from these
NOHYPHEN characters by using COMPOUNDLEFTHYPHENMIN and
COMPOUNDRIGHTHYPHENMIN attributes.
Compound word hyphenation
Hyphen library supports better compound word hyphenation and special

Просмотреть файл

@ -226,118 +226,61 @@ hnj_add_trans (HyphenDict *dict, int state1, int state2, char ch)
}
#ifdef VERBOSE
HashTab *global;
HashTab *global[1];
static char *
get_state_str (int state)
get_state_str (int state, int level)
{
int i;
HashEntry *e;
for (i = 0; i < HASH_SIZE; i++)
for (e = global->entries[i]; e; e = e->next)
for (e = global[level]->entries[i]; e; e = e->next)
if (e->val == state)
return e->key;
return NULL;
}
#endif
HyphenDict *
hnj_hyphen_load (const char *fn)
{
HyphenDict *dict[2];
HashTab *hashtab;
FILE *f;
char buf[MAX_CHARS];
void hnj_hyphen_load_line(char * buf, HyphenDict * dict, HashTab * hashtab) {
int i, j;
char word[MAX_CHARS];
char pattern[MAX_CHARS];
char * repl;
signed char replindex;
signed char replcut;
int state_num = 0, last_state;
int i, j, k;
int state_num = 0;
int last_state;
char ch;
int found;
HashEntry *e;
int nextlevel = 0;
f = fopen (fn, "r");
if (f == NULL)
return NULL;
// loading one or two dictionaries (separated by NEXTLEVEL keyword)
for (k = 0; k == 0 || (k == 1 && nextlevel); k++) {
hashtab = hnj_hash_new ();
#ifdef VERBOSE
global = hashtab;
#endif
hnj_hash_insert (hashtab, "", 0);
dict[k] = hnj_malloc (sizeof(HyphenDict));
dict[k]->num_states = 1;
dict[k]->states = hnj_malloc (sizeof(HyphenState));
dict[k]->states[0].match = NULL;
dict[k]->states[0].repl = NULL;
dict[k]->states[0].fallback_state = -1;
dict[k]->states[0].num_trans = 0;
dict[k]->states[0].trans = NULL;
dict[k]->nextlevel = NULL;
dict[k]->lhmin = 0;
dict[k]->rhmin = 0;
dict[k]->clhmin = 0;
dict[k]->crhmin = 0;
dict[k]->nohyphen = NULL;
dict[k]->nohyphenl = 0;
/* read in character set info */
if (k == 0) {
for (i=0;i<MAX_NAME;i++) dict[k]->cset[i]= 0;
if (fgets(dict[k]->cset, sizeof(dict[k]->cset),f) != NULL) {
for (i=0;i<MAX_NAME;i++)
if ((dict[k]->cset[i] == '\r') || (dict[k]->cset[i] == '\n'))
dict[k]->cset[i] = 0;
} else {
dict[k]->cset[0] = 0;
}
dict[k]->utf8 = (strcmp(dict[k]->cset, "UTF-8") == 0);
} else {
strcpy(dict[k]->cset, dict[0]->cset);
dict[k]->utf8 = dict[0]->utf8;
}
while (fgets (buf, sizeof(buf), f) != NULL)
{
if (buf[0] != '%')
{
if (strncmp(buf, "NEXTLEVEL", 9) == 0) {
nextlevel = 1;
break;
} else if (strncmp(buf, "LEFTHYPHENMIN", 13) == 0) {
dict[k]->lhmin = atoi(buf + 13);
continue;
if (strncmp(buf, "LEFTHYPHENMIN", 13) == 0) {
dict->lhmin = atoi(buf + 13);
return;
} else if (strncmp(buf, "RIGHTHYPHENMIN", 14) == 0) {
dict[k]->rhmin = atoi(buf + 14);
continue;
dict->rhmin = atoi(buf + 14);
return;
} else if (strncmp(buf, "COMPOUNDLEFTHYPHENMIN", 21) == 0) {
dict[k]->clhmin = atoi(buf + 21);
continue;
dict->clhmin = atoi(buf + 21);
return;
} else if (strncmp(buf, "COMPOUNDRIGHTHYPHENMIN", 22) == 0) {
dict[k]->crhmin = atoi(buf + 22);
continue;
dict->crhmin = atoi(buf + 22);
return;
} else if (strncmp(buf, "NOHYPHEN", 8) == 0) {
char * space = buf + 8;
while (*space != '\0' && (*space == ' ' || *space == '\t')) space++;
if (*buf != '\0') dict[k]->nohyphen = hnj_strdup(space);
if (dict[k]->nohyphen) {
char * nhe = dict[k]->nohyphen + strlen(dict[k]->nohyphen) - 1;
if (*buf != '\0') dict->nohyphen = hnj_strdup(space);
if (dict->nohyphen) {
char * nhe = dict->nohyphen + strlen(dict->nohyphen) - 1;
*nhe = 0;
for (nhe = nhe - 1; nhe > dict[k]->nohyphen; nhe--) {
for (nhe = nhe - 1; nhe > dict->nohyphen; nhe--) {
if (*nhe == ',') {
dict[k]->nohyphenl++;
dict->nohyphenl++;
*nhe = 0;
}
}
}
continue;
return;
}
j = 0;
pattern[j] = '0';
@ -382,7 +325,7 @@ for (k = 0; k == 0 || (k == 1 && nextlevel); k++) {
} else {
if (*word == '.') i++;
/* convert UTF-8 char. positions of discretionary hyph. replacements to 8-bit */
if (dict[k]->utf8) {
if (dict->utf8) {
int pu = -1; /* unicode character position */
int ps = -1; /* unicode start position (original replindex) */
int pc = (*word == '.') ? 1: 0; /* 8-bit character position */
@ -406,14 +349,14 @@ for (k = 0; k == 0 || (k == 1 && nextlevel); k++) {
printf ("word %s pattern %s, j = %d repl: %s\n", word, pattern + i, j, repl);
#endif
found = hnj_hash_lookup (hashtab, word);
state_num = hnj_get_state (dict[k], hashtab, word);
dict[k]->states[state_num].match = hnj_strdup (pattern + i);
dict[k]->states[state_num].repl = repl;
dict[k]->states[state_num].replindex = replindex;
state_num = hnj_get_state (dict, hashtab, word);
dict->states[state_num].match = hnj_strdup (pattern + i);
dict->states[state_num].repl = repl;
dict->states[state_num].replindex = replindex;
if (!replcut) {
dict[k]->states[state_num].replcut = (signed char) strlen(word);
dict->states[state_num].replcut = (signed char) strlen(word);
} else {
dict[k]->states[state_num].replcut = replcut;
dict->states[state_num].replcut = replcut;
}
/* now, put in the prefix transitions */
@ -423,11 +366,85 @@ for (k = 0; k == 0 || (k == 1 && nextlevel); k++) {
ch = word[j - 1];
word[j - 1] = '\0';
found = hnj_hash_lookup (hashtab, word);
state_num = hnj_get_state (dict[k], hashtab, word);
hnj_add_trans (dict[k], state_num, last_state, ch);
state_num = hnj_get_state (dict, hashtab, word);
hnj_add_trans (dict, state_num, last_state, ch);
}
}
}
HyphenDict *
hnj_hyphen_load (const char *fn)
{
HyphenDict *dict[2];
HashTab *hashtab;
FILE *f;
char buf[MAX_CHARS];
int nextlevel = 0;
int i, j, k;
HashEntry *e;
int state_num = 0;
f = fopen (fn, "r");
if (f == NULL)
return NULL;
// loading one or two dictionaries (separated by NEXTLEVEL keyword)
for (k = 0; k < 2; k++) {
hashtab = hnj_hash_new ();
#ifdef VERBOSE
global[k] = hashtab;
#endif
hnj_hash_insert (hashtab, "", 0);
dict[k] = hnj_malloc (sizeof(HyphenDict));
dict[k]->num_states = 1;
dict[k]->states = hnj_malloc (sizeof(HyphenState));
dict[k]->states[0].match = NULL;
dict[k]->states[0].repl = NULL;
dict[k]->states[0].fallback_state = -1;
dict[k]->states[0].num_trans = 0;
dict[k]->states[0].trans = NULL;
dict[k]->nextlevel = NULL;
dict[k]->lhmin = 0;
dict[k]->rhmin = 0;
dict[k]->clhmin = 0;
dict[k]->crhmin = 0;
dict[k]->nohyphen = NULL;
dict[k]->nohyphenl = 0;
/* read in character set info */
if (k == 0) {
for (i=0;i<MAX_NAME;i++) dict[k]->cset[i]= 0;
if (fgets(dict[k]->cset, sizeof(dict[k]->cset),f) != NULL) {
for (i=0;i<MAX_NAME;i++)
if ((dict[k]->cset[i] == '\r') || (dict[k]->cset[i] == '\n'))
dict[k]->cset[i] = 0;
} else {
dict[k]->cset[0] = 0;
}
dict[k]->utf8 = (strcmp(dict[k]->cset, "UTF-8") == 0);
} else {
strcpy(dict[k]->cset, dict[0]->cset);
dict[k]->utf8 = dict[0]->utf8;
}
if (k == 0 || nextlevel) {
while (fgets (buf, sizeof(buf), f) != NULL) {
if (strncmp(buf, "NEXTLEVEL", 9) == 0) {
nextlevel = 1;
break;
} else if (buf[0] != '%') hnj_hyphen_load_line(buf, dict[k], hashtab);
}
} else if (k == 1) {
/* default first level: hyphen and ASCII apostrophe */
if (!dict[0]->utf8) hnj_hyphen_load_line("NOHYPHEN '\n", dict[k], hashtab);
else hnj_hyphen_load_line("NOHYPHEN ',\xe2\x80\x93,\xe2\x80\x99\n", dict[k], hashtab);
strcpy(buf, "1-1/=,1,1\n"); // buf rewritten by hnj_hyphen_load here
hnj_hyphen_load_line(buf, dict[k], hashtab); /* remove hyphen */
hnj_hyphen_load_line("1'1\n", dict[k], hashtab); /* ASCII apostrophe */
if (dict[0]->utf8) {
hnj_hyphen_load_line("1\xe2\x80\x93" "1\n", dict[k], hashtab); /* endash */
hnj_hyphen_load_line("1\xe2\x80\x99" "1\n", dict[k], hashtab); /* apostrophe */
}
}
/* Could do unioning of matches here (instead of the preprocessor script).
If we did, the pseudocode would look something like this:
@ -479,7 +496,20 @@ for (k = 0; k == 0 || (k == 1 && nextlevel); k++) {
state_num = 0;
}
fclose(f);
if (k == 2) dict[0]->nextlevel = dict[1];
if (nextlevel) dict[0]->nextlevel = dict[1];
else {
dict[1] -> nextlevel = dict[0];
dict[1]->lhmin = dict[0]->lhmin;
dict[1]->rhmin = dict[0]->rhmin;
dict[1]->clhmin = (dict[0]->clhmin) ? dict[0]->clhmin : ((dict[0]->lhmin) ? dict[0]->lhmin : 3);
dict[1]->crhmin = (dict[0]->crhmin) ? dict[0]->crhmin : ((dict[0]->rhmin) ? dict[0]->rhmin : 3);
#ifdef VERBOSE
HashTab *r = global[0];
global[0] = global[1];
global[1] = r;
#endif
return dict[1];
}
return dict[0];
}
@ -530,8 +560,13 @@ int hnj_hyphen_hyphenate (HyphenDict *dict,
j = 0;
prep_word[j++] = '.';
for (i = 0; i < word_size; i++)
for (i = 0; i < word_size; i++) {
if (word[i] <= '9' && word[i] >= '0') {
prep_word[j++] = '.';
} else {
prep_word[j++] = word[i];
}
}
prep_word[j++] = '.';
prep_word[j] = '\0';
@ -560,7 +595,7 @@ int hnj_hyphen_hyphenate (HyphenDict *dict,
#ifdef VERBOSE
char *state_str;
state_str = get_state_str (state);
state_str = get_state_str (state, 0);
for (k = 0; k < i - strlen (state_str); k++)
putchar (' ');
@ -673,6 +708,9 @@ int hnj_hyphen_lhmin(int utf8, const char *word, int word_size, char * hyphens,
i += hnj_ligature(word[2]);
}
// ignore numbers
for (j = 0; word[j] <= '9' && word[j] >= '0'; j++) i--;
for (j = 0; i < lhmin && word[j] != '\0'; i++) do {
// check length of the non-standard part
if (*rep && *pos && *cut && (*rep)[j]) {
@ -699,9 +737,13 @@ int hnj_hyphen_lhmin(int utf8, const char *word, int word_size, char * hyphens,
int hnj_hyphen_rhmin(int utf8, const char *word, int word_size, char * hyphens,
char *** rep, int ** pos, int ** cut, int rhmin)
{
int i;
int j = word_size - 2;
for (i = 1; i < rhmin && j > 0; j--) {
int i = 1;
int j;
// ignore numbers
for (j = word_size - 1; j > 0 && word[j] <= '9' && word[j] >= '0'; j--) i--;
for (j = word_size - 2; i < rhmin && j > 0; j--) {
// check length of the non-standard part
if (*rep && *pos && *cut && (*rep)[j]) {
char * rh = strchr((*rep)[j], '=');
@ -759,8 +801,15 @@ int hnj_hyphen_hyph_(HyphenDict *dict, const char *word, int word_size,
j = 0;
prep_word[j++] = '.';
for (i = 0; i < word_size; i++)
for (i = 0; i < word_size; i++) {
if (word[i] <= '9' && word[i] >= '0') {
prep_word[j++] = '.';
} else {
prep_word[j++] = word[i];
}
}
prep_word[j++] = '.';
prep_word[j] = '\0';
@ -789,7 +838,7 @@ int hnj_hyphen_hyph_(HyphenDict *dict, const char *word, int word_size,
#ifdef VERBOSE
char *state_str;
state_str = get_state_str (state);
state_str = get_state_str (state, 1);
for (k = 0; k < i - strlen (state_str); k++)
putchar (' ');
@ -1036,6 +1085,9 @@ int hnj_hyphen_norm(const char *word, int word_size, char * hyphens,
}
}
hyphens[j + 1] = '\0';
#ifdef VERBOSE
printf ("nums: %s\n", hyphens);
#endif
return 0;
}
@ -1077,8 +1129,8 @@ int hnj_hyphen_hyphenate2 (HyphenDict *dict,
for (nhi = 0; nhi <= dict->nohyphenl; nhi++) {
char * nhy = (char *) strstr(word, nh);
while (nhy) {
hyphens[nhy - word + strlen(nh) - 1] = 0;
if (nhy - word - 1 >= 0) hyphens[nhy - word - 1] = 0;
hyphens[nhy - word + strlen(nh) - 1] = '0';
if (nhy - word - 1 >= 0) hyphens[nhy - word - 1] = '0';
nhy = (char *) strstr(nhy + 1, nh);
}
nh = nh + strlen(nh) + 1;
@ -1087,6 +1139,9 @@ int hnj_hyphen_hyphenate2 (HyphenDict *dict,
if (hyphword) hnj_hyphen_hyphword(word, word_size, hyphens, hyphword, rep, pos, cut);
if (dict->utf8) return hnj_hyphen_norm(word, word_size, hyphens, rep, pos, cut);
#ifdef VERBOSE
printf ("nums: %s\n", hyphens);
#endif
return 0;
}
@ -1096,8 +1151,10 @@ int hnj_hyphen_hyphenate3 (HyphenDict *dict,
char *hyphword, char *** rep, int ** pos, int ** cut,
int lhmin, int rhmin, int clhmin, int crhmin)
{
lhmin = (lhmin > 0 ? lhmin : dict->lhmin);
rhmin = (rhmin > 0 ? rhmin : dict->rhmin);
lhmin = (lhmin > dict->lhmin) ? lhmin : dict->lhmin;
rhmin = (rhmin > dict->rhmin) ? rhmin : dict->rhmin;
clhmin = (clhmin > dict->clhmin) ? clhmin : dict->clhmin;
crhmin = (crhmin > dict->crhmin) ? crhmin : dict->crhmin;
hnj_hyphen_hyph_(dict, word, word_size, hyphens, rep, pos, cut,
clhmin, crhmin, 1, 1);
hnj_hyphen_lhmin(dict->utf8, word, word_size, hyphens,

Просмотреть файл

@ -1,13 +1,6 @@
UTF-8
LEFTHYPHENMIN 2
RIGHTHYPHENMIN 3
COMPOUNDLEFTHYPHENMIN 2
COMPOUNDRIGHTHYPHENMIN 3
NOHYPHEN -,',
1-1
1'1
11
NEXTLEVEL
.a2ch4
.ad4der
.a2d

Просмотреть файл

@ -302,7 +302,7 @@ nsPropertyEnumeratorByURL::HasMoreElements(bool * aResult)
}
if (!hasMore)
mCurrent = false;
mCurrent = nsnull;
*aResult = mCurrent ? true : false;

Просмотреть файл

@ -65,7 +65,7 @@ enum ProcessArchitecture {
PROCESS_ARCH_ARM = 0x8
};
static ProcessArchitecture GetCurrentProcessArchitecture()
static inline ProcessArchitecture GetCurrentProcessArchitecture()
{
base::ProcessArchitecture currentArchitecture;
#if defined(ARCH_CPU_X86)

Просмотреть файл

@ -41,8 +41,7 @@
#ifndef js_template_lib_h__
#define js_template_lib_h__
#include "mozilla/Types.h"
#include "jsstdint.h"
#include "jstypes.h"
/*
* Library of reusable template meta-functions (that is, functions on types and

Просмотреть файл

@ -43,7 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include "mozilla/Util.h"
#include "jstypes.h"
#ifdef __cplusplus

Просмотреть файл

@ -275,24 +275,10 @@ EXPORTS_js = \
$(NULL)
###############################################
# BEGIN include sources for low-level code shared with Gecko
# BEGIN include sources for low-level code shared with mfbt
#
VPATH += \
$(srcdir)/../../mfbt \
$(NULL)
EXPORTS_NAMESPACES += mozilla
EXPORTS_mozilla = \
Attributes.h \
GuardObjects.h \
MSStdInt.h \
RangedPtr.h \
RefPtr.h \
StdInt.h \
Types.h \
Util.h \
$(NULL)
VPATH += $(srcdir)/../../mfbt
include $(srcdir)/../../mfbt/exported_headers.mk
ifdef ENABLE_METHODJIT

Просмотреть файл

@ -173,7 +173,7 @@ MOZ_ARG_WITH_STRING(dist-dir,
TOP_DIST=dist)
AC_SUBST(TOP_DIST)
dnl Default to MSVC for win32 and gcc-4.2 for darwin
dnl Default to MSVC for win32
dnl ==============================================================
if test -z "$CROSS_COMPILE"; then
case "$target" in
@ -196,8 +196,9 @@ case "$target" in
if test -z "$MIDL"; then MIDL=midl; fi
;;
*-darwin*)
if test -z "$CC"; then CC=gcc-4.2; fi
if test -z "$CXX"; then CXX=g++-4.2; fi
# prefer gcc-4.2 to default cc on older xcode
MOZ_PATH_PROGS(CC, $CC gcc-4.2 gcc)
MOZ_PATH_PROGS(CXX, $CXX g++-4.2 g++)
;;
esac
fi
@ -3865,13 +3866,6 @@ AC_CACHE_CHECK(for __attribute__((warn_unused_result)),
ac_cv_attribute_warn_unused=yes,
ac_cv_attribute_warn_unused=no)])
AC_CACHE_CHECK(for __attribute__((noreturn)),
ac_cv_attribute_noreturn,
[AC_TRY_COMPILE([void f(void) __attribute__((noreturn));],
[],
ac_cv_attribute_noreturn=yes,
ac_cv_attribute_noreturn=no)])
dnl End of C++ language/feature checks
AC_LANG_C
@ -3927,12 +3921,6 @@ else
AC_DEFINE(NS_WARN_UNUSED_RESULT,)
fi
if test "$ac_cv_attribute_noreturn" = yes ; then
AC_DEFINE(NS_NORETURN, [__attribute__((noreturn))])
else
AC_DEFINE(NS_NORETURN,)
fi
dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
dnl features that Windows actually does support.

Просмотреть файл

@ -785,47 +785,51 @@ JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg)
return i;
}
struct SizeOfEntryEnumeratorArg
struct SizeOfEntryExcludingThisArg
{
size_t total;
JSDHashSizeOfEntryFun sizeOfEntry;
JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis;
JSMallocSizeOfFun mallocSizeOf;
void *arg; // the arg passed by the user
};
static JSDHashOperator
SizeOfEntryEnumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number,
void *arg)
SizeOfEntryExcludingThisEnumerator(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32_t number, void *arg)
{
SizeOfEntryEnumeratorArg *e = (SizeOfEntryEnumeratorArg *)arg;
e->total += e->sizeOfEntry(hdr, e->mallocSizeOf);
SizeOfEntryExcludingThisArg *e = (SizeOfEntryExcludingThisArg *)arg;
e->total += e->sizeOfEntryExcludingThis(hdr, e->mallocSizeOf, e->arg);
return JS_DHASH_NEXT;
}
extern JS_PUBLIC_API(size_t)
JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table,
JSDHashSizeOfEntryFun sizeOfEntry,
JSMallocSizeOfFun mallocSizeOf)
JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
JSMallocSizeOfFun mallocSizeOf,
void *arg /* = NULL */)
{
size_t n = 0;
n += mallocSizeOf(table->entryStore,
JS_DHASH_TABLE_SIZE(table) * table->entrySize +
ENTRY_STORE_EXTRA);
if (sizeOfEntry) {
SizeOfEntryEnumeratorArg arg = { 0, sizeOfEntry, mallocSizeOf };
if (sizeOfEntryExcludingThis) {
SizeOfEntryExcludingThisArg arg2 = { 0, sizeOfEntryExcludingThis, mallocSizeOf, arg };
JS_DHashTableEnumerate(const_cast<JSDHashTable *>(table),
SizeOfEntryEnumerator, &arg);
n += arg.total;
SizeOfEntryExcludingThisEnumerator, &arg2);
n += arg2.total;
}
return n;
}
extern JS_PUBLIC_API(size_t)
JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table,
JSDHashSizeOfEntryFun sizeOfEntry,
JSMallocSizeOfFun mallocSizeOf)
JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
JSMallocSizeOfFun mallocSizeOf,
void *arg /* = NULL */)
{
return mallocSizeOf(table, sizeof(JSDHashTable)) +
JS_DHashTableSizeOfExcludingThis(table, sizeOfEntry, mallocSizeOf);
JS_DHashTableSizeOfExcludingThis(table, sizeOfEntryExcludingThis,
mallocSizeOf, arg);
}
#ifdef DEBUG

Просмотреть файл

@ -580,26 +580,30 @@ extern JS_PUBLIC_API(uint32_t)
JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg);
typedef size_t
(* JSDHashSizeOfEntryFun)(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
(* JSDHashSizeOfEntryExcludingThisFun)(JSDHashEntryHdr *hdr,
JSMallocSizeOfFun mallocSizeOf,
void *arg);
/**
* Measure the size of the table's entry storage, and if |sizeOfEntry| is
* non-NULL, measure the size of things pointed to by entries. Doesn't measure
* |ops| because it's often shared between tables, nor |data| because it's
* opaque.
* Measure the size of the table's entry storage, and if
* |sizeOfEntryExcludingThis| is non-NULL, measure the size of things pointed
* to by entries. Doesn't measure |ops| because it's often shared between
* tables, nor |data| because it's opaque.
*/
extern JS_PUBLIC_API(size_t)
JS_DHashTableSizeOfExcludingThis(const JSDHashTable *table,
JSDHashSizeOfEntryFun sizeOfEntry,
JSMallocSizeOfFun mallocSizeOf);
JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
JSMallocSizeOfFun mallocSizeOf,
void *arg = NULL);
/**
* Like JS_DHashTableSizeOfExcludingThis, but includes sizeof(*this).
*/
extern JS_PUBLIC_API(size_t)
JS_DHashTableSizeOfIncludingThis(const JSDHashTable *table,
JSDHashSizeOfEntryFun sizeOfEntry,
JSMallocSizeOfFun mallocSizeOf);
JSDHashSizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
JSMallocSizeOfFun mallocSizeOf,
void *arg = NULL);
#ifdef DEBUG
/**

Просмотреть файл

@ -537,7 +537,7 @@ ChunkPool::expire(JSRuntime *rt, bool releaseAll)
}
JS_FRIEND_API(int64_t)
ChunkPool::countDecommittedArenas(JSRuntime *rt)
ChunkPool::countCleanDecommittedArenas(JSRuntime *rt)
{
JS_ASSERT(this == &rt->gcChunkPool);

Просмотреть файл

@ -786,7 +786,7 @@ class ChunkPool {
void expire(JSRuntime *rt, bool releaseAll);
/* Must be called either during the GC or with the GC lock taken. */
JS_FRIEND_API(int64_t) countDecommittedArenas(JSRuntime *rt);
JS_FRIEND_API(int64_t) countCleanDecommittedArenas(JSRuntime *rt);
};
inline uintptr_t

Просмотреть файл

@ -54,9 +54,8 @@
#ifndef jstypes_h___
#define jstypes_h___
#include "mozilla/StdInt.h"
#include "mozilla/Util.h"
#include <stddef.h>
#include "js-config.h"
/***********************************************************************
@ -80,63 +79,11 @@
**
***********************************************************************/
#define DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION(Name) class Name
#if defined(WIN32) || defined(XP_OS2)
/* These also work for __MWERKS__ */
# define JS_EXTERN_API(__type) extern __declspec(dllexport) __type
# define JS_EXPORT_API(__type) __declspec(dllexport) __type
# define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
# define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
#else /* Unix */
# ifdef HAVE_VISIBILITY_ATTRIBUTE
# define JS_EXTERNAL_VIS __attribute__((visibility ("default")))
# if defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ < 5
/*
* GCC wrongly produces a warning when a type with hidden visibility
* (e.g. js::Value) is a member of a local class of a static function.
* This is apparently fixed with GCC 4.5 and above. See:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40145.
*/
# undef DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION
# define DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION(Name) class __attribute__((visibility ("hidden"))) Name
# endif
# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# define JS_EXTERNAL_VIS __global
# else
# define JS_EXTERNAL_VIS
# endif
# define JS_EXTERN_API(__type) extern JS_EXTERNAL_VIS __type
# define JS_EXPORT_API(__type) JS_EXTERNAL_VIS __type
# define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type
# define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type
#endif
#ifdef _WIN32
# if defined(__MWERKS__) || defined(__GNUC__)
# define JS_IMPORT_API(__x) __x
# else
# define JS_IMPORT_API(__x) __declspec(dllimport) __x
# endif
#elif defined(XP_OS2)
# define JS_IMPORT_API(__x) __declspec(dllimport) __x
#else
# define JS_IMPORT_API(__x) JS_EXPORT_API (__x)
#endif
#if defined(_WIN32) && !defined(__MWERKS__)
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
#elif defined(XP_OS2)
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
#else
# define JS_IMPORT_DATA(__x) JS_EXPORT_DATA (__x)
#endif
#define JS_EXTERN_API(type) extern MOZ_EXPORT_API(type)
#define JS_EXPORT_API(type) MOZ_EXPORT_API(type)
#define JS_EXPORT_DATA(type) MOZ_EXPORT_DATA(type)
#define JS_IMPORT_API(type) MOZ_IMPORT_API(type)
#define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA(type)
/*
* The linkage of JS API functions differs depending on whether the file is
@ -145,20 +92,14 @@
* should not. STATIC_JS_API is used to build JS as a static library.
*/
#if defined(STATIC_JS_API)
# define JS_PUBLIC_API(t) t
# define JS_PUBLIC_DATA(t) t
# define JS_PUBLIC_API(t) t
# define JS_PUBLIC_DATA(t) t
#elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API)
# define JS_PUBLIC_API(t) JS_EXPORT_API(t)
# define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
# define JS_PUBLIC_API(t) MOZ_EXPORT_API(t)
# define JS_PUBLIC_DATA(t) MOZ_EXPORT_DATA(t)
#else
# define JS_PUBLIC_API(t) JS_IMPORT_API(t)
# define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
# define JS_PUBLIC_API(t) MOZ_IMPORT_API(t)
# define JS_PUBLIC_DATA(t) MOZ_IMPORT_DATA(t)
#endif
#define JS_FRIEND_API(t) JS_PUBLIC_API(t)
@ -258,17 +199,8 @@
** DESCRIPTION:
** Macro shorthands for conditional C++ extern block delimiters.
***********************************************************************/
#ifdef __cplusplus
# define JS_BEGIN_EXTERN_C extern "C" {
# define JS_END_EXTERN_C }
#else
# define JS_BEGIN_EXTERN_C
# define JS_END_EXTERN_C
#endif
#define JS_BEGIN_EXTERN_C MOZ_BEGIN_EXTERN_C
#define JS_END_EXTERN_C MOZ_END_EXTERN_C
/***********************************************************************
** MACROS: JS_BIT

Просмотреть файл

@ -38,9 +38,10 @@
*
* ***** END LICENSE BLOCK ***** */
/*
* PR assertion checker.
*/
/* Various JS utility functions. */
#include "mozilla/Attributes.h"
#include <stdio.h>
#include <stdlib.h>
#include "jstypes.h"
@ -53,6 +54,8 @@
# include <signal.h>
#endif
#include "js/TemplateLib.h"
using namespace js;
#ifdef DEBUG
@ -96,7 +99,16 @@ CrashInJS()
#endif
}
JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
/*
* |JS_Assert| historically took |JSIntn ln| as its last argument. We've
* boiled |JSIntn ln| down to simply |int ln| so that mfbt may declare the
* function without depending on the |JSIntn| typedef, so we must manually
* verify that the |JSIntn| typedef is consistent.
*/
JS_STATIC_ASSERT((tl::IsSameType<JSIntn, int>::result));
JS_PUBLIC_API(void)
JS_Assert(const char *s, const char *file, int ln)
{
fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
fflush(stderr);

Просмотреть файл

@ -231,8 +231,8 @@ my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
#ifdef EDITLINE
JS_BEGIN_EXTERN_C
JS_EXTERN_API(char) *readline(const char *prompt);
JS_EXTERN_API(void) add_history(char *line);
extern JS_EXPORT_API(char *) readline(const char *prompt);
extern JS_EXPORT_API(void) add_history(char *line);
JS_END_EXTERN_C
#endif

Просмотреть файл

@ -246,7 +246,7 @@ GetLocationProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
#ifdef EDITLINE
extern "C" {
extern JS_EXPORT_API(char) *readline(const char *prompt);
extern JS_EXPORT_API(char *) readline(const char *prompt);
extern JS_EXPORT_API(void) add_history(char *line);
}
#endif

Просмотреть файл

@ -1265,6 +1265,8 @@ CompartmentCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
void
ChunkCallback(JSContext *cx, void *vdata, js::gc::Chunk *chunk)
{
// Nb: This function is only called for dirty chunks, which is why we
// increment gcHeapChunkDirtyDecommitted.
IterateData *data = static_cast<IterateData *>(vdata);
for (uint32 i = 0; i < js::gc::ArenasPerChunk; i++)
if (chunk->decommittedArenas.get(i))
@ -1395,6 +1397,29 @@ ReportMemoryBytes0(const nsCString &path, PRInt32 kind, PRInt64 amount,
ReportMemoryBytes(path, kind, amount, desc, callback, closure);
}
template <int N>
inline void
ReportGCHeapBytes(const nsACString &path, PRInt64 *total, PRInt64 amount,
const char (&desc)[N],
nsIMemoryMultiReporterCallback *callback,
nsISupports *closure)
{
ReportMemory(path, nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount,
desc, callback, closure);
*total += amount;
}
template <int N>
inline void
ReportGCHeapBytes0(const nsCString &path, PRInt64 *total, PRInt64 amount,
const char (&desc)[N],
nsIMemoryMultiReporterCallback *callback,
nsISupports *closure)
{
if (amount)
return ReportGCHeapBytes(path, total, amount, desc, callback, closure);
}
template <int N>
inline void
ReportMemoryPercentage(const nsACString &path, PRInt32 kind, PRInt64 amount,
@ -1418,8 +1443,6 @@ MakeMemoryReporterPath(const nsACString &pathPrefix,
} // anonymous namespace
#define JS_GC_HEAP_KIND nsIMemoryReporter::KIND_NONHEAP
// We have per-compartment GC heap totals, so we can't put the total GC heap
// size in the explicit allocations tree. But it's a useful figure, so put it
// in the "others" list.
@ -1548,7 +1571,7 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
data->compartmentStatsVector.SetCapacity(rt->compartments.length());
data->gcHeapChunkCleanDecommitted =
rt->gcChunkPool.countDecommittedArenas(rt) *
rt->gcChunkPool.countCleanDecommittedArenas(rt) *
js::gc::ArenaSize;
data->gcHeapChunkCleanUnused =
PRInt64(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) *
@ -1629,6 +1652,7 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
stats.gcHeapStrings +
stats.gcHeapShapesTree +
stats.gcHeapShapesDict +
stats.gcHeapShapesBase +
stats.gcHeapScripts +
stats.gcHeapTypeObjects +
stats.gcHeapXML;
@ -1683,51 +1707,53 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
#define SLOP_BYTES_STRING \
" The measurement includes slop bytes caused by the heap allocator rounding up request sizes."
static void
static PRInt64
ReportCompartmentStats(const CompartmentStats &stats,
const nsACString &pathPrefix,
nsIMemoryMultiReporterCallback *callback,
nsISupports *closure)
{
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
PRInt64 gcTotal = 0;
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/arena/headers"),
JS_GC_HEAP_KIND, stats.gcHeapArenaHeaders,
&gcTotal, stats.gcHeapArenaHeaders,
"Memory on the compartment's garbage-collected JavaScript heap, within "
"arenas, that is used to hold internal book-keeping information.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/arena/padding"),
JS_GC_HEAP_KIND, stats.gcHeapArenaPadding,
&gcTotal, stats.gcHeapArenaPadding,
"Memory on the compartment's garbage-collected JavaScript heap, within "
"arenas, that is unused and present only so that other data is aligned. "
"This constitutes internal fragmentation.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/arena/unused"),
JS_GC_HEAP_KIND, stats.gcHeapArenaUnused,
&gcTotal, stats.gcHeapArenaUnused,
"Memory on the compartment's garbage-collected JavaScript heap, within "
"arenas, that could be holding useful data but currently isn't.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/objects/non-function"),
JS_GC_HEAP_KIND, stats.gcHeapObjectsNonFunction,
&gcTotal, stats.gcHeapObjectsNonFunction,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"non-function objects.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/objects/function"),
JS_GC_HEAP_KIND, stats.gcHeapObjectsFunction,
&gcTotal, stats.gcHeapObjectsFunction,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"function objects.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/strings"),
JS_GC_HEAP_KIND, stats.gcHeapStrings,
&gcTotal, stats.gcHeapStrings,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"string headers. String headers contain various pieces of information "
"about a string, but do not contain (except in the case of very short "
@ -1735,45 +1761,45 @@ ReportCompartmentStats(const CompartmentStats &stats,
"under 'gc-heap/string-chars' instead.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/scripts"),
JS_GC_HEAP_KIND, stats.gcHeapScripts,
&gcTotal, stats.gcHeapScripts,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"JSScript instances. A JSScript is created for each user-defined function "
"in a script. One is also created for the top-level code in a script.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/shapes/tree"),
JS_GC_HEAP_KIND, stats.gcHeapShapesTree,
&gcTotal, stats.gcHeapShapesTree,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"shapes that are in a property tree.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/shapes/dict"),
JS_GC_HEAP_KIND, stats.gcHeapShapesDict,
&gcTotal, stats.gcHeapShapesDict,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"shapes that are in dictionary mode.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/shapes/base"),
JS_GC_HEAP_KIND, stats.gcHeapShapesBase,
&gcTotal, stats.gcHeapShapesBase,
"Memory on the compartment's garbage-collected JavaScript heap that collates "
"data common to many shapes.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/type-objects"),
JS_GC_HEAP_KIND, stats.gcHeapTypeObjects,
&gcTotal, stats.gcHeapTypeObjects,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"type inference information.",
callback, closure);
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"gc-heap/xml"),
JS_GC_HEAP_KIND, stats.gcHeapXML,
&gcTotal, stats.gcHeapXML,
"Memory on the compartment's garbage-collected JavaScript heap that holds "
"E4X XML objects.",
callback, closure);
@ -1858,7 +1884,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
"type-inference/object-main"),
JS_GC_HEAP_KIND,
nsIMemoryReporter::KIND_HEAP,
stats.typeInferenceMemory.objects,
"Memory used during type inference to store types and possible "
"property types of JS objects.",
@ -1878,6 +1904,8 @@ ReportCompartmentStats(const CompartmentStats &stats,
"Memory used during type inference and compilation to hold transient "
"analysis information. Cleared on GC.",
callback, closure);
return gcTotal;
}
void
@ -1885,11 +1913,12 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix,
nsIMemoryMultiReporterCallback *callback,
nsISupports *closure)
{
PRInt64 gcTotal = 0;
for (PRUint32 index = 0;
index < data.compartmentStatsVector.Length();
index++) {
ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix,
callback, closure);
gcTotal += ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix,
callback, closure);
}
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
@ -1939,39 +1968,42 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix,
"Memory used by XPConnect." SLOP_BYTES_STRING,
callback, closure);
ReportMemoryBytes(pathPrefix +
ReportGCHeapBytes(pathPrefix +
NS_LITERAL_CSTRING("gc-heap-chunk-dirty-unused"),
JS_GC_HEAP_KIND, data.gcHeapChunkDirtyUnused,
&gcTotal, data.gcHeapChunkDirtyUnused,
"Memory on the garbage-collected JavaScript heap, within chunks with at "
"least one allocated GC thing, that could be holding useful data but "
"currently isn't. Memory here is mutually exclusive with memory reported"
"under gc-heap-decommitted.",
callback, closure);
ReportMemoryBytes(pathPrefix +
ReportGCHeapBytes(pathPrefix +
NS_LITERAL_CSTRING("gc-heap-chunk-clean-unused"),
JS_GC_HEAP_KIND, data.gcHeapChunkCleanUnused,
&gcTotal, data.gcHeapChunkCleanUnused,
"Memory on the garbage-collected JavaScript heap taken by completely empty "
"chunks, that soon will be released unless claimed for new allocations. "
"Memory here is mutually exclusive with memory reported under "
"gc-heap-decommitted.",
callback, closure);
ReportMemoryBytes(pathPrefix +
ReportGCHeapBytes(pathPrefix +
NS_LITERAL_CSTRING("gc-heap-decommitted"),
JS_GC_HEAP_KIND,
&gcTotal,
data.gcHeapChunkCleanDecommitted + data.gcHeapChunkDirtyDecommitted,
"Memory in the address space of the garbage-collected JavaScript heap that "
"is currently returned to the OS.",
callback, closure);
ReportMemoryBytes(pathPrefix +
ReportGCHeapBytes(pathPrefix +
NS_LITERAL_CSTRING("gc-heap-chunk-admin"),
JS_GC_HEAP_KIND, data.gcHeapChunkAdmin,
&gcTotal, data.gcHeapChunkAdmin,
"Memory on the garbage-collected JavaScript heap, within chunks, that is "
"used to hold internal book-keeping information.",
callback, closure);
// gcTotal is the sum of everything we've reported for the GC heap. It
// should equal data.gcHeapChunkTotal.
JS_ASSERT(gcTotal == data.gcHeapChunkTotal);
}
} // namespace memory

Просмотреть файл

@ -140,12 +140,13 @@ JSObject2WrappedJSMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
{
size_t n = 0;
n += mallocSizeOf(this, sizeof(JSObject2WrappedJSMap));
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntry, mallocSizeOf) : 0;
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
return n;
}
/* static */ size_t
JSObject2WrappedJSMap::SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf)
JSObject2WrappedJSMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
JSMallocSizeOfFun mallocSizeOf, void *)
{
return mallocSizeOf(((JSObject2WrappedJSMap::Entry*)hdr)->value,
sizeof(nsXPCWrappedJS));
@ -182,12 +183,13 @@ Native2WrappedNativeMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
{
size_t n = 0;
n += mallocSizeOf(this, sizeof(Native2WrappedNativeMap));
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntry, mallocSizeOf) : 0;
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
return n;
}
/* static */ size_t
Native2WrappedNativeMap::SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf)
Native2WrappedNativeMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
JSMallocSizeOfFun mallocSizeOf, void *)
{
return mallocSizeOf(((Native2WrappedNativeMap::Entry*)hdr)->value,
sizeof(XPCWrappedNative));
@ -271,12 +273,13 @@ IID2NativeInterfaceMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
{
size_t n = 0;
n += mallocSizeOf(this, sizeof(IID2NativeInterfaceMap));
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntry, mallocSizeOf) : 0;
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
return n;
}
/* static */ size_t
IID2NativeInterfaceMap::SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf)
IID2NativeInterfaceMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
JSMallocSizeOfFun mallocSizeOf, void *)
{
XPCNativeInterface *iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value;
return iface->SizeOfIncludingThis(mallocSizeOf);
@ -349,12 +352,13 @@ ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSiz
{
size_t n = 0;
n += mallocSizeOf(this, sizeof(ClassInfo2WrappedNativeProtoMap));
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntry, mallocSizeOf) : 0;
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
return n;
}
/* static */ size_t
ClassInfo2WrappedNativeProtoMap::SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf)
ClassInfo2WrappedNativeProtoMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr,
JSMallocSizeOfFun mallocSizeOf, void *)
{
return mallocSizeOf(((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value,
sizeof(XPCWrappedNativeProto));
@ -473,12 +477,12 @@ NativeSetMap::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
{
size_t n = 0;
n += mallocSizeOf(this, sizeof(NativeSetMap));
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntry, mallocSizeOf) : 0;
n += mTable ? JS_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0;
return n;
}
/* static */ size_t
NativeSetMap::SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf)
NativeSetMap::SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *)
{
XPCNativeSet *set = ((NativeSetMap::Entry*)hdr)->key_value;
return set->SizeOfIncludingThis(mallocSizeOf);

Просмотреть файл

@ -109,7 +109,7 @@ private:
JSObject2WrappedJSMap(); // no implementation
JSObject2WrappedJSMap(int size);
static size_t SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
static size_t SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *);
private:
JSDHashTable *mTable;
@ -177,7 +177,7 @@ private:
Native2WrappedNativeMap(); // no implementation
Native2WrappedNativeMap(int size);
static size_t SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
static size_t SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *);
private:
JSDHashTable *mTable;
@ -296,7 +296,7 @@ private:
IID2NativeInterfaceMap(); // no implementation
IID2NativeInterfaceMap(int size);
static size_t SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
static size_t SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *);
private:
JSDHashTable *mTable;
@ -415,7 +415,7 @@ private:
ClassInfo2WrappedNativeProtoMap(); // no implementation
ClassInfo2WrappedNativeProtoMap(int size);
static size_t SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
static size_t SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *);
private:
JSDHashTable *mTable;
@ -488,7 +488,7 @@ private:
NativeSetMap(); // no implementation
NativeSetMap(int size);
static size_t SizeOfEntry(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf);
static size_t SizeOfEntryExcludingThis(JSDHashEntryHdr *hdr, JSMallocSizeOfFun mallocSizeOf, void *);
private:
JSDHashTable *mTable;

Просмотреть файл

@ -187,7 +187,7 @@ GeneratePropertyOp(JSContext *cx, JSObject *obj, jsid id, uintN argc, Op pop)
JSFunction *fun =
js::NewFunctionByIdWithReserved(cx, PropertyOpForwarder<Op>, argc, 0, obj, id);
if (!fun)
return false;
return nsnull;
JSObject *funobj = JS_GetFunctionObject(fun);
@ -197,10 +197,10 @@ GeneratePropertyOp(JSContext *cx, JSObject *obj, jsid id, uintN argc, Op pop)
// second object to work around this.
JSObject *ptrobj = JS_NewObject(cx, &PointerHolderClass, nsnull, funobj);
if (!ptrobj)
return false;
return nsnull;
Op *popp = new Op;
if (!popp)
return false;
return nsnull;
*popp = pop;
JS_SetPrivate(cx, ptrobj, popp);

Просмотреть файл

@ -40,6 +40,8 @@
#ifndef __CrossOriginWrapper_h__
#define __CrossOriginWrapper_h__
#include "mozilla/Attributes.h"
#include "jsapi.h"
#include "jswrapper.h"
@ -50,8 +52,8 @@ class NoWaiverWrapper : public js::CrossCompartmentWrapper {
NoWaiverWrapper(uintN flags);
virtual ~NoWaiverWrapper();
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp);
virtual void leave(JSContext *cx, JSObject *wrapper);
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp) MOZ_OVERRIDE;
virtual void leave(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
static NoWaiverWrapper singleton;
};
@ -62,15 +64,15 @@ class CrossOriginWrapper : public NoWaiverWrapper {
virtual ~CrossOriginWrapper();
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
bool set, js::PropertyDescriptor *desc);
bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
bool set, js::PropertyDescriptor *desc);
bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id,
js::Value *vp);
js::Value *vp) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp);
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JSObject *wrapper,
uintN argc, js::Value *argv, js::Value *rval);
uintN argc, js::Value *argv, js::Value *rval) MOZ_OVERRIDE;
static CrossOriginWrapper singleton;
};

Просмотреть файл

@ -1377,10 +1377,11 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
// Assign the item to a layer
if (layerState == LAYER_ACTIVE_FORCE ||
layerState == LAYER_ACTIVE_EMPTY ||
layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
// We can use the visible rect here only because the item has its own
// layer, like the comment below.
!aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect()))) {
(layerState == LAYER_ACTIVE &&
(aClip.mRoundedClipRects.IsEmpty() ||
// We can use the visible rect here only because the item has its own
// layer, like the comment below.
!aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect())))) {
// LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
// We should never see an empty layer with any visible content!

Просмотреть файл

@ -2567,6 +2567,15 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
(newOrigin + toMozOrigin, result);
}
bool
nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
return aFrame->AreLayersMarkedActive(nsChangeHint_UpdateTransformLayer) &&
aFrame->GetVisualOverflowRectRelativeToSelf().Size() <=
aBuilder->ReferenceFrame()->GetSize();
}
/* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix)
{
@ -2644,7 +2653,8 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
* think that it's painting in its original rectangular coordinate space.
* If we can't untransform, take the entire overflow rect */
nsRect untransformedVisibleRect;
if (!UntransformRect(mVisibleRect,
if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
!UntransformRect(mVisibleRect,
mFrame,
aBuilder->ToReferenceFrame(mFrame),
&untransformedVisibleRect))

Просмотреть файл

@ -2210,6 +2210,12 @@ public:
float aFactor,
const nsRect* aBoundsOverride = nsnull,
nsIFrame** aOutAncestor = nsnull);
/**
* Return true when we should try to prerender the entire contents of the
* transformed frame even when it's not completely visible (yet).
*/
static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
private:
nsDisplayWrapList mStoredList;

Просмотреть файл

@ -4111,11 +4111,8 @@ nsLayoutUtils::SurfaceFromElement(dom::Element* aElement,
result.mSurface = gfxsurf;
result.mSize = gfxIntSize(imgWidth, imgHeight);
result.mPrincipal = principal.forget();
// SVG images could have <foreignObject> and/or <image> elements that load
// content from another domain. For safety, they make the canvas write-only.
// XXXdholbert We could probably be more permissive here if we check that our
// helper SVG document has no elements that could load remote content.
result.mIsWriteOnly = (imgContainer->GetType() == imgIContainer::TYPE_VECTOR);
// no images, including SVG images, can load content from another domain.
result.mIsWriteOnly = false;
result.mImageRequest = imgRequest.forget();
return result;

Просмотреть файл

@ -44,6 +44,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_CHROME_FILES = \
paint_listener.js \
test_bug370436.html \
test_bug396367-1.html \
test_bug396367-2.html \
@ -62,10 +63,11 @@ _CHROME_FILES = \
chrome_over_plugin_window.xul \
test_default_background.xul \
default_background_window.xul \
test_leaf_layers_partition_browser_window.xul \
test_no_clip_iframe.xul \
no_clip_iframe_window.xul \
no_clip_iframe_subdoc.html \
test_leaf_layers_partition_browser_window.xul \
test_no_clip_iframe.xul \
no_clip_iframe_window.xul \
no_clip_iframe_subdoc.html \
test_prerendered_transforms.html \
test_printpreview.xul \
printpreview_helper.xul \
test_printpreview_bug396024.xul \

Просмотреть файл

@ -8,6 +8,7 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript"
src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="text/javascript" src="paint_listener.js"></script>
<div id="container" xmlns="http://www.w3.org/1999/xhtml" style="height:400px; overflow:auto; background:gray">
<div style="height:0">
@ -33,50 +34,6 @@
SimpleTest.waitForExplicitFinish();
var accumulatedRect = null;
var onpaint = function() {};
function paintListener(event) {
if (event.target != window)
return;
dump("got MozAfterPaint: " + event.boundingClientRect.left + "," + event.boundingClientRect.top + "," +
event.boundingClientRect.right + "," + event.boundingClientRect.bottom + "\n");
if (accumulatedRect) {
accumulatedRect[0] = Math.min(accumulatedRect[0], event.boundingClientRect.left);
accumulatedRect[1] = Math.min(accumulatedRect[1], event.boundingClientRect.top);
accumulatedRect[2] = Math.max(accumulatedRect[2], event.boundingClientRect.right);
accumulatedRect[3] = Math.max(accumulatedRect[3], event.boundingClientRect.bottom);
} else {
accumulatedRect = [event.boundingClientRect.left, event.boundingClientRect.top,
event.boundingClientRect.right, event.boundingClientRect.bottom];
}
onpaint();
}
window.addEventListener("MozAfterPaint", paintListener, false);
function waitForAllPaintsFlushed(callback, subdoc) {
document.documentElement.getBoundingClientRect();
if (subdoc) {
subdoc.documentElement.getBoundingClientRect();
}
var CI = Components.interfaces;
var utils = window.QueryInterface(CI.nsIInterfaceRequestor)
.getInterface(CI.nsIDOMWindowUtils);
if (!utils.isMozAfterPaintPending) {
dump("done...\n");
var result = accumulatedRect;
accumulatedRect = null;
onpaint = function() {};
if (!result) {
result = [0,0,0,0];
}
callback(result[0], result[1], result[2], result[3]);
return;
}
dump("waiting for paint...\n");
onpaint = function() { waitForAllPaintsFlushed(callback); };
}
var Ci = Components.interfaces;
var frame = document.getElementById("f");
var fl = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
@ -118,7 +75,6 @@
ref.style.visibility = "hidden";
document.getElementById("container").style.height = "400px";
waitForAllPaintsFlushed(function() {
dump("Scrolling\n");
frame.contentWindow.scrollTo(0,80);
waitForAllPaintsFlushed(function(x1, y1, x2, y2) {
ok(x1 <= 1 && x2 >= 151 && y1 <= 0 && y2 >= 400,

Просмотреть файл

@ -0,0 +1,50 @@
var accumulatedRect = null;
var onpaint = function() {};
var debug = false;
function paintListener(event) {
if (event.target != window)
return;
if (debug) {
dump("got MozAfterPaint: " + event.boundingClientRect.left + "," + event.boundingClientRect.top + "," +
event.boundingClientRect.right + "," + event.boundingClientRect.bottom + "\n");
}
if (accumulatedRect) {
accumulatedRect[0] = Math.min(accumulatedRect[0], event.boundingClientRect.left);
accumulatedRect[1] = Math.min(accumulatedRect[1], event.boundingClientRect.top);
accumulatedRect[2] = Math.max(accumulatedRect[2], event.boundingClientRect.right);
accumulatedRect[3] = Math.max(accumulatedRect[3], event.boundingClientRect.bottom);
} else {
accumulatedRect = [event.boundingClientRect.left, event.boundingClientRect.top,
event.boundingClientRect.right, event.boundingClientRect.bottom];
}
onpaint();
}
window.addEventListener("MozAfterPaint", paintListener, false);
function waitForAllPaintsFlushed(callback, subdoc) {
document.documentElement.getBoundingClientRect();
if (subdoc) {
subdoc.documentElement.getBoundingClientRect();
}
var CI = Components.interfaces;
var utils = window.QueryInterface(CI.nsIInterfaceRequestor)
.getInterface(CI.nsIDOMWindowUtils);
if (!utils.isMozAfterPaintPending) {
if (debug) {
dump("done...\n");
}
var result = accumulatedRect;
accumulatedRect = null;
onpaint = function() {};
if (!result) {
result = [0,0,0,0];
}
callback(result[0], result[1], result[2], result[3]);
return;
}
if (debug) {
dump("waiting for paint...\n");
}
onpaint = function() { waitForAllPaintsFlushed(callback, subdoc); };
}

Просмотреть файл

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that active transformed elements coming into view are prerendered so we don't have to redraw constantly</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="paint_listener.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body onload="startTest()">
<div>
<div id="t" style="position:absolute; left:0; top:500px; -moz-transform: translatex(-100px); width:200px; height:100px; background:yellow;">
<div style="text-align:right">Hello</div>
<div style="text-align:left">Kitty</div>
</div>
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var t = document.getElementById("t");
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
function startTest() {
// Do a couple of transform changes to ensure we've triggered activity heuristics
waitForAllPaintsFlushed(function () {
t.style.MozTransform = "translatex(-75px)";
waitForAllPaintsFlushed(function () {
t.style.MozTransform = "translatex(-50px)";
waitForAllPaintsFlushed(function () {
// Clear paint state now and move again.
utils.checkAndClearPaintedState(t);
// Don't move to 0 since that might trigger some special case that turns off transforms.
t.style.MozTransform = "translatex(-1px)";
waitForAllPaintsFlushed(function () {
var painted = utils.checkAndClearPaintedState(t);
is(painted, false, "Transformed element should not have been painted");
SimpleTest.finish();
});
});
});
});
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1680,19 +1680,24 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
bool inTransform = aBuilder->IsInTransform();
if ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
disp->HasTransform()) {
// Transform dirtyRect into our frame's local coordinate space. Note that
// the new value is the bounds of the old value's transformed vertices, so
// the area covered by dirtyRect may increase here.
//
// Although we don't bother to check for and maintain the 1x1 size of the
// magic rect indicating a hit test point, in reality this is extremely
// unlikely to matter. The rect starts off with dimensions of 1x1 *app*
// units, and it would require a very large number of elements with
// transforms along a parent chain to noticably expand this by an entire
// device pixel.
if (Preserves3DChildren() || !nsDisplayTransform::UntransformRect(dirtyRect, this, nsPoint(0, 0), &dirtyRect)) {
// we have a singular transform - just grab the entire overflow rect
if (nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this) ||
Preserves3DChildren()) {
dirtyRect = GetVisualOverflowRectRelativeToSelf();
} else {
// Transform dirtyRect into our frame's local coordinate space. Note that
// the new value is the bounds of the old value's transformed vertices, so
// the area covered by dirtyRect may increase here.
//
// Although we don't bother to check for and maintain the 1x1 size of the
// magic rect indicating a hit test point, in reality this is extremely
// unlikely to matter. The rect starts off with dimensions of 1x1 *app*
// units, and it would require a very large number of elements with
// transforms along a parent chain to noticably expand this by an entire
// device pixel.
if (!nsDisplayTransform::UntransformRect(dirtyRect, this, nsPoint(0, 0), &dirtyRect)) {
// we have a singular transform - just grab the entire overflow rect
dirtyRect = GetVisualOverflowRectRelativeToSelf();
}
}
inTransform = true;
}

Просмотреть файл

@ -1626,7 +1626,7 @@ nsFrameSelection::AdjustForMaintainedSelection(nsIContent *aContent,
// If aContent/aOffset is inside the maintained selection, or if it is on the
// "anchor" side of the maintained selection, we need to do something.
if (relToStart < 0 && relToEnd > 0 ||
if ((relToStart < 0 && relToEnd > 0) ||
(relToStart > 0 &&
mDomSelections[index]->GetDirection() == eDirNext) ||
(relToEnd < 0 &&

Просмотреть файл

@ -103,8 +103,8 @@ size_t
nsTransformedTextRun::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
{
size_t total = gfxTextRun::SizeOfExcludingThis(aMallocSizeOf);
total += mStyles.SizeOf();
total += mCapitalize.SizeOf();
total += mStyles.SizeOfExcludingThis(aMallocSizeOf);
total += mCapitalize.SizeOfExcludingThis(aMallocSizeOf);
if (mOwnsFactory) {
// It's not worth the effort to get all the sub-class cases right for a
// small size in the fallback case. So we use a |computedSize| of 0, which

Просмотреть файл

@ -49,7 +49,7 @@ ifeq (WINNT,$(OS_TARGET))
FORCE_SHARED_LIB = 1
endif
SHARED_LIBRARY_LIBS =
SHARED_LIBRARY_LIBS = $(MOZ_OTS_LIBS)
ifdef MOZ_VORBIS
SHARED_LIBRARY_LIBS += \
@ -93,6 +93,13 @@ SHARED_LIBRARY_LIBS += \
EXTRA_DSO_LDOPTS = $(MOZALLOC_LIB) $(NSPR_LIBS)
ifeq (WINNT,$(OS_TARGET))
# OTS uses uncompress2() from libz, so we need to link with this
ifdef MOZ_NATIVE_ZLIB
EXTRA_DSO_LDOPTS += $(ZLIB_LIBS)
else
EXTRA_DSO_LDOPTS += $(MOZ_ZLIB_LIBS)
endif
DEFFILE = symbols.def
symbols.def: symbols.def.in

Просмотреть файл

@ -0,0 +1,24 @@
<html>
<head>
<script type="text/javascript">
function go() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var image = document.getElementById("image");
// Draw the SVG image
ctx.drawImage(image, 0, 0);
try {
canvas.toDataURL();
} catch (ex) {
document.body.textContent = ex;
}
}
</script>
</head>
<body onload="go()">
<canvas id="canvas" width="200" height="200"></canvas>
<img id="image" src="lime100x100.svg" style="display: none">
</body>
</html>

Просмотреть файл

@ -41,6 +41,8 @@ fails == canvas-drawImage-scale-2b.html canvas-drawImage-scale-2-ref.html # XXX
== canvas-drawImage-slice-1a.html lime100x100-ref.html
fails == canvas-drawImage-slice-1b.html lime100x100-ref.html # XXX all edges fuzzy
== canvas-drawImage-origin-clean-1.html lime100x100-ref.html
# Simple <img> tests
== img-simple-1.html lime100x100-ref.html
== img-simple-2.html lime100x100-ref.html

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше