зеркало из https://github.com/mozilla/gecko-dev.git
Merge last green PGO changeset from mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
f0d8a7f557
|
@ -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
|
||||
*/
|
||||
|
|
21
configure.in
21
configure.in
|
@ -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
|
||||
1’1
|
||||
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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче