Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2015-06-10 15:25:21 +02:00
commit 8bd8e55f0c
206 changed files with 2955 additions and 1475 deletions

View File

@ -455,7 +455,8 @@ DocAccessible::Shutdown()
mChildDocuments.Clear();
// XXX thinking about ordering?
if (IPCAccessibilityActive()) {
if (mIPCDoc) {
MOZ_ASSERT(IPCAccessibilityActive());
mIPCDoc->Shutdown();
MOZ_ASSERT(!mIPCDoc);
}

1
aclocal.m4 vendored
View File

@ -33,6 +33,7 @@ builtin(include, build/autoconf/winsdk.m4)dnl
builtin(include, build/autoconf/icu.m4)dnl
builtin(include, build/autoconf/ffi.m4)dnl
builtin(include, build/autoconf/clang-plugin.m4)dnl
builtin(include, build/autoconf/alloc.m4)dnl
MOZ_PROG_CHECKMSYS()

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="aac9cc4bb94cf720baf8f7ee419b4d76ac86b1ac"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="aac9cc4bb94cf720baf8f7ee419b4d76ac86b1ac"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "9844b7c9d4429a041cff7201f1a63d0264e155ff",
"git_revision": "e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "8edfc1021ec1ceb0a7f7fb0b23e96b44a0fe8254",
"revision": "c33bf7766d1b19c407c3bbab943403ddee172915",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9844b7c9d4429a041cff7201f1a63d0264e155ff"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3eaf72ccd1bfe6d60d37efde6d3b92c1dbc5ff9"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -975,6 +975,7 @@ pref("browser.safebrowsing.enabled", true);
pref("browser.safebrowsing.malware.enabled", true);
pref("browser.safebrowsing.downloads.enabled", true);
pref("browser.safebrowsing.downloads.remote.enabled", true);
pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
pref("browser.safebrowsing.debug", false);
pref("browser.safebrowsing.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");

View File

@ -692,7 +692,7 @@
if (this.mTab.hasAttribute("busy")) {
this.mTab.removeAttribute("busy");
this.mTabBrowser._tabAttrModified(this.mTab);
this.mTabBrowser._tabAttrModified(this.mTab, ["busy"]);
if (!this.mTab.selected)
this.mTab.setAttribute("unread", "true");
}
@ -892,7 +892,7 @@
aTab.setAttribute("image", sizedIconUrl);
else
aTab.removeAttribute("image");
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["image"]);
}
this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
@ -1167,8 +1167,8 @@
});
this.mCurrentTab.dispatchEvent(event);
this._tabAttrModified(oldTab);
this._tabAttrModified(this.mCurrentTab);
this._tabAttrModified(oldTab, ["selected"]);
this._tabAttrModified(this.mCurrentTab, ["selected"]);
if (oldBrowser != newBrowser &&
oldBrowser.docShell &&
@ -1300,14 +1300,18 @@
<method name="_tabAttrModified">
<parameter name="aTab"/>
<parameter name="aChanged"/>
<body><![CDATA[
if (aTab.closing)
return;
// This event should be dispatched when any of these attributes change:
// label, crop, busy, image, selected
var event = document.createEvent("Events");
event.initEvent("TabAttrModified", true, false);
let event = new CustomEvent("TabAttrModified", {
bubbles: true,
cancelable: false,
detail: {
changed: aChanged,
}
});
aTab.dispatchEvent(event);
]]></body>
</method>
@ -1318,7 +1322,7 @@
<![CDATA[
aTab.label = this.mStringBundle.getString("tabs.connecting");
aTab.crop = "end";
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["label", "crop"]);
]]>
</body>
</method>
@ -1363,7 +1367,7 @@
aTab.label = title;
aTab.crop = crop;
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["label", "crop"]);
if (aTab.selected)
this.updateTitlebar();
@ -2461,7 +2465,7 @@
var isBusy = aOtherTab.hasAttribute("busy");
if (isBusy) {
aOurTab.setAttribute("busy", "true");
this._tabAttrModified(aOurTab);
this._tabAttrModified(aOurTab, ["busy"]);
if (aOurTab.selected)
this.mIsBusy = true;
}

53
build/autoconf/alloc.m4 Normal file
View File

@ -0,0 +1,53 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl Check for the existence of various allocation headers/functions
AC_DEFUN([MOZ_CHECK_ALLOCATOR],[
MALLOC_HEADERS="malloc.h malloc_np.h malloc/malloc.h sys/malloc.h"
MALLOC_H=
for file in $MALLOC_HEADERS; do
MOZ_CHECK_HEADER($file, [MALLOC_H=$file])
if test "$MALLOC_H" != ""; then
AC_DEFINE_UNQUOTED(MALLOC_H, <$MALLOC_H>)
break
fi
done
MOZ_CHECK_HEADERS(alloca.h)
AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);],
[return malloc_usable_size(0);],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
dnl In newer bionic headers, valloc is built but not defined,
dnl so we check more carefully here.
AC_MSG_CHECKING([for valloc in malloc.h])
AC_EGREP_HEADER(valloc, malloc.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
AC_MSG_CHECKING([for valloc in unistd.h])
AC_EGREP_HEADER(valloc, unistd.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
])

View File

@ -47,6 +47,7 @@ SEARCH_PATHS = [
'other-licenses/ply',
'xpcom/idl-parser',
'testing',
'testing/tools/autotry',
'testing/taskcluster',
'testing/xpcshell',
'testing/web-platform',

View File

@ -3399,52 +3399,6 @@ if test -n "$MOZ_LINKER" -a "$OS_TARGET" = "Android"; then
fi
fi
dnl Check for the existence of various allocation headers/functions
MALLOC_HEADERS="malloc.h malloc_np.h malloc/malloc.h sys/malloc.h"
MALLOC_H=
for file in $MALLOC_HEADERS; do
MOZ_CHECK_HEADER($file, [MALLOC_H=$file])
if test "$MALLOC_H" != ""; then
AC_DEFINE_UNQUOTED(MALLOC_H, <$MALLOC_H>)
break
fi
done
MOZ_CHECK_HEADERS(alloca.h)
AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);],
[return malloc_usable_size(0);],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
dnl In newer bionic headers, valloc is built but not defined,
dnl so we check more carefully here.
AC_MSG_CHECKING([for valloc in malloc.h])
AC_EGREP_HEADER(valloc, malloc.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
AC_MSG_CHECKING([for valloc in unistd.h])
AC_EGREP_HEADER(valloc, unistd.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
dnl See if compiler supports some gcc-style attributes
AC_CACHE_CHECK(for __attribute__((always_inline)),
@ -3479,6 +3433,8 @@ fi
AC_HAVE_FUNCS(localeconv)
fi # ! SKIP_COMPILER_CHECKS
MOZ_CHECK_ALLOCATOR
TARGET_XPCOM_ABI=
if test -n "${CPU_ARCH}" -a -n "${TARGET_COMPILER_ABI}"; then
TARGET_XPCOM_ABI="${CPU_ARCH}-${TARGET_COMPILER_ABI}"

View File

@ -11196,12 +11196,8 @@ ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
void
nsDocument::ExitFullscreen(nsIDocument* aDoc)
{
// Unlock the pointer, if it's locked.
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
// Unlock the pointer
UnlockPointer();
if (aDoc) {
ExitFullscreenInDocTree(aDoc);
@ -11258,11 +11254,7 @@ nsDocument::RestorePreviousFullScreenState()
}
// If fullscreen mode is updated the pointer should be unlocked
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
UnlockPointer();
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
@ -11271,7 +11263,6 @@ nsDocument::RestorePreviousFullScreenState()
while (doc != this) {
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
UnlockPointer();
DispatchFullScreenChange(doc);
doc = doc->GetParentDocument();
}
@ -11280,7 +11271,6 @@ nsDocument::RestorePreviousFullScreenState()
NS_ASSERTION(doc == this, "Must have reached this doc.");
while (doc != nullptr) {
static_cast<nsDocument*>(doc)->FullScreenStackPop();
UnlockPointer();
DispatchFullScreenChange(doc);
if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
// Full-screen stack in document is empty. Go back up to the parent
@ -11666,19 +11656,10 @@ nsDocument::RequestFullScreen(Element* aElement,
// 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.
nsIDocument* fullScreenRootDoc = nsContentUtils::GetRootDocument(this);
if (fullScreenRootDoc->IsFullScreenDoc()) {
// A document is already in fullscreen, unlock the mouse pointer
// before setting a new document to fullscreen
UnlockPointer();
}
// If a document is already in fullscreen, then unlock the mouse pointer
// before setting a new document to fullscreen
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
UnlockPointer();
// Process options -- in this case, just HMD
if (aOptions.mVRHMDDevice) {

View File

@ -5,18 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothSocket.h"
#include <fcntl.h>
#include <sys/socket.h>
#include "base/message_loop.h"
#include "BluetoothSocketObserver.h"
#include "BluetoothInterface.h"
#include "BluetoothUtils.h"
#include "mozilla/ipc/UnixSocketWatcher.h"
#include "mozilla/FileUtils.h"
#include "mozilla/RefPtr.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
using namespace mozilla::ipc;
@ -74,11 +70,11 @@ public:
SOCKET_IS_CONNECTED
};
DroidSocketImpl(nsIThread* aConsumerThread,
DroidSocketImpl(MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
BluetoothSocket* aConsumer)
: ipc::UnixFdWatcher(aIOLoop)
, DataSocketIO(aConsumerThread)
, DataSocketIO(aConsumerLoop)
, mConsumer(aConsumer)
, mShuttingDownOnIOThread(false)
, mConnectionStatus(SOCKET_IS_DISCONNECTED)
@ -173,7 +169,7 @@ public:
}
private:
class ReceiveRunnable;
class ReceiveTask;
/**
* libevent triggered functions that reads data from socket when available and
@ -319,9 +315,8 @@ DroidSocketImpl::Accept(int aFd)
SetFd(aFd);
mConnectionStatus = SOCKET_IS_CONNECTED;
GetConsumerThread()->Dispatch(
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@ -426,15 +421,15 @@ private:
DroidSocketImpl* mImpl;
};
class AcceptRunnable final : public SocketIORunnable<DroidSocketImpl>
class InvokeAcceptTask final : public SocketTask<DroidSocketImpl>
{
public:
AcceptRunnable(DroidSocketImpl* aImpl, int aFd)
: SocketIORunnable<DroidSocketImpl>(aImpl)
, mFd(aFd)
InvokeAcceptTask(DroidSocketImpl* aImpl, int aFd)
: SocketTask<DroidSocketImpl>(aImpl)
, mFd(aFd)
{ }
NS_IMETHOD Run() override
void Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
MOZ_ASSERT(sBluetoothSocketInterface);
@ -443,8 +438,6 @@ public:
GetIO()->mConsumer->SetCurrentResultHandler(res);
sBluetoothSocketInterface->Accept(mFd, res);
return NS_OK;
}
private:
@ -462,8 +455,7 @@ DroidSocketImpl::OnSocketCanAcceptWithoutBlocking(int aFd)
*/
RemoveWatchers(READ_WATCHER);
GetConsumerThread()->Dispatch(new AcceptRunnable(this, aFd),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(FROM_HERE, new InvokeAcceptTask(this, aFd));
}
void
@ -507,9 +499,8 @@ DroidSocketImpl::OnSocketCanConnectWithoutBlocking(int aFd)
mConnectionStatus = SOCKET_IS_CONNECTED;
GetConsumerThread()->Dispatch(
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@ -537,33 +528,30 @@ DroidSocketImpl::QueryReceiveBuffer(
* |ReceiveRunnable| transfers data received on the I/O thread
* to an instance of |BluetoothSocket| on the consumer thread.
*/
class DroidSocketImpl::ReceiveRunnable final
: public SocketIORunnable<DroidSocketImpl>
class DroidSocketImpl::ReceiveTask final : public SocketTask<DroidSocketImpl>
{
public:
ReceiveRunnable(DroidSocketImpl* aIO, UnixSocketBuffer* aBuffer)
: SocketIORunnable<DroidSocketImpl>(aIO)
ReceiveTask(DroidSocketImpl* aIO, UnixSocketBuffer* aBuffer)
: SocketTask<DroidSocketImpl>(aIO)
, mBuffer(aBuffer)
{ }
NS_IMETHOD Run() override
void Run() override
{
DroidSocketImpl* io = SocketIORunnable<DroidSocketImpl>::GetIO();
DroidSocketImpl* io = SocketTask<DroidSocketImpl>::GetIO();
MOZ_ASSERT(io->IsConsumerThread());
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return NS_OK;
return;
}
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
MOZ_ASSERT(bluetoothSocket);
bluetoothSocket->ReceiveSocketData(mBuffer);
return NS_OK;
}
private:
@ -573,8 +561,8 @@ private:
void
DroidSocketImpl::ConsumeBuffer()
{
GetConsumerThread()->Dispatch(new ReceiveRunnable(this, mBuffer.forget()),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(FROM_HERE,
new ReceiveTask(this, mBuffer.forget()));
}
void
@ -651,14 +639,14 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt,
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop)
{
MOZ_ASSERT(!mImpl);
SetConnectionStatus(SOCKET_CONNECTING);
mImpl = new DroidSocketImpl(aConsumerThread, aIOLoop, this);
mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
SetCurrentResultHandler(res);
@ -678,14 +666,8 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
int aChannel,
bool aAuth, bool aEncrypt)
{
nsIThread* consumerThread = nullptr;
nsresult rv = NS_GetCurrentThread(&consumerThread);
if (NS_FAILED(rv)) {
return rv;
}
return Connect(aDeviceAddress, aServiceUuid, aType, aChannel, aAuth,
aEncrypt, consumerThread, XRE_GetIOMessageLoop());
aEncrypt, MessageLoop::current(), XRE_GetIOMessageLoop());
}
class ListenResultHandler final : public BluetoothSocketResultHandler
@ -721,14 +703,14 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt,
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop)
{
MOZ_ASSERT(!mImpl);
SetConnectionStatus(SOCKET_LISTENING);
mImpl = new DroidSocketImpl(aConsumerThread, aIOLoop, this);
mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
SetCurrentResultHandler(res);
@ -748,14 +730,8 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
int aChannel,
bool aAuth, bool aEncrypt)
{
nsIThread* consumerThread = nullptr;
nsresult rv = NS_GetCurrentThread(&consumerThread);
if (NS_FAILED(rv)) {
return rv;
}
return Listen(aServiceName, aServiceUuid, aType, aChannel, aAuth, aEncrypt,
consumerThread, XRE_GetIOMessageLoop());
MessageLoop::current(), XRE_GetIOMessageLoop());
}
void

View File

@ -11,7 +11,6 @@
#include "mozilla/ipc/DataSocket.h"
class MessageLoop;
class nsIThread;
BEGIN_BLUETOOTH_NAMESPACE
@ -29,7 +28,7 @@ public:
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt,
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop);
nsresult Connect(const nsAString& aDeviceAddress,
@ -43,7 +42,7 @@ public:
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt,
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop);
nsresult Listen(const nsAString& aServiceName,

View File

@ -8,9 +8,7 @@
#include <fcntl.h>
#include "BluetoothSocketObserver.h"
#include "BluetoothUnixSocketConnector.h"
#include "mozilla/unused.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#include "mozilla/RefPtr.h"
#include "nsXULAppAPI.h"
using namespace mozilla::ipc;
@ -28,7 +26,7 @@ class BluetoothSocket::BluetoothSocketIO final
, public DataSocketIO
{
public:
BluetoothSocketIO(nsIThread* aConsumerThread,
BluetoothSocketIO(MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
BluetoothSocket* aConsumer,
UnixSocketConnector* aConnector);
@ -90,7 +88,7 @@ public:
void ShutdownOnIOThread() override;
private:
class ReceiveRunnable;
class ReceiveTask;
void FireSocketError();
@ -134,12 +132,12 @@ private:
};
BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
BluetoothSocket* aConsumer,
UnixSocketConnector* aConnector)
: UnixSocketWatcher(aIOLoop)
, DataSocketIO(aConsumerThread)
, DataSocketIO(aConsumerLoop)
, mConsumer(aConsumer)
, mConnector(aConnector)
, mShuttingDownOnIOThread(false)
@ -281,9 +279,8 @@ BluetoothSocket::BluetoothSocketIO::OnConnected()
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
GetConsumerThread()->Dispatch(
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@ -331,9 +328,8 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
Close();
SetSocket(fd, SOCKET_IS_CONNECTED);
GetConsumerThread()->Dispatch(
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@ -382,10 +378,8 @@ BluetoothSocket::BluetoothSocketIO::FireSocketError()
Close();
// Tell the consumer thread we've errored
GetConsumerThread()->Dispatch(
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_ERROR));
}
// |DataSocketIO|
@ -405,36 +399,34 @@ BluetoothSocket::BluetoothSocketIO::QueryReceiveBuffer(
}
/**
* |ReceiveRunnable| transfers data received on the I/O thread
* |ReceiveTask| transfers data received on the I/O thread
* to an instance of |BluetoothSocket| on the consumer thread.
*/
class BluetoothSocket::BluetoothSocketIO::ReceiveRunnable final
: public SocketIORunnable<BluetoothSocketIO>
class BluetoothSocket::BluetoothSocketIO::ReceiveTask final
: public SocketTask<BluetoothSocketIO>
{
public:
ReceiveRunnable(BluetoothSocketIO* aIO, UnixSocketBuffer* aBuffer)
: SocketIORunnable<BluetoothSocketIO>(aIO)
ReceiveTask(BluetoothSocketIO* aIO, UnixSocketBuffer* aBuffer)
: SocketTask<BluetoothSocketIO>(aIO)
, mBuffer(aBuffer)
{ }
NS_IMETHOD Run() override
void Run() override
{
BluetoothSocketIO* io = SocketIORunnable<BluetoothSocketIO>::GetIO();
BluetoothSocketIO* io = SocketTask<BluetoothSocketIO>::GetIO();
MOZ_ASSERT(io->IsConsumerThread());
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return NS_OK;
return;
}
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
MOZ_ASSERT(bluetoothSocket);
bluetoothSocket->ReceiveSocketData(mBuffer);
return NS_OK;
}
private:
@ -444,8 +436,8 @@ private:
void
BluetoothSocket::BluetoothSocketIO::ConsumeBuffer()
{
GetConsumerThread()->Dispatch(new ReceiveRunnable(this, mBuffer.forget()),
NS_DISPATCH_NORMAL);
GetConsumerThread()->PostTask(FROM_HERE,
new ReceiveTask(this, mBuffer.forget()));
}
void
@ -650,14 +642,14 @@ BluetoothSocket::SendSocketData(const nsACString& aStr)
nsresult
BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
int aDelayMs,
nsIThread* aConsumerThread, MessageLoop* aIOLoop)
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
{
MOZ_ASSERT(aConnector);
MOZ_ASSERT(aConsumerThread);
MOZ_ASSERT(aConsumerLoop);
MOZ_ASSERT(aIOLoop);
MOZ_ASSERT(!mIO);
mIO = new BluetoothSocketIO(aConsumerThread, aIOLoop, this, aConnector);
mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
@ -675,25 +667,20 @@ nsresult
BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
int aDelayMs)
{
nsIThread* consumerThread = nullptr;
nsresult rv = NS_GetCurrentThread(&consumerThread);
if (NS_FAILED(rv)) {
return rv;
}
return Connect(aConnector, aDelayMs, consumerThread, XRE_GetIOMessageLoop());
return Connect(aConnector, aDelayMs, MessageLoop::current(),
XRE_GetIOMessageLoop());
}
nsresult
BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector,
nsIThread* aConsumerThread, MessageLoop* aIOLoop)
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
{
MOZ_ASSERT(aConnector);
MOZ_ASSERT(aConsumerThread);
MOZ_ASSERT(aConsumerLoop);
MOZ_ASSERT(aIOLoop);
MOZ_ASSERT(!mIO);
mIO = new BluetoothSocketIO(aConsumerThread, aIOLoop, this, aConnector);
mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
SetConnectionStatus(SOCKET_LISTENING);
aIOLoop->PostTask(FROM_HERE, new ListenTask(mIO));
@ -704,13 +691,7 @@ BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector,
nsresult
BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector)
{
nsIThread* consumerThread = nullptr;
nsresult rv = NS_GetCurrentThread(&consumerThread);
if (NS_FAILED(rv)) {
return rv;
}
return Listen(aConnector, consumerThread, XRE_GetIOMessageLoop());
return Listen(aConnector, MessageLoop::current(), XRE_GetIOMessageLoop());
}
void

View File

@ -8,13 +8,10 @@
#define mozilla_dom_bluetooth_BluetoothSocket_h
#include "BluetoothCommon.h"
#include <stdlib.h>
#include "mozilla/ipc/DataSocket.h"
#include "mozilla/ipc/UnixSocketWatcher.h"
#include "mozilla/RefPtr.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsThreadUtils.h"
class MessageLoop;
@ -66,12 +63,12 @@ public:
*
* @param aConnector Connector object for socket type specific functions
* @param aDelayMs Time delay in milli-seconds.
* @param aConsumerThread The socket's consumer thread.
* @param aConsumerLoop The socket's consumer thread.
* @param aIOLoop The socket's I/O thread.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Connect(BluetoothUnixSocketConnector* aConnector, int aDelayMs,
nsIThread* aConsumerThread, MessageLoop* aIOLoop);
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
/**
* Starts a task on the socket that will try to connect to a socket in a
@ -89,12 +86,12 @@ public:
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aConsumerThread The socket's consumer thread.
* @param aConsumerLoop The socket's consumer thread.
* @param aIOLoop The socket's I/O thread.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Listen(BluetoothUnixSocketConnector* aConnector,
nsIThread* aConsumerThread, MessageLoop* aIOLoop);
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
/**
* Starts a task on the socket that will try to accept a new connection in a

View File

@ -33,7 +33,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override;
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;

View File

@ -35,22 +35,6 @@ WebGL1Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
return false;
}
/** Buffer and Target validation for BindBuffer */
bool
WebGL1Context::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
if (buffer->HasEverBeenBound() && target != buffer->Target()) {
ErrorInvalidOperation("%s: buffer already bound to a different target", info);
return false;
}
return true;
}
bool
WebGL1Context::ValidateBufferUsageEnum(GLenum usage, const char* info)
{

View File

@ -365,10 +365,11 @@ private:
GLsizei width, GLsizei height, GLsizei depth,
const char* info);
// CreateVertexArrayImpl is assumed to be infallible.
virtual WebGLVertexArray* CreateVertexArrayImpl() override;
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override;
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;

View File

@ -45,36 +45,6 @@ WebGL2Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
}
}
bool
WebGL2Context::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
switch (target) {
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
return true;
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
return !buffer->HasEverBeenBound() ||
buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
return !buffer->HasEverBeenBound() ||
buffer->Target() != LOCAL_GL_ELEMENT_ARRAY_BUFFER;
}
ErrorInvalidOperation("%s: buffer already bound to a incompatible target %s",
info, EnumName(buffer->Target().get()));
return false;
}
bool
WebGL2Context::ValidateBufferUsageEnum(GLenum usage, const char* info)
{
@ -123,7 +93,7 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
if (!readBuffer)
return ErrorInvalidOperation("copyBufferSubData: No buffer bound to readTarget");
const WebGLBuffer* writeBuffer = writeBufferSlot.get();
WebGLBuffer* writeBuffer = writeBufferSlot.get();
if (!writeBuffer)
return ErrorInvalidOperation("copyBufferSubData: No buffer bound to writeTarget");
@ -145,8 +115,27 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
return;
}
WebGLBuffer::Kind readType = readBuffer->Content();
WebGLBuffer::Kind writeType = writeBuffer->Content();
if (readType != WebGLBuffer::Kind::Undefined &&
writeType != WebGLBuffer::Kind::Undefined &&
writeType != readType)
{
ErrorInvalidOperation("copyBufferSubData: Can't copy %s data to %s data",
(readType == WebGLBuffer::Kind::OtherData) ? "other" : "element",
(writeType == WebGLBuffer::Kind::OtherData) ? "other" : "element");
return;
}
WebGLContextUnchecked::CopyBufferSubData(readTarget, writeTarget, readOffset,
writeOffset, size);
if (writeType == WebGLBuffer::Kind::Undefined) {
writeBuffer->BindTo(
(readType == WebGLBuffer::Kind::OtherData) ? LOCAL_GL_ARRAY_BUFFER
: LOCAL_GL_ELEMENT_ARRAY_BUFFER);
}
}
void
@ -155,7 +144,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
{
if (IsContextLost())
return;
// For the WebGLBuffer bound to the passed target, read
// returnedData.byteLength bytes from the buffer starting at byte
// offset offset and write them to returnedData.
@ -168,7 +157,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
// If offset is less than zero, an INVALID_VALUE error is
// generated.
if (offset < 0)
return ErrorInvalidValue("getBufferSubData: negative offset");
return ErrorInvalidValue("getBufferSubData: negative offset");
// If returnedData is null then an INVALID_VALUE error is
// generated.
@ -179,7 +168,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
WebGLBuffer* boundBuffer = bufferSlot.get();
if (!boundBuffer)
return ErrorInvalidOperation("getBufferSubData: no buffer bound");
// If offset + returnedData.byteLength would extend beyond the end
// of the buffer an INVALID_VALUE error is generated.
const dom::ArrayBuffer& data = maybeData.Value();

View File

@ -54,7 +54,8 @@ WebGL2Context::IsSampler(WebGLSampler* sampler)
if (sampler->IsDeleted())
return false;
return !sampler->HasEverBeenBound();
MakeContextCurrent();
return gl->fIsSampler(sampler->mGLName);
}
void

View File

@ -60,7 +60,7 @@ WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf)
return false;
MakeContextCurrent();
return gl->fIsTransformFeedback(tf->GLName());
return gl->fIsTransformFeedback(tf->mGLName);
}
void
@ -84,11 +84,8 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
if (tf && tf->IsDeleted())
return ErrorInvalidOperation("bindTransformFeedback: Attempt to bind deleted id");
if (tf)
tf->BindTo(LOCAL_GL_TRANSFORM_FEEDBACK);
MakeContextCurrent();
gl->fBindTransformFeedback(target, tf ? tf->GLName() : 0);
gl->fBindTransformFeedback(target, tf ? tf->mGLName : 0);
if (tf)
mBoundTransformFeedback = tf;
else

View File

@ -5,16 +5,17 @@
#include "WebGL2Context.h"
#include "GLContext.h"
#include "WebGLVertexArrayObject.h"
using namespace mozilla;
using namespace mozilla::dom;
namespace mozilla {
// -------------------------------------------------------------------------
// Vertex Array Object
// TODO(djg): Implemented in WebGLContext
/*
already_AddRefed<WebGLVertexArrayObject> CreateVertexArray();
void DeleteVertexArray(WebGLVertexArrayObject* vertexArray);
bool IsVertexArray(WebGLVertexArrayObject* vertexArray);
void BindVertexArray(WebGLVertexArrayObject* vertexArray);
*/
WebGLVertexArray*
WebGL2Context::CreateVertexArrayImpl()
{
return dom::WebGLVertexArrayObject::Create(this);
}
} // namespace mozilla

View File

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef WEBGLBINDABLENAME_H_
#define WEBGLBINDABLENAME_H_
#include "WebGLTypes.h"
#include "GLDefs.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Assertions.h"
namespace mozilla {
/** Represents a binding to a GL binding point
*/
template<typename T>
class WebGLBindable
{
public:
WebGLBindable() : mTarget(LOCAL_GL_NONE) { }
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
void BindTo(T target) {
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
MOZ_ASSERT(!HasEverBeenBound() || mTarget == target, "Rebinding is illegal.");
bool targetChanged = (target != mTarget);
mTarget = target;
if (targetChanged)
OnTargetChanged();
}
T Target() const {
MOZ_ASSERT(HasEverBeenBound());
return mTarget;
}
protected:
//! Called after mTarget has been changed by BindTo(target).
virtual void OnTargetChanged() {}
T mTarget;
};
/** Represents a GL name that can be bound to a target.
*/
template<typename T>
class WebGLBindableName
: public WebGLBindable<T>
{
public:
explicit WebGLBindableName(GLuint aName)
: WebGLBindable<T>()
, mGLName(aName)
{ }
GLuint GLName() const { return mGLName; }
protected:
const GLuint mGLName;
};
} // namespace mozilla
#endif // !WEBGLBINDABLENAME_H_

View File

@ -13,8 +13,9 @@
namespace mozilla {
WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf)
: WebGLBindableName<BufferBinding>(buf)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(buf)
, mContent(Kind::Undefined)
, mByteLength(0)
{
mContext->mBuffers.insertBack(this);
@ -25,6 +26,34 @@ WebGLBuffer::~WebGLBuffer()
DeleteOnce();
}
void
WebGLBuffer::BindTo(GLenum target)
{
switch (target) {
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
mContent = Kind::ElementArray;
if (!mCache)
mCache = new WebGLElementArrayCache;
break;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
mContent = Kind::OtherData;
break;
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
/* Do nothing. Doesn't set the type of the buffer contents. */
break;
default:
MOZ_CRASH();
}
}
void
WebGLBuffer::Delete()
{
@ -35,18 +64,11 @@ WebGLBuffer::Delete()
LinkedListElement<WebGLBuffer>::remove(); // remove from mContext->mBuffers
}
void
WebGLBuffer::OnTargetChanged()
{
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
mCache = new WebGLElementArrayCache;
}
bool
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr,
size_t bufferSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
if (mContent == Kind::ElementArray)
return mCache->BufferData(ptr, bufferSizeInBytes);
return true;
@ -56,7 +78,7 @@ void
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr,
size_t updateSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
if (mContent == Kind::ElementArray)
mCache->BufferSubData(pos, ptr, updateSizeInBytes);
}

View File

@ -10,7 +10,6 @@
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "WebGLTypes.h"
@ -21,14 +20,23 @@ class WebGLElementArrayCache;
class WebGLBuffer final
: public nsWrapperCache
, public WebGLBindableName<BufferBinding>
, public WebGLRefCountedObject<WebGLBuffer>
, public LinkedListElement<WebGLBuffer>
, public WebGLContextBoundObject
{
public:
enum class Kind {
Undefined,
ElementArray,
OtherData
};
explicit WebGLBuffer(WebGLContext* webgl, GLuint buf);
void BindTo(GLenum target);
Kind Content() const { return mContent; }
void Delete();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
@ -52,14 +60,15 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
protected:
~WebGLBuffer();
virtual void OnTargetChanged() override;
Kind mContent;
WebGLsizeiptr mByteLength;
nsAutoPtr<WebGLElementArrayCache> mCache;
};

View File

@ -1880,7 +1880,7 @@ WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
: gl::OriginPos::TopLeft;
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(),
srcImage->GetSize(),
tex->GLName(),
tex->mGLName,
texImageTarget.get(),
destOrigin);
if (ok) {

View File

@ -939,6 +939,8 @@ protected:
WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
GLuint index);
GLenum GetCurrentBinding(WebGLBuffer* buffer) const;
// -----------------------------------------------------------------------------
// Queries (WebGL2ContextQueries.cpp)
protected:
@ -1390,10 +1392,12 @@ private:
private:
// -------------------------------------------------------------------------
// Context customization points
virtual WebGLVertexArray* CreateVertexArrayImpl();
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0;
virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) = 0;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info);
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) = 0;
virtual bool ValidateQueryTarget(GLenum usage, const char* info) = 0;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0;

View File

@ -20,24 +20,7 @@ WebGLContext::UpdateBoundBuffer(GLenum target, WebGLBuffer* buffer)
if (!buffer)
return;
/* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
*
* In the WebGL 2 API, buffers have their WebGL buffer type
* initially set to undefined. Calling bindBuffer, bindBufferRange
* or bindBufferBase with the target argument set to any buffer
* binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will
* then set the WebGL buffer type of the buffer being bound
* according to the table above.
*
* Any call to one of these functions which attempts to bind a
* WebGLBuffer that has the element array WebGL buffer type to a
* binding point that falls under other data, or bind a
* WebGLBuffer which has the other data WebGL buffer type to
* ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error,
* and the state of the binding point will remain untouched.
*/
if (target != LOCAL_GL_COPY_READ_BUFFER && target != LOCAL_GL_COPY_WRITE_BUFFER)
buffer->BindTo(target);
buffer->BindTo(target);
}
void
@ -410,12 +393,50 @@ WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
if (!buffer || buffer->IsDeleted())
return;
if (mBoundArrayBuffer == buffer)
BindBuffer(LOCAL_GL_ARRAY_BUFFER, static_cast<WebGLBuffer*>(nullptr));
// TODO: Extract this into a helper function?
if (mBoundArrayBuffer == buffer) {
WebGLContextUnchecked::BindBuffer(LOCAL_GL_ARRAY_BUFFER, nullptr);
mBoundArrayBuffer = nullptr;
}
if (mBoundVertexArray->mElementArrayBuffer == buffer) {
BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
static_cast<WebGLBuffer*>(nullptr));
WebGLContextUnchecked::BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, nullptr);
mBoundVertexArray->mElementArrayBuffer = nullptr;
}
// WebGL binding points
if (IsWebGL2()) {
if (mBoundCopyReadBuffer == buffer)
mBoundCopyReadBuffer = nullptr;
if (mBoundCopyWriteBuffer == buffer)
mBoundCopyWriteBuffer = nullptr;
if (mBoundPixelPackBuffer == buffer)
mBoundPixelPackBuffer = nullptr;
if (mBoundPixelUnpackBuffer == buffer)
mBoundPixelUnpackBuffer = nullptr;
if (mBoundTransformFeedbackBuffer == buffer)
mBoundTransformFeedbackBuffer = nullptr;
if (mBoundUniformBuffer == buffer)
mBoundUniformBuffer = nullptr;
const size_t xfBufferCount = mBoundTransformFeedbackBuffers.Length();
for (size_t n = 0; n < xfBufferCount; n++) {
if (mBoundTransformFeedbackBuffers[n] == buffer) {
mBoundTransformFeedbackBuffers[n] = nullptr;
}
}
const size_t uniformBufferCount = mBoundUniformBuffers.Length();
for (size_t n = 0; n < uniformBufferCount; n++) {
if (mBoundUniformBuffers[n] == buffer) {
mBoundUniformBuffers[n] = nullptr;
}
}
}
for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
@ -435,9 +456,89 @@ WebGLContext::IsBuffer(WebGLBuffer* buffer)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isBuffer", buffer) &&
!buffer->IsDeleted() &&
buffer->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isBuffer", buffer))
return false;
if (buffer->IsDeleted())
return false;
MakeContextCurrent();
return gl->fIsBuffer(buffer->mGLName);
}
bool
WebGLContext::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
/* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
*
* In the WebGL 2 API, buffers have their WebGL buffer type
* initially set to undefined. Calling bindBuffer, bindBufferRange
* or bindBufferBase with the target argument set to any buffer
* binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will
* then set the WebGL buffer type of the buffer being bound
* according to the table above.
*
* Any call to one of these functions which attempts to bind a
* WebGLBuffer that has the element array WebGL buffer type to a
* binding point that falls under other data, or bind a
* WebGLBuffer which has the other data WebGL buffer type to
* ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error,
* and the state of the binding point will remain untouched.
*/
GLenum boundTo = GetCurrentBinding(buffer);
if (boundTo != LOCAL_GL_NONE) {
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
boundTo != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
{
ErrorInvalidOperation("Can't bind buffer to TRANSFORM_FEEDBACK_BUFFER as the "
"buffer is already bound to another bind point.");
return false;
}
else if (target != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
boundTo == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
{
ErrorInvalidOperation("Can't bind buffer to bind point as it is currently "
"bound to TRANSFORM_FEEDBACK_BUFFER.");
return false;
}
}
WebGLBuffer::Kind content = buffer->Content();
if (content == WebGLBuffer::Kind::Undefined)
return true;
switch (target) {
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
return true;
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
if (content == WebGLBuffer::Kind::ElementArray)
return true;
break;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
if (content == WebGLBuffer::Kind::OtherData)
return true;
break;
default:
MOZ_CRASH();
}
ErrorInvalidOperation("%s: buffer already contains %s data.", info,
content == WebGLBuffer::Kind::OtherData ? "other" : "element");
return false;
}
bool
@ -510,6 +611,37 @@ WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index)
}
}
GLenum
WebGLContext::GetCurrentBinding(WebGLBuffer* buffer) const
{
if (mBoundArrayBuffer == buffer)
return LOCAL_GL_ARRAY_BUFFER;
if (mBoundCopyReadBuffer == buffer)
return LOCAL_GL_COPY_READ_BUFFER;
if (mBoundCopyWriteBuffer == buffer)
return LOCAL_GL_COPY_WRITE_BUFFER;
if (mBoundPixelPackBuffer == buffer)
return LOCAL_GL_PIXEL_PACK_BUFFER;
if (mBoundPixelUnpackBuffer == buffer)
return LOCAL_GL_PIXEL_UNPACK_BUFFER;
if (mBoundTransformFeedbackBuffer == buffer ||
mBoundTransformFeedbackBuffers.Contains(buffer)) {
return LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER;
}
if (mBoundUniformBuffer == buffer ||
mBoundUniformBuffers.Contains(buffer)) {
return LOCAL_GL_UNIFORM_BUFFER;
}
return LOCAL_GL_NONE;
}
GLenum
WebGLContext::CheckedBufferData(GLenum target, GLsizeiptr size,
const GLvoid* data, GLenum usage)

View File

@ -600,7 +600,7 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
}
GLenum error = GetAndFlushUnderlyingGLErrors();
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
// note that we do this error checking and early return AFTER having restored the buffer binding above
if (error) {
@ -626,7 +626,7 @@ WebGLContext::UndoFakeVertexAttrib0()
if (mBoundVertexArray->HasAttrib(0) && mBoundVertexArray->mAttribs[0].buf) {
const WebGLVertexAttribData& attrib0 = mBoundVertexArray->mAttribs[0];
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->GLName());
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->mGLName);
if (attrib0.integer) {
gl->fVertexAttribIPointer(0,
attrib0.size,
@ -645,7 +645,7 @@ WebGLContext::UndoFakeVertexAttrib0()
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
}
WebGLContextFakeBlackStatus
@ -737,11 +737,11 @@ WebGLContext::UnbindFakeBlackTextures()
for (int32_t i = 0; i < mGLMaxTextureUnits; ++i) {
if (mBound2DTextures[i] && mBound2DTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->GLName());
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->mGLName);
}
if (mBoundCubeMapTextures[i] && mBoundCubeMapTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->GLName());
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->mGLName);
}
}

View File

@ -159,9 +159,11 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
if (!wfb) {
gl->fBindFramebuffer(target, 0);
} else {
wfb->BindTo(target);
GLuint framebuffername = wfb->GLName();
GLuint framebuffername = wfb->mGLName;
gl->fBindFramebuffer(target, framebuffername);
#ifdef ANDROID
wfb->mIsFB = true;
#endif
}
switch (target) {
@ -196,15 +198,15 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb)
if (wrb && wrb->IsDeleted())
return;
if (wrb)
wrb->BindTo(target);
MakeContextCurrent();
// Sometimes we emulate renderbuffers (depth-stencil emu), so there's not
// always a 1-1 mapping from `wrb` to GL name. Just have `wrb` handle it.
if (wrb) {
wrb->BindRenderbuffer();
#ifdef ANDROID
wrb->mIsRB = true;
#endif
} else {
gl->fBindRenderbuffer(target, 0);
}
@ -737,7 +739,7 @@ WebGLContext::DeleteTexture(WebGLTexture* tex)
(mBound3DTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_3D))
{
ActiveTexture(LOCAL_GL_TEXTURE0 + i);
BindTexture(tex->Target().get(), nullptr);
BindTexture(tex->Target(), nullptr);
}
}
ActiveTexture(LOCAL_GL_TEXTURE0 + activeTexture);
@ -1691,9 +1693,22 @@ WebGLContext::IsFramebuffer(WebGLFramebuffer* fb)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isFramebuffer", fb) &&
!fb->IsDeleted() &&
fb->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isFramebuffer", fb))
return false;
if (fb->IsDeleted())
return false;
#ifdef ANDROID
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::AndroidEmulator)
{
return fb->mIsFB;
}
#endif
MakeContextCurrent();
return gl->fIsFramebuffer(fb->mGLName);
}
bool
@ -1711,9 +1726,22 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer* rb)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isRenderBuffer", rb) &&
!rb->IsDeleted() &&
rb->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isRenderBuffer", rb))
return false;
if (rb->IsDeleted())
return false;
#ifdef ANDROID
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::AndroidEmulator)
{
return rb->mIsRB;
}
#endif
MakeContextCurrent();
return gl->fIsRenderbuffer(rb->PrimaryGLName());
}
bool

View File

@ -126,8 +126,7 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed()
buffer;
buffer = buffer->getNext())
{
if (buffer->HasEverBeenBound() &&
buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
if (buffer->Content() == WebGLBuffer::Kind::ElementArray) {
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
}
}

View File

@ -194,21 +194,38 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
if (IsWebGL2()) {
switch (pname) {
case LOCAL_GL_MAX_SAMPLES:
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
GLint val;
gl->fGetIntegerv(pname, &val);
return JS::NumberValue(uint32_t(val));
}
case LOCAL_GL_MAX_SAMPLES:
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
GLint val;
gl->fGetIntegerv(pname, &val);
return JS::NumberValue(uint32_t(val));
}
case LOCAL_GL_TEXTURE_BINDING_3D: {
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
}
case LOCAL_GL_TEXTURE_BINDING_3D:
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
case LOCAL_GL_COPY_READ_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
}
}
@ -533,13 +550,6 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
}
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
if (!IsWebGL2()) {
break;
}
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
}
case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv);
}

View File

@ -24,21 +24,32 @@ void
WebGLContextUnchecked::BindBuffer(GLenum target, WebGLBuffer* buffer)
{
gl->MakeCurrent();
gl->fBindBuffer(target, buffer ? buffer->GLName() : 0);
gl->fBindBuffer(target, buffer ? buffer->mGLName : 0);
}
void
WebGLContextUnchecked::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
{
gl->MakeCurrent();
gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0);
gl->fBindBufferBase(target, index, buffer ? buffer->mGLName : 0);
}
void
WebGLContextUnchecked::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size)
{
gl->MakeCurrent();
gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size);
#ifdef XP_MACOSX
if (buffer && buffer->Content() == WebGLBuffer::Kind::Undefined &&
gl->WorkAroundDriverBugs())
{
// BindBufferRange will fail if the buffer's contents is undefined.
// Bind so driver initializes the buffer.
gl->fBindBuffer(target, buffer->mGLName);
}
#endif
gl->fBindBufferRange(target, index, buffer ? buffer->mGLName : 0, offset, size);
}
void
@ -56,9 +67,7 @@ void
WebGLContextUnchecked::BindSampler(GLuint unit, WebGLSampler* sampler)
{
gl->MakeCurrent();
gl->fBindSampler(unit, sampler ? sampler->GLName() : 0);
if (sampler)
sampler->BindTo(LOCAL_GL_SAMPLER_BINDING);
gl->fBindSampler(unit, sampler ? sampler->mGLName : 0);
}
GLint
@ -69,7 +78,7 @@ WebGLContextUnchecked::GetSamplerParameteriv(WebGLSampler* sampler,
GLint param = 0;
gl->MakeCurrent();
gl->fGetSamplerParameteriv(sampler->GLName(), pname, &param);
gl->fGetSamplerParameteriv(sampler->mGLName, pname, &param);
return param;
}
@ -82,7 +91,7 @@ WebGLContextUnchecked::GetSamplerParameterfv(WebGLSampler* sampler,
GLfloat param = 0.0f;
gl->MakeCurrent();
gl->fGetSamplerParameterfv(sampler->GLName(), pname, &param);
gl->fGetSamplerParameterfv(sampler->mGLName, pname, &param);
return param;
}
@ -93,7 +102,7 @@ WebGLContextUnchecked::SamplerParameteri(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteri(sampler->GLName(), pname, param);
gl->fSamplerParameteri(sampler->mGLName, pname, param);
}
void
@ -103,7 +112,7 @@ WebGLContextUnchecked::SamplerParameteriv(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteriv(sampler->GLName(), pname, param);
gl->fSamplerParameteriv(sampler->mGLName, pname, param);
}
void
@ -113,7 +122,7 @@ WebGLContextUnchecked::SamplerParameterf(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterf(sampler->GLName(), pname, param);
gl->fSamplerParameterf(sampler->mGLName, pname, param);
}
void
@ -123,7 +132,7 @@ WebGLContextUnchecked::SamplerParameterfv(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterfv(sampler->GLName(), pname, param);
gl->fSamplerParameterfv(sampler->mGLName, pname, param);
}
} // namespace mozilla

View File

@ -1098,15 +1098,15 @@ WebGLContext::AssertCachedBindings()
// Bound object state
if (IsWebGL2()) {
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound);
bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->GLName() : 0;
bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound);
} else {
MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
}
@ -1119,20 +1119,20 @@ WebGLContext::AssertCachedBindings()
AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);
WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
bound = curTex ? curTex->GLName() : 0;
bound = curTex ? curTex->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound);
curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
bound = curTex ? curTex->GLName() : 0;
bound = curTex ? curTex->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound);
// Buffers
bound = mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0;
bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound);
MOZ_ASSERT(mBoundVertexArray);
WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer;
bound = curBuff ? curBuff->GLName() : 0;
bound = curBuff ? curBuff->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound);
MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors());

View File

@ -266,8 +266,10 @@ WebGLContext::ValidateDataRanges(WebGLintptr readOffset, WebGLintptr writeOffset
MOZ_ASSERT((CheckedInt<WebGLsizeiptr>(writeOffset) + size).isValid());
bool separate = (readOffset + size < writeOffset || writeOffset + size < readOffset);
if (!separate)
ErrorInvalidValue("%s: ranges [readOffset, readOffset + size) and [writeOffset, writeOffset + size) overlap");
if (!separate) {
ErrorInvalidValue("%s: ranges [readOffset, readOffset + size) and [writeOffset, "
"writeOffset + size) overlap", info);
}
return separate;
}

View File

@ -51,7 +51,7 @@ WebGLContext::CreateVertexArray()
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLVertexArray> globj = WebGLVertexArray::Create(this);
nsRefPtr<WebGLVertexArray> globj = CreateVertexArrayImpl();
MakeContextCurrent();
globj->GenVertexArray();
@ -59,6 +59,12 @@ WebGLContext::CreateVertexArray()
return globj.forget();
}
WebGLVertexArray*
WebGLContext::CreateVertexArrayImpl()
{
return WebGLVertexArray::Create(this);
}
void
WebGLContext::DeleteVertexArray(WebGLVertexArray* array)
{
@ -86,9 +92,14 @@ WebGLContext::IsVertexArray(WebGLVertexArray* array)
if (!array)
return false;
return ValidateObjectAllowDeleted("isVertexArray", array) &&
!array->IsDeleted() &&
array->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isVertexArray", array))
return false;
if (array->IsDeleted())
return false;
MakeContextCurrent();
return array->IsVertexArray();
}
} // namespace mozilla

View File

@ -93,8 +93,8 @@ WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target,
mContext->MakeContextCurrent();
gl::GLContext* gl = mContext->GL();
gl->fBeginQuery(target, query->GLName());
query->BindTo(LOCAL_GL_TIME_ELAPSED_EXT);
gl->fBeginQuery(target, query->mGLName);
query->mTarget = LOCAL_GL_TIME_ELAPSED_EXT;
mActiveQuery = query;
}
@ -137,8 +137,8 @@ WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
}
mContext->MakeContextCurrent();
mContext->GL()->fQueryCounter(query->GLName(), target);
query->BindTo(LOCAL_GL_TIMESTAMP_EXT);
mContext->GL()->fQueryCounter(query->mGLName, target);
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
}
void
@ -210,7 +210,7 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
switch (pname) {
case LOCAL_GL_QUERY_RESULT_EXT: {
GLuint64 result = 0;
mContext->GL()->fGetQueryObjectui64v(query->GLName(),
mContext->GL()->fGetQueryObjectui64v(query->mGLName,
LOCAL_GL_QUERY_RESULT_EXT,
&result);
retval.set(JS::NumberValue(result));
@ -218,7 +218,7 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
}
case LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT: {
GLuint avail = 0;
mContext->GL()->fGetQueryObjectuiv(query->GLName(),
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
&avail);
retval.set(JS::BooleanValue(bool(avail)));

View File

@ -378,7 +378,7 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
const GLenum imageTarget = ImageTarget().get();
const GLint mipLevel = MipLevel();
const GLuint glName = Texture()->GLName();
const GLuint glName = Texture()->mGLName;
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
@ -404,14 +404,18 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
// WebGLFramebuffer
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
: WebGLBindableName<FBTarget>(fbo)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(fbo)
, mStatus(0)
, mReadBufferMode(LOCAL_GL_COLOR_ATTACHMENT0)
, mColorAttachment0(this, LOCAL_GL_COLOR_ATTACHMENT0)
, mDepthAttachment(this, LOCAL_GL_DEPTH_ATTACHMENT)
, mStencilAttachment(this, LOCAL_GL_STENCIL_ATTACHMENT)
, mDepthStencilAttachment(this, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
#ifdef ANDROID
, mIsFB(false)
#endif
{
mContext->mFramebuffers.insertBack(this);
}
@ -432,6 +436,10 @@ WebGLFramebuffer::Delete()
mContext->MakeContextCurrent();
mContext->gl->fDeleteFramebuffers(1, &mGLName);
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
#ifdef ANDROID
mIsFB = false;
#endif
}
void

View File

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -23,12 +22,13 @@ namespace gl {
class WebGLFramebuffer final
: public nsWrapperCache
, public WebGLBindableName<FBTarget>
, public WebGLRefCountedObject<WebGLFramebuffer>
, public LinkedListElement<WebGLFramebuffer>
, public WebGLContextBoundObject
, public SupportsWeakPtr<WebGLFramebuffer>
{
friend class WebGLContext;
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
@ -53,7 +53,6 @@ public:
}
bool IsDefined() const;
bool IsDeleteRequested() const;
TexInternalFormat EffectiveInternalFormat() const;
@ -99,6 +98,8 @@ public:
FBAttachment attachmentLoc) const;
};
const GLuint mGLName;
private:
mutable GLenum mStatus;
@ -111,6 +112,15 @@ private:
AttachPoint mDepthStencilAttachment;
nsTArray<AttachPoint> mMoreColorAttachments;
#ifdef ANDROID
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
// This shows up on Android 2.3 emulator.
//
// So we track the `is a Framebuffer` state ourselves.
bool mIsFB;
#endif
public:
WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);

View File

@ -47,14 +47,16 @@ WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
: WebGLBindable<RBTarget>()
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mPrimaryRB(0)
, mSecondaryRB(0)
, mInternalFormat(0)
, mInternalFormatForGL(0)
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
, mSamples(1)
#ifdef ANDROID
, mIsRB(false)
#endif
{
mContext->MakeContextCurrent();
@ -75,6 +77,9 @@ WebGLRenderbuffer::Delete()
mContext->gl->fDeleteRenderbuffers(1, &mSecondaryRB);
LinkedListElement<WebGLRenderbuffer>::removeFrom(mContext->mRenderbuffers);
#ifdef ANDROID
mIsRB = false;
#endif
}
int64_t

View File

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
@ -16,7 +15,6 @@ namespace mozilla {
class WebGLRenderbuffer final
: public nsWrapperCache
, public WebGLBindable<RBTarget>
, public WebGLRefCountedObject<WebGLRenderbuffer>
, public LinkedListElement<WebGLRenderbuffer>
, public WebGLRectangleObject
@ -41,6 +39,8 @@ public:
GLsizei Samples() const { return mSamples; }
void SetSamples(GLsizei samples) { mSamples = samples; }
GLuint PrimaryGLName() const { return mPrimaryRB; }
GLenum InternalFormat() const { return mInternalFormat; }
void SetInternalFormat(GLenum internalFormat) {
mInternalFormat = internalFormat;
@ -80,7 +80,16 @@ protected:
GLenum mInternalFormatForGL;
WebGLImageDataStatus mImageDataStatus;
GLsizei mSamples;
#ifdef ANDROID
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
// This shows up on Android 2.3 emulator.
//
// So we track the `is a Renderbuffer` state ourselves.
bool mIsRB;
#endif
friend class WebGLContext;
friend class WebGLFramebuffer;
};

View File

@ -12,8 +12,8 @@
namespace mozilla {
WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler)
: WebGLBindableName<GLenum>(sampler),
WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(sampler)
{
mContext->mSamplers.insertBack(this);
}

View File

@ -8,14 +8,12 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLSampler final
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLSampler>
, public LinkedListElement<WebGLSampler>
, public WebGLContextBoundObject
@ -25,6 +23,8 @@ class WebGLSampler final
public:
explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
const GLuint mGLName;
void Delete();
WebGLContext* GetParentObject() const;

View File

@ -92,6 +92,11 @@ TranslateWithoutValidation(const nsACString& sourceNS, bool isWebGL2,
switch (glesslVersion) {
case 100:
if (!versionStrLen) {
/* According to ARB_ES2_compatibility extension glsl
* should accept #version 100 for ES 2 shaders. */
reversionedSource.insert(versionStrStart, "#version 100\n");
}
break;
case 300:
reversionedSource.insert(versionStrStart, "#version 330\n");

View File

@ -24,8 +24,9 @@ WebGLTexture::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {
}
WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
: WebGLBindableName<TexTarget>(tex)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(tex)
, mTarget(LOCAL_GL_NONE)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
, mWrapS(LOCAL_GL_REPEAT)
@ -142,7 +143,7 @@ WebGLTexture::Bind(TexTarget texTarget)
bool firstTimeThisTextureIsBound = !HasEverBeenBound();
if (firstTimeThisTextureIsBound) {
BindTo(texTarget);
mTarget = texTarget.get();
} else if (texTarget != Target()) {
mContext->ErrorInvalidOperation("bindTexture: This texture has already"
" been bound to a different target.");
@ -152,9 +153,7 @@ WebGLTexture::Bind(TexTarget texTarget)
return;
}
GLuint name = GLName();
mContext->gl->fBindTexture(texTarget.get(), name);
mContext->gl->fBindTexture(texTarget.get(), mGLName);
if (firstTimeThisTextureIsBound) {
mFacesCount = (texTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? 6 : 1;
@ -229,7 +228,7 @@ WebGLTexture::SetCustomMipmap()
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
for(size_t face = 0; face < mFacesCount; ++face) {
for (size_t face = 0; face < mFacesCount; ++face) {
ImageInfoAtFace(face, level) = imageInfo;
}
}
@ -276,8 +275,8 @@ WebGLTexture::IsMipmapCubeComplete() const
return false;
for (int i = 0; i < 6; i++) {
const TexImageTarget face = TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP,
i);
const TexImageTarget face =
TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP, i);
if (!DoesMipmapHaveAllLevelsConsistentlyDefined(face))
return false;
}
@ -626,7 +625,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget,
// Try to clear with glClear.
if (imageTarget == LOCAL_GL_TEXTURE_2D) {
bool cleared = ClearWithTempFB(mContext, GLName(), imageTarget, level,
bool cleared = ClearWithTempFB(mContext, mGLName, imageTarget, level,
imageInfo.mEffectiveInternalFormat,
imageInfo.mHeight, imageInfo.mWidth);
if (cleared) {
@ -637,7 +636,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget,
}
// That didn't work. Try uploading zeros then.
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
gl::ScopedBindTexture autoBindTex(mContext->gl, mGLName, mTarget);
size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat);
MOZ_ASSERT((bitspertexel % 8) == 0); // That would only happen for

View File

@ -12,7 +12,6 @@
#include "mozilla/LinkedList.h"
#include "nsAlgorithm.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -31,7 +30,6 @@ IsPOTAssumingNonnegative(GLsizei x)
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
class WebGLTexture final
: public nsWrapperCache
, public WebGLBindableName<TexTarget>
, public WebGLRefCountedObject<WebGLTexture>
, public LinkedListElement<WebGLTexture>
, public WebGLContextBoundObject
@ -42,6 +40,9 @@ public:
void Delete();
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const {
return Context();
}
@ -62,6 +63,12 @@ protected:
// We store information about the various images that are part of this
// texture. (cubemap faces, mipmap levels)
public:
const GLuint mGLName;
protected:
GLenum mTarget;
public:
class ImageInfo
: public WebGLRectangleObject

View File

@ -20,11 +20,17 @@ WebGLTimerQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint aName)
: WebGLBindableName<QueryBinding>(aName)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(aName)
, mTarget(LOCAL_GL_NONE)
{
}
WebGLTimerQuery::~WebGLTimerQuery()
{
DeleteOnce();
}
WebGLTimerQuery*
WebGLTimerQuery::Create(WebGLContext* webgl)
{
@ -41,6 +47,13 @@ WebGLTimerQuery::Delete()
mContext->gl->fDeleteQueries(1, &mGLName);
}
WebGLContext*
WebGLTimerQuery::GetParentObject() const
{
return Context();
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTimerQuery, AddRef)

View File

@ -14,32 +14,32 @@ namespace mozilla {
class WebGLTimerQuery final
: public nsWrapperCache
, public WebGLBindableName<QueryBinding>
, public WebGLRefCountedObject<WebGLTimerQuery>
, public WebGLContextBoundObject
{
public:
static WebGLTimerQuery* Create(WebGLContext* webgl);
// WebGLRefCountedObject
void Delete();
// nsWrapperCache
WebGLContext* GetParentObject() const {
return Context();
}
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const;
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTimerQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
private:
explicit WebGLTimerQuery(WebGLContext* webgl, GLuint aName);
~WebGLTimerQuery() {
DeleteOnce();
}
~WebGLTimerQuery();
GLenum mTarget;
friend class WebGLExtensionDisjointTimerQuery;
};

View File

@ -13,8 +13,8 @@ namespace mozilla {
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl,
GLuint tf)
: WebGLBindableName<GLenum>(tf)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(tf)
, mMode(LOCAL_GL_NONE)
, mIsActive(false)
, mIsPaused(false)

View File

@ -8,14 +8,12 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLTransformFeedback final
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLTransformFeedback>
, public LinkedListElement<WebGLTransformFeedback>
, public WebGLContextBoundObject
@ -30,11 +28,14 @@ public:
WebGLContext* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLuint mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
private:
~WebGLTransformFeedback();
GLenum mMode;
bool mIsActive;
bool mIsPaused;

View File

@ -21,8 +21,7 @@ WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
: WebGLBindable<VAOBinding>()
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(0)
{
mContext->mVertexArrays.insertBack(this);
@ -50,6 +49,12 @@ WebGLVertexArray::Delete()
mAttribs.Clear();
}
bool
WebGLVertexArray::IsVertexArray()
{
return IsVertexArrayImpl();
}
void
WebGLVertexArray::EnsureAttrib(GLuint index)
{

View File

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLBuffer.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -20,7 +19,6 @@ class WebGLVertexArrayFake;
class WebGLVertexArray
: public nsWrapperCache
, public WebGLBindable<VAOBinding>
, public WebGLRefCountedObject<WebGLVertexArray>
, public LinkedListElement<WebGLVertexArray>
, public WebGLContextBoundObject
@ -31,14 +29,9 @@ public:
void BindVertexArray() {
// Bind to dummy value to signal that this vertex array has ever been
// bound.
BindTo(LOCAL_GL_VERTEX_ARRAY_BINDING);
BindVertexArrayImpl();
};
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) const {
return index < mAttribs.Length();
@ -49,6 +42,7 @@ public:
// Implement parent classes:
void Delete();
bool IsVertexArray();
WebGLContext* GetParentObject() const {
return Context();
@ -68,6 +62,11 @@ protected:
MOZ_ASSERT(IsDeleted());
}
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
virtual bool IsVertexArrayImpl() = 0;
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;

View File

@ -10,6 +10,11 @@
namespace mozilla {
WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
, mIsVAO(false)
{ }
void
WebGLVertexArrayFake::BindVertexArrayImpl()
{
@ -52,6 +57,19 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
mIsVAO = true;
}
void
WebGLVertexArrayFake::DeleteImpl()
{
mIsVAO = false;
}
bool
WebGLVertexArrayFake::IsVertexArrayImpl()
{
return mIsVAO;
}
} // namespace mozilla

View File

@ -13,21 +13,22 @@ namespace mozilla {
class WebGLVertexArrayFake final
: public WebGLVertexArray
{
public:
friend class WebGLVertexArray;
protected:
virtual void BindVertexArrayImpl() override;
virtual void DeleteImpl() override {};
virtual void DeleteImpl() override;
virtual void GenVertexArray() override {};
virtual bool IsVertexArrayImpl() override;
private:
explicit WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
explicit WebGLVertexArrayFake(WebGLContext* webgl);
~WebGLVertexArrayFake() {
DeleteOnce();
}
friend class WebGLVertexArray;
bool mIsVAO;
};
} // namespace mozilla

View File

@ -10,6 +10,18 @@
namespace mozilla {
WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
#if defined(XP_LINUX)
, mIsVAO(false)
#endif
{ }
WebGLVertexArrayGL::~WebGLVertexArrayGL()
{
DeleteOnce();
}
void
WebGLVertexArrayGL::DeleteImpl()
{
@ -17,14 +29,21 @@ WebGLVertexArrayGL::DeleteImpl()
mContext->MakeContextCurrent();
mContext->gl->fDeleteVertexArrays(1, &mGLName);
#if defined(XP_LINUX)
mIsVAO = false;
#endif
}
void
WebGLVertexArrayGL::BindVertexArrayImpl()
{
mContext->mBoundVertexArray = this;
mContext->gl->fBindVertexArray(mGLName);
#if defined(XP_LINUX)
mIsVAO = true;
#endif
}
void
@ -33,4 +52,21 @@ WebGLVertexArrayGL::GenVertexArray()
mContext->gl->fGenVertexArrays(1, &mGLName);
}
bool
WebGLVertexArrayGL::IsVertexArrayImpl()
{
#if defined(XP_LINUX)
gl::GLContext* gl = mContext->gl;
if (gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLVendor::VMware &&
gl->Renderer() == gl::GLRenderer::GalliumLlvmpipe)
{
return mIsVAO;
}
#endif
mContext->MakeContextCurrent();
return mContext->gl->fIsVertexArray(mGLName) != 0;
}
} // namespace mozilla

View File

@ -10,24 +10,28 @@
namespace mozilla {
class WebGLVertexArrayGL final
class WebGLVertexArrayGL
: public WebGLVertexArray
{
friend class WebGLVertexArray;
public:
virtual void DeleteImpl() override;
virtual void BindVertexArrayImpl() override;
virtual void GenVertexArray() override;
virtual bool IsVertexArrayImpl() override;
private:
explicit WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
protected:
explicit WebGLVertexArrayGL(WebGLContext* webgl);
~WebGLVertexArrayGL();
~WebGLVertexArrayGL() {
DeleteOnce();
}
friend class WebGLVertexArray;
#if defined(XP_LINUX)
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
//
// So we track the `is a VAO` state ourselves.
bool mIsVAO;
#endif
};
} // namespace mozilla

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLVertexArrayObject.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
namespace mozilla {
namespace dom {
WebGLVertexArray*
WebGLVertexArrayObject::Create(WebGLContext* webgl)
{
// WebGL 2: This is core in GL ES 3. If support is missing something
// is very wrong.
bool vaoSupport = webgl->GL()->IsSupported(gl::GLFeature::vertex_array_object);
MOZ_RELEASE_ASSERT(vaoSupport, "Vertex Array Objects aren't supported.");
if (vaoSupport)
return new WebGLVertexArrayObject(webgl);
return nullptr;
}
JSObject*
WebGLVertexArrayObject::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto)
{
return dom::WebGLVertexArrayObjectBinding::Wrap(cx, this, givenProto);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_WebGLVertexArrayObject_h
#define mozilla_dom_WebGLVertexArrayObject_h
#include "WebGLVertexArrayGL.h"
namespace mozilla {
namespace dom {
/**
* This class implements the DOM bindings for WebGL 2 VAO.
*
* This exists to so the object returned from gl.createVertexArray()
* is an instance of WebGLVertexArrayObject (to match the WebGL 2
* spec.)
*/
class WebGLVertexArrayObject final
: public WebGLVertexArrayGL
{
public:
static WebGLVertexArray* Create(WebGLContext* webgl);
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
private:
explicit WebGLVertexArrayObject(WebGLContext* webgl)
: WebGLVertexArrayGL(webgl)
{ }
~WebGLVertexArrayObject() {
DeleteOnce();
}
};
} // namespace dom
} // namespace mozilla
#endif // !mozilla_dom_WebGLVertexArrayObject_h

View File

@ -31,6 +31,7 @@ EXPORTS.mozilla.dom += [
'CanvasUtils.h',
'ImageData.h',
'TextMetrics.h',
'WebGLVertexArrayObject.h',
]
# http://support.microsoft.com/kb/143208
@ -128,6 +129,7 @@ UNIFIED_SOURCES += [
'WebGLVertexArray.cpp',
'WebGLVertexArrayFake.cpp',
'WebGLVertexArrayGL.cpp',
'WebGLVertexArrayObject.cpp',
]
LOCAL_INCLUDES += [
'/js/xpconnect/wrappers',

View File

@ -548,14 +548,16 @@ FetchDriver::ContinueHttpFetchAfterNetworkFetch()
}
already_AddRefed<InternalResponse>
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI)
{
MOZ_ASSERT(aResponse);
if (!aResponse->FinalURL()) {
nsAutoCString reqURL;
nsAutoCString reqURL;
if (aFinalURI) {
aFinalURI->GetSpec(reqURL);
} else {
mRequest->GetURL(reqURL);
aResponse->SetUrl(reqURL);
}
aResponse->SetUrl(reqURL);
// FIXME(nsm): Handle mixed content check, step 7 of fetch.
@ -584,7 +586,7 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
void
FetchDriver::BeginResponse(InternalResponse* aResponse)
{
nsRefPtr<InternalResponse> r = BeginAndGetFilteredResponse(aResponse);
nsRefPtr<InternalResponse> r = BeginAndGetFilteredResponse(aResponse, nullptr);
// Release the ref.
}
@ -716,9 +718,17 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
response->InitChannelInfo(channel);
nsCOMPtr<nsIURI> channelURI;
rv = channel->GetURI(getter_AddRefs(channelURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
FailWithNetworkError();
// Cancel request.
return rv;
}
// Resolves fetch() promise which may trigger code running in a worker. Make
// sure the Response is fully initialized before calling this.
mResponse = BeginAndGetFilteredResponse(response);
mResponse = BeginAndGetFilteredResponse(response, channelURI);
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {

View File

@ -88,8 +88,9 @@ private:
nsresult HttpFetch(bool aCORSFlag = false, bool aCORSPreflightFlag = false, bool aAuthenticationFlag = false);
nsresult ContinueHttpFetchAfterNetworkFetch();
// Returns the filtered response sent to the observer.
// Callers who don't have access to a channel can pass null for aFinalURI.
already_AddRefed<InternalResponse>
BeginAndGetFilteredResponse(InternalResponse* aResponse);
BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI);
// Utility since not all cases need to do any post processing of the filtered
// response.
void BeginResponse(InternalResponse* aResponse);

View File

@ -14,7 +14,6 @@ namespace dom {
InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
: mType(ResponseType::Default)
, mFinalURL(false)
, mStatus(aStatus)
, mStatusText(aStatusText)
, mHeaders(new InternalHeaders(HeadersGuardEnum::Response))

View File

@ -48,7 +48,6 @@ public:
response->mType = ResponseType::Opaque;
response->mTerminationReason = mTerminationReason;
response->mURL = mURL;
response->mFinalURL = mFinalURL;
response->mChannelInfo = mChannelInfo;
response->mWrappedResponse = this;
return response.forget();
@ -90,18 +89,6 @@ public:
mURL.Assign(aURL);
}
bool
FinalURL() const
{
return mFinalURL;
}
void
SetFinalURL(bool aFinalURL)
{
mFinalURL = aFinalURL;
}
uint16_t
GetStatus() const
{
@ -197,7 +184,6 @@ private:
copy->mType = mType;
copy->mTerminationReason = mTerminationReason;
copy->mURL = mURL;
copy->mFinalURL = mFinalURL;
copy->mChannelInfo = mChannelInfo;
return copy.forget();
}
@ -205,7 +191,6 @@ private:
ResponseType mType;
nsCString mTerminationReason;
nsCString mURL;
bool mFinalURL;
const uint16_t mStatus;
const nsCString mStatusText;
nsRefPtr<InternalHeaders> mHeaders;

View File

@ -858,7 +858,8 @@ ReadCompressedIndexDataValuesFromBlob(
blobDataIter += keyBufferLength;
if (NS_WARN_IF(!aIndexValues.InsertElementSorted(
IndexDataValue(indexId, unique, Key(keyBuffer))))) {
IndexDataValue(indexId, unique, Key(keyBuffer)),
fallible))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_OUT_OF_MEMORY;
}
@ -2734,7 +2735,8 @@ InsertIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
}
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(indexId, !!unique, value)));
indexValues.InsertElementSorted(IndexDataValue(indexId, !!unique, value),
fallible));
// Compress the array.
UniqueFreePtr<uint8_t> indexValuesBlob;
@ -17856,7 +17858,8 @@ DatabaseOperationBase::IndexDataValuesFromUpdateInfos(
MOZ_ALWAYS_TRUE(aUniqueIndexTable.Get(indexId, &unique));
MOZ_ALWAYS_TRUE(
aIndexValues.InsertElementSorted(IndexDataValue(indexId, unique, key)));
aIndexValues.InsertElementSorted(IndexDataValue(indexId, unique, key),
fallible));
}
return NS_OK;
@ -22291,7 +22294,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
metadata.unique(),
info.value())));
info.value()),
fallible));
}
UniqueFreePtr<uint8_t> indexValuesBlob;
@ -22327,7 +22331,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
metadata.unique(),
info.value())));
info.value()),
fallible));
}
}

View File

@ -133,4 +133,16 @@ AbstractThread::InitStatics()
sCurrentThreadTLS.set(sMainThread);
}
void
AbstractThread::DispatchStateChange(already_AddRefed<nsIRunnable> aRunnable)
{
GetCurrent()->TailDispatcher().AddStateChangeTask(this, Move(aRunnable));
}
/* static */ void
AbstractThread::DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable)
{
GetCurrent()->TailDispatcher().AddDirectTask(Move(aRunnable));
}
} // namespace mozilla

View File

@ -79,6 +79,10 @@ public:
// Must be called exactly once during startup.
static void InitStatics();
void DispatchStateChange(already_AddRefed<nsIRunnable> aRunnable);
static void DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable);
protected:
virtual ~AbstractThread() {}
static ThreadLocal<AbstractThread*> sCurrentThreadTLS;

View File

@ -165,18 +165,10 @@ AudioSink::SetPreservesPitch(bool aPreservesPitch)
}
void
AudioSink::StartPlayback()
AudioSink::SetPlaying(bool aPlaying)
{
AssertCurrentThreadInMonitor();
mPlaying = true;
GetReentrantMonitor().NotifyAll();
}
void
AudioSink::StopPlayback()
{
AssertCurrentThreadInMonitor();
mPlaying = false;
mPlaying = aPlaying;
GetReentrantMonitor().NotifyAll();
}

View File

@ -42,8 +42,7 @@ public:
void SetPlaybackRate(double aPlaybackRate);
void SetPreservesPitch(bool aPreservesPitch);
void StartPlayback();
void StopPlayback();
void SetPlaying(bool aPlaying);
private:
~AudioSink() {}

View File

@ -69,6 +69,19 @@ private:
bool mStreamFinishedOnMainThread;
};
static void
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
{
int32_t delta = aBlocking ? 1 : -1;
if (NS_IsMainThread()) {
aStream->ChangeExplicitBlockerCount(delta);
} else {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
AbstractThread::MainThread()->Dispatch(r.forget());
}
}
DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
: mAudioFramesWritten(0)
, mNextVideoTime(-1)
@ -78,14 +91,13 @@ DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
, mHaveSentFinishAudio(false)
, mHaveSentFinishVideo(false)
, mStream(aStream)
, mHaveBlockedForPlayState(false)
, mHaveBlockedForStateMachineNotPlaying(false)
, mPlaying(false)
, mEOSVideoCompensation(false)
{
mListener = new DecodedStreamGraphListener(mStream);
mStream->AddListener(mListener);
// Block the stream until the initialization is done.
mStream->ChangeExplicitBlockerCount(1);
// Block the stream as mPlaying is initially false.
UpdateStreamBlocking(mStream, true);
}
DecodedStreamData::~DecodedStreamData()
@ -106,6 +118,15 @@ DecodedStreamData::GetPosition() const
return mListener->GetLastOutputTime();
}
void
DecodedStreamData::SetPlaying(bool aPlaying)
{
if (mPlaying != aPlaying) {
mPlaying = aPlaying;
UpdateStreamBlocking(mStream, !mPlaying);
}
}
class OutputStreamListener : public MediaStreamListener {
typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
public:
@ -290,4 +311,12 @@ DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
}
}
void
DecodedStream::SetPlaying(bool aPlaying)
{
GetReentrantMonitor().AssertCurrentThreadIn();
MOZ_ASSERT(mData);
mData->SetPlaying(aPlaying);
}
} // namespace mozilla

View File

@ -41,6 +41,7 @@ public:
~DecodedStreamData();
bool IsFinished() const;
int64_t GetPosition() const;
void SetPlaying(bool aPlaying);
/* The following group of fields are protected by the decoder's monitor
* and can be read or written on any thread.
@ -66,12 +67,7 @@ public:
// The decoder is responsible for calling Destroy() on this stream.
const nsRefPtr<SourceMediaStream> mStream;
nsRefPtr<DecodedStreamGraphListener> mListener;
// True when we've explicitly blocked this stream because we're
// not in PLAY_STATE_PLAYING. Used on the main thread only.
bool mHaveBlockedForPlayState;
// We also have an explicit blocker on the stream when
// mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
bool mHaveBlockedForStateMachineNotPlaying;
bool mPlaying;
// True if we need to send a compensation video frame to ensure the
// StreamTime going forward.
bool mEOSVideoCompensation;
@ -96,6 +92,7 @@ public:
nsTArray<OutputStreamData>& OutputStreams();
ReentrantMonitor& GetReentrantMonitor() const;
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
void SetPlaying(bool aPlaying);
private:
void Connect(OutputStreamData* aStream);

View File

@ -639,7 +639,8 @@ MediaRawDataWriter::Prepend(const uint8_t* aData, size_t aSize)
}
// We ensure sufficient capacity above so this shouldn't fail.
MOZ_ALWAYS_TRUE(mBuffer->InsertElementsAt(mTarget->mPadding, aData, aSize));
MOZ_ALWAYS_TRUE(mBuffer->InsertElementsAt(mTarget->mPadding, aData, aSize,
fallible));
mTarget->mSize += aSize;
mSize = mTarget->mSize;
return true;

View File

@ -272,6 +272,14 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
// timeEndPeriod() call.
timeBeginPeriod(1);
#endif
AudioQueue().AddPopListener(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioPopped),
mTaskQueue);
VideoQueue().AddPopListener(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnVideoPopped),
mTaskQueue);
}
MediaDecoderStateMachine::~MediaDecoderStateMachine()
@ -314,8 +322,6 @@ MediaDecoderStateMachine::InitializationTask()
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
}
bool MediaDecoderStateMachine::HasFutureAudio()
@ -430,19 +436,6 @@ static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
return lastVideoStratTime == aInput.GetDuration();
}
static void
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
{
int32_t delta = aBlocking ? 1 : -1;
if (NS_IsMainThread()) {
aStream->ChangeExplicitBlockerCount(delta);
} else {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
AbstractThread::MainThread()->Dispatch(r.forget());
}
}
void MediaDecoderStateMachine::SendStreamData()
{
MOZ_ASSERT(OnTaskQueue());
@ -481,12 +474,6 @@ void MediaDecoderStateMachine::SendStreamData()
}
mediaStream->FinishAddTracks();
stream->mStreamInitialized = true;
// Make sure stream blocking is updated before sending stream data so we
// don't 'leak' data when the stream is supposed to be blocked.
UpdateStreamBlockingForPlayState();
UpdateStreamBlockingForStateMachinePlaying();
UpdateStreamBlocking(mediaStream, false);
}
if (mInfo.HasAudio()) {
@ -513,6 +500,12 @@ void MediaDecoderStateMachine::SendStreamData()
endPosition = std::max(endPosition,
mediaStream->TicksToTimeRoundDown(mInfo.mAudio.mRate,
stream->mAudioFramesWritten));
CheckedInt64 playedUsecs = mStreamStartTime +
FramesToUsecs(stream->mAudioFramesWritten, mInfo.mAudio.mRate);
if (playedUsecs.isValid()) {
OnAudioEndTimeUpdate(playedUsecs.value());
}
}
if (mInfo.HasVideo()) {
@ -601,8 +594,7 @@ void MediaDecoderStateMachine::SendStreamData()
// Therefore we only discard those behind the stream clock to throttle
// the decoding speed.
if (a && a->mTime <= clockTime) {
OnAudioEndTimeUpdate(std::max(mAudioEndTime, a->GetEndTime()));
nsRefPtr<AudioData> releaseMe = PopAudio();
nsRefPtr<AudioData> releaseMe = AudioQueue().PopFront();
continue;
}
break;
@ -926,22 +918,25 @@ MediaDecoderStateMachine::PushFront(VideoData* aSample)
UpdateNextFrameStatus();
}
already_AddRefed<AudioData>
MediaDecoderStateMachine::PopAudio()
void
MediaDecoderStateMachine::OnAudioPopped()
{
MOZ_ASSERT(OnTaskQueue());
nsRefPtr<AudioData> sample = AudioQueue().PopFront();
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
UpdateNextFrameStatus();
return sample.forget();
DispatchAudioDecodeTaskIfNeeded();
}
already_AddRefed<VideoData>
MediaDecoderStateMachine::PopVideo()
void
MediaDecoderStateMachine::OnVideoPopped()
{
MOZ_ASSERT(OnTaskQueue());
nsRefPtr<VideoData> sample = VideoQueue().PopFront();
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
UpdateNextFrameStatus();
return sample.forget();
DispatchVideoDecodeTaskIfNeeded();
// Notify the decode thread that the video queue's buffers may have
// free'd up space for more frames.
mDecoder->GetReentrantMonitor().NotifyAll();
}
void
@ -1295,7 +1290,6 @@ void MediaDecoderStateMachine::StopPlayback()
// so it can pause audio playback.
mDecoder->GetReentrantMonitor().NotifyAll();
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
UpdateStreamBlockingForStateMachinePlaying();
DispatchDecodeTasksIfNeeded();
}
@ -1333,7 +1327,6 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
NS_ENSURE_SUCCESS_VOID(rv);
mDecoder->GetReentrantMonitor().NotifyAll();
UpdateStreamBlockingForStateMachinePlaying();
DispatchDecodeTasksIfNeeded();
}
@ -2306,17 +2299,6 @@ MediaDecoderStateMachine::DecodeFirstFrame()
MOZ_ASSERT(mState == DECODER_STATE_DECODING_FIRSTFRAME);
DECODER_LOG("DecodeFirstFrame started");
if (HasAudio()) {
RefPtr<nsIRunnable> decodeTask(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DispatchAudioDecodeTaskIfNeeded));
AudioQueue().AddPopListener(decodeTask, TaskQueue());
}
if (HasVideo()) {
RefPtr<nsIRunnable> decodeTask(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded));
VideoQueue().AddPopListener(decodeTask, TaskQueue());
}
if (IsRealTime()) {
SetStartTime(0);
nsresult res = FinishDecodeFirstFrame();
@ -2948,10 +2930,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
currentFrame->mTime, clock_time, ++droppedFrames);
}
currentFrame = frame;
nsRefPtr<VideoData> releaseMe = PopVideo();
// Notify the decode thread that the video queue's buffers may have
// free'd up space for more frames.
mDecoder->GetReentrantMonitor().NotifyAll();
nsRefPtr<VideoData> releaseMe = VideoQueue().PopFront();
OnPlaybackOffsetUpdate(frame->mOffset);
if (VideoQueue().GetSize() == 0)
break;
@ -3296,13 +3275,11 @@ void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
{
AssertCurrentThreadInMonitor();
mPlayStartTime = aTimeStamp;
if (!mAudioSink) {
return;
}
if (!mPlayStartTime.IsNull()) {
mAudioSink->StartPlayback();
} else {
mAudioSink->StopPlayback();
if (mAudioSink) {
mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
} else if (mAudioCaptured) {
mDecodedStream.SetPlaying(!mPlayStartTime.IsNull());
}
}
@ -3505,6 +3482,9 @@ void MediaDecoderStateMachine::DispatchAudioCaptured()
// the 1st frame. But this is OK since we will update mStreamStartTime
// again in SetStartTime().
self->mStreamStartTime = self->GetMediaTime();
// Reset mAudioEndTime which will be updated as we send audio data to
// stream. Otherwise it will remain -1 if we don't have audio.
self->mAudioEndTime = -1;
self->mAudioCaptured = true;
self->ScheduleStateMachine();
}
@ -3526,44 +3506,12 @@ void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
DispatchAudioCaptured();
}
void MediaDecoderStateMachine::UpdateStreamBlockingForPlayState()
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
auto stream = GetDecodedStream();
if (!stream) {
return;
}
bool blocking = mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
mLogicallySeeking;
if (blocking != stream->mHaveBlockedForPlayState) {
stream->mHaveBlockedForPlayState = blocking;
UpdateStreamBlocking(stream->mStream, blocking);
}
}
void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
{
AssertCurrentThreadInMonitor();
auto stream = GetDecodedStream();
if (!stream) {
return;
}
bool blocking = !IsPlaying();
if (blocking != stream->mHaveBlockedForStateMachineNotPlaying) {
stream->mHaveBlockedForStateMachineNotPlaying = blocking;
UpdateStreamBlocking(stream->mStream, blocking);
}
}
void MediaDecoderStateMachine::RecreateDecodedStream(MediaStreamGraph* aGraph)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecodedStream.RecreateData(aGraph);
mDecodedStream.SetPlaying(IsPlaying());
}
} // namespace mozilla

View File

@ -162,13 +162,6 @@ private:
void DispatchAudioCaptured();
// Update blocking state of mDecodedStream when mPlayState or
// mLogicallySeeking change. Decoder monitor must be held.
void UpdateStreamBlockingForPlayState();
// Call this IsPlaying() changes. Decoder monitor must be held.
void UpdateStreamBlockingForStateMachinePlaying();
// Recreates mDecodedStream. Call this to create mDecodedStream at first,
// and when seeking, to ensure a new stream is set up with fresh buffers.
// Decoder monitor must be held.
@ -427,12 +420,8 @@ protected:
void PushFront(AudioData* aSample);
void PushFront(VideoData* aSample);
// Pops MediaData* samples from their respective MediaQueues.
// Note that the audio queue is also drained on the audio thread,
// which we can't easily react to - This should be fixed when we
// remove the audio thread in bug 750596.
already_AddRefed<AudioData> PopAudio();
already_AddRefed<VideoData> PopVideo();
void OnAudioPopped();
void OnVideoPopped();
void VolumeChanged();
void LogicalPlaybackRateChanged();

View File

@ -197,7 +197,7 @@ private:
// updates at all if the value ends up where it started.
if (!alreadyNotifying) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(this, &Impl::DoNotify);
AbstractThread::GetCurrent()->TailDispatcher().AddDirectTask(r.forget());
AbstractThread::DispatchDirectTask(r.forget());
}
}
@ -222,7 +222,7 @@ private:
}
for (size_t i = 0; i < mMirrors.Length(); ++i) {
OwnerThread()->TailDispatcher().AddStateChangeTask(mMirrors[i]->OwnerThread(), MakeNotifier(mMirrors[i]));
mMirrors[i]->OwnerThread()->DispatchStateChange(MakeNotifier(mMirrors[i]));
}
}

View File

@ -60,6 +60,10 @@ TrialCreatePrefName(const nsAString& aKeySystem)
GMPVideoDecoderTrialCreator::TrialCreateState
GMPVideoDecoderTrialCreator::GetCreateTrialState(const nsAString& aKeySystem)
{
if (Preferences::GetBool("media.gmp.always-trial-create", false)) {
return Pending;
}
const char* pref = TrialCreatePrefName(aKeySystem);
if (!pref) {
return Pending;

View File

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "gmp-entrypoints.h"
#include "prlink.h"
#include "prenv.h"
#include <string>
@ -168,22 +169,25 @@ GMPLoaderImpl::Load(const char* aLibPath,
if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
return false;
}
// We've successfully bound the origin salt to node id.
// rlz_lib::GetRawMachineId and/or the system functions it
// called could have left user identifiable data on the stack,
// so carefully zero the stack down to the guard page.
uint8_t* top;
uint8_t* bottom;
if (!GetStackAfterCurrentFrame(&top, &bottom)) {
return false;
}
assert(top >= bottom);
// Inline instructions equivalent to RtlSecureZeroMemory().
// We can't just use RtlSecureZeroMemory here directly, as in debug
// builds, RtlSecureZeroMemory() can't be inlined, and the stack
// memory it uses would get wiped by itself running, causing crashes.
for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
*p = 0;
if (!PR_GetEnv("MOZ_GMP_DISABLE_NODE_ID_CLEANUP")) {
// We've successfully bound the origin salt to node id.
// rlz_lib::GetRawMachineId and/or the system functions it
// called could have left user identifiable data on the stack,
// so carefully zero the stack down to the guard page.
uint8_t* top;
uint8_t* bottom;
if (!GetStackAfterCurrentFrame(&top, &bottom)) {
return false;
}
assert(top >= bottom);
// Inline instructions equivalent to RtlSecureZeroMemory().
// We can't just use RtlSecureZeroMemory here directly, as in debug
// builds, RtlSecureZeroMemory() can't be inlined, and the stack
// memory it uses would get wiped by itself running, causing crashes.
for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
*p = 0;
}
}
} else
#endif

View File

@ -237,7 +237,8 @@ TCPSocketChild::SendSend(JS::Handle<JS::Value> aData,
if (!data) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes)) {
if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes,
fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}

View File

@ -311,7 +311,7 @@ TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle<JS::Value> aDataVa
errLine = __LINE__;
break;
}
if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) {
if (!fallibleArr.InsertElementsAt(0, buffer, nbytes, fallible)) {
errLine = __LINE__;
break;
}

View File

@ -249,7 +249,7 @@ UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr,
NS_ENSURE_ARG(aData);
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -451,7 +451,7 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage
}
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
if (!fallibleArray.InsertElementsAt(0, buffer, len, fallible)) {
FireInternalError(__LINE__);
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -5098,7 +5098,9 @@ OriginParser::HandleToken(const nsDependentCSubstring& aToken)
return;
}
mState = eExpectingDriveLetterOrPathnameComponent;
mState =
mTokenizer.hasMoreTokens() ? eExpectingDriveLetterOrPathnameComponent
: eComplete;
return;
}
@ -5216,7 +5218,7 @@ OriginParser::HandleToken(const nsDependentCSubstring& aToken)
void
OriginParser::HandleTrailingSeparator()
{
MOZ_ASSERT(mState = eComplete);
MOZ_ASSERT(mState == eComplete);
MOZ_ASSERT(mSchemaType == eFile);
mPathnameComponents.AppendElement(EmptyCString());

View File

@ -385,7 +385,8 @@ DOMSVGPathSegList::InsertItemBefore(DOMSVGPathSeg& aNewItem,
MOZ_ALWAYS_TRUE(InternalList().mData.InsertElementsAt(internalIndex,
segAsRaw,
1 + argCount));
1 + argCount,
fallible));
MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex,
ItemProxy(domItem.get(),
internalIndex),

View File

@ -27,12 +27,10 @@ skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = buildapp == 'b2g' # Bug 1137683
[test_fetch_basic_http.html]
[test_fetch_basic_http_sw_reroute.html]
skip-if = true # Bug 1170937, need fully support for redirects
#skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g
[test_fetch_cors.html]
[test_fetch_cors_sw_reroute.html]
skip-if = true # Bug 1170937, need fully support for redirects
#skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g
[test_formdataparsing.html]
[test_formdataparsing_sw_reroute.html]
skip-if = buildapp == 'b2g' # Bug 1137683

View File

@ -26,11 +26,9 @@ interface WebGLSync {
interface WebGLTransformFeedback {
};
/*
[Pref="webgl.enable-prototype-webgl2"]
interface WebGLVertexArrayObject {
};
*/
[Pref="webgl.enable-prototype-webgl2"]
interface WebGL2RenderingContext : WebGLRenderingContext
@ -238,7 +236,6 @@ interface WebGL2RenderingContext : WebGLRenderingContext
const GLenum RGB8_SNORM = 0x8F96;
const GLenum RGBA8_SNORM = 0x8F97;
const GLenum SIGNED_NORMALIZED = 0x8F9C;
const GLenum PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69;
const GLenum COPY_READ_BUFFER = 0x8F36;
const GLenum COPY_WRITE_BUFFER = 0x8F37;
const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; /* Same as COPY_READ_BUFFER */
@ -291,10 +288,6 @@ interface WebGL2RenderingContext : WebGLRenderingContext
const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
const GLenum SAMPLER_BINDING = 0x8919;
const GLenum RGB10_A2UI = 0x906F;
const GLenum TEXTURE_SWIZZLE_R = 0x8E42;
const GLenum TEXTURE_SWIZZLE_G = 0x8E43;
const GLenum TEXTURE_SWIZZLE_B = 0x8E44;
const GLenum TEXTURE_SWIZZLE_A = 0x8E45;
const GLenum GREEN = 0x1904;
const GLenum BLUE = 0x1905;
const GLenum INT_2_10_10_10_REV = 0x8D9F;
@ -475,10 +468,8 @@ interface WebGL2RenderingContext : WebGLRenderingContext
void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
/* Vertex Array Objects */
/*
WebGLVertexArrayObject? createVertexArray();
void deleteVertexArray(WebGLVertexArrayObject? vertexArray);
[WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray);
void bindVertexArray(WebGLVertexArrayObject? array);
*/
};

View File

@ -983,9 +983,11 @@ private:
// If the load principal is the system principal then the channel
// principal must also be the system principal (we do not allow chrome
// code to create workers with non-chrome scripts). Otherwise this channel
// principal must be same origin with the load principal (we check again
// here in case redirects changed the location of the script).
// code to create workers with non-chrome scripts, and if we ever decide
// to change this we need to make sure we don't always set
// mPrincipalIsSystem to true in WorkerPrivate::GetLoadInfo()). Otherwise
// this channel principal must be same origin with the load principal (we
// check again here in case redirects changed the location of the script).
if (nsContentUtils::IsSystemPrincipal(loadPrincipal)) {
if (!nsContentUtils::IsSystemPrincipal(channelPrincipal)) {
// See if this is a resource URI. Since JSMs usually come from

View File

@ -4885,12 +4885,15 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
return NS_ERROR_DOM_SECURITY_ERR;
}
// Chrome callers (whether ChromeWorker of Worker) always get the system
// principal here as they're allowed to load anything. The script loader may
// change the principal later depending on the script uri.
// Chrome callers (whether creating a ChromeWorker or Worker) always get the
// system principal here as they're allowed to load anything. The script
// loader will refuse to run any script that does not also have the system
// principal.
if (isChrome) {
rv = ssm->GetSystemPrincipal(getter_AddRefs(loadInfo.mPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
loadInfo.mPrincipalIsSystem = true;
}
// See if we're being called from a window.

View File

@ -1964,7 +1964,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = aTexture->QueryInterface((IDXGISurface**)byRef(surface));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to QI texture to surface. Code: " << hr;
gfxCriticalError() << "Failed to QI texture to surface. Code: " << hexa(hr);
return nullptr;
}
@ -1982,7 +1982,8 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to create D2D render target for texture. Code:" << hr << " " << mSize << " Format: " << uint32_t(aFormat);
gfxCriticalError() << "Failed to create D2D render target for texture. Code: "
<< hexa(hr) << " " << mSize << " Format: " << uint32_t(aFormat);
return nullptr;
}

View File

@ -413,7 +413,8 @@ CompositorD3D11::GetTextureFactoryIdentifier()
if (mAttachments->mSyncTexture) {
HRESULT hr = mAttachments->mSyncTexture->GetSharedHandle(&ident.mSyncHandle);
if (FAILED(hr) || !ident.mSyncHandle) {
gfxCriticalError() << "Failed to get SharedHandle for sync texture. Result: " << hr;
gfxCriticalError() << "Failed to get SharedHandle for sync texture. Result: "
<< hexa(hr);
MOZ_CRASH();
}
}
@ -1342,7 +1343,7 @@ CompositorD3D11::UpdateConstantBuffers()
hr = mContext->Map(mAttachments->mVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
if (Failed(hr) || !resource.pData) {
gfxCriticalError() << "Failed to map VSConstantBuffer. Result: " << hr;
gfxCriticalError() << "Failed to map VSConstantBuffer. Result: " << hexa(hr);
return false;
}
*(VertexShaderConstants*)resource.pData = mVSConstants;
@ -1351,7 +1352,7 @@ CompositorD3D11::UpdateConstantBuffers()
hr = mContext->Map(mAttachments->mPSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
if (Failed(hr) || !resource.pData) {
gfxCriticalError() << "Failed to map PSConstantBuffer. Result: " << hr;
gfxCriticalError() << "Failed to map PSConstantBuffer. Result: " << hexa(hr);
return false;
}
*(PixelShaderConstants*)resource.pData = mPSConstants;

View File

@ -910,7 +910,10 @@ gfxFontconfigFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
#endif
gfxFcPlatformFontList::gfxFcPlatformFontList()
: mLocalNames(64), mGenericMappings(32), mLastConfig(nullptr)
: mLocalNames(64)
, mGenericMappings(32)
, mFcSubstituteCache(64)
, mLastConfig(nullptr)
{
// if the rescan interval is set, start the timer
int rescanInterval = FcConfigGetRescanInterval(nullptr);
@ -1036,6 +1039,8 @@ gfxFcPlatformFontList::InitFontList()
mLocalNames.Clear();
mGenericMappings.Clear();
mFcSubstituteCache.Clear();
sSentinelFirstFamily = nullptr;
// iterate over available fonts
FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem);
@ -1048,7 +1053,6 @@ gfxFcPlatformFontList::InitFontList()
#endif
mOtherFamilyNamesInitialized = true;
sSentinelFirstFamily = nullptr;
return NS_OK;
}
@ -1240,6 +1244,14 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
// In this case fontconfig is including Tex Gyre Heros and
// Nimbus Sans L as alternatives for Helvetica.
// Because the FcConfigSubstitute call is quite expensive, we cache the
// actual font family found via this process. So check the cache first:
NS_ConvertUTF16toUTF8 familyToFind(familyName);
gfxFontFamily* cached = mFcSubstituteCache.GetWeak(familyToFind);
if (cached) {
return cached;
}
const FcChar8* kSentinelName = ToFcChar8Ptr("-moz-sentinel");
if (!sSentinelFirstFamily) {
nsAutoRef<FcPattern> sentinelSubst(FcPatternCreate());
@ -1250,7 +1262,6 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
// substitutions for font, -moz-sentinel pattern
nsAutoRef<FcPattern> fontWithSentinel(FcPatternCreate());
NS_ConvertUTF16toUTF8 familyToFind(familyName);
FcPatternAddString(fontWithSentinel, FC_FAMILY, ToFcChar8Ptr(familyToFind.get()));
FcPatternAddString(fontWithSentinel, FC_FAMILY, kSentinelName);
FcConfigSubstitute(nullptr, fontWithSentinel, FcMatchPattern);
@ -1269,6 +1280,9 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
}
gfxFontFamily* foundFamily = gfxPlatformFontList::FindFamily(subst);
if (foundFamily) {
// We've figured out what family the given name maps to, after any
// fontconfig subsitutions. Cache it to speed up future lookups.
mFcSubstituteCache.Put(familyToFind, foundFamily);
return foundFamily;
}
}

View File

@ -256,6 +256,9 @@ protected:
// caching generic/lang ==> font family
nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> mGenericMappings;
// caching family lookups as found by FindFamily after resolving substitutions
nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> mFcSubstituteCache;
nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
nsCountedRef<FcConfig> mLastConfig;

View File

@ -1980,7 +1980,7 @@ gfxWindowsPlatform::InitD3D11Devices()
if (FAILED(hr)) {
// This should always succeed... in theory.
gfxCriticalError() << "Failed to initialize WARP D3D11 device!" << hr;
gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
return;
}

View File

@ -214,7 +214,7 @@ BluetoothDaemonPDUConsumer::~BluetoothDaemonPDUConsumer()
class BluetoothDaemonConnectionIO final : public ConnectionOrientedSocketIO
{
public:
BluetoothDaemonConnectionIO(nsIThread* aConsumerThread,
BluetoothDaemonConnectionIO(MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
int aFd, ConnectionStatus aConnectionStatus,
UnixSocketConnector* aConnector,
@ -247,14 +247,14 @@ private:
};
BluetoothDaemonConnectionIO::BluetoothDaemonConnectionIO(
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
int aFd,
ConnectionStatus aConnectionStatus,
UnixSocketConnector* aConnector,
BluetoothDaemonConnection* aConnection,
BluetoothDaemonPDUConsumer* aConsumer)
: ConnectionOrientedSocketIO(aConsumerThread,
: ConnectionOrientedSocketIO(aConsumerLoop,
aIOLoop,
aFd,
aConnectionStatus,
@ -361,7 +361,7 @@ BluetoothDaemonConnection::~BluetoothDaemonConnection()
nsresult
BluetoothDaemonConnection::PrepareAccept(UnixSocketConnector* aConnector,
nsIThread* aConsumerThread,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
ConnectionOrientedSocketIO*& aIO)
{
@ -370,7 +370,7 @@ BluetoothDaemonConnection::PrepareAccept(UnixSocketConnector* aConnector,
SetConnectionStatus(SOCKET_CONNECTING);
mIO = new BluetoothDaemonConnectionIO(
aConsumerThread, aIOLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
aConsumerLoop, aIOLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
aConnector, this, mPDUConsumer);
aIO = mIO;

Some files were not shown because too many files have changed in this diff Show More