Merge m-c to fx-team. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-08-01 16:08:39 -04:00
commit 35cd2b1e5e
219 changed files with 4820 additions and 2361 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Multiple bugs that happened to trigger bug 1042115.
Bug 1046585 moved files to a different directory and required a clobber.

View File

@ -219,6 +219,7 @@ ifdef MOZ_CRASHREPORTER
echo building symbol store
$(RM) -r $(DIST)/crashreporter-symbols
$(RM) '$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip'
$(RM) '$(DIST)/$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
$(NSINSTALL) -D $(DIST)/crashreporter-symbols
OBJCOPY='$(OBJCOPY)' \
$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \

View File

@ -1,9 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# The midl generated code include Windows headers which defines min and max
# macros which conflicts with std::min/max. Suppress the macros:
OS_CXXFLAGS += -DNOMINMAX
include $(topsrcdir)/config/rules.mk

View File

@ -45,3 +45,8 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul'
# The midl generated code include Windows headers which defines min and max
# macros which conflicts with std::min/max. Suppress the macros:
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['NOMINMAX'] = True

View File

@ -1,9 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# The midl generated code include Windows headers which defines min and max
# macros which conflicts with std::min/max. Suppress the macros:
OS_CXXFLAGS += -DNOMINMAX
include $(topsrcdir)/config/rules.mk

View File

@ -18,3 +18,8 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul'
# The midl generated code include Windows headers which defines min and max
# macros which conflicts with std::min/max. Suppress the macros:
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['NOMINMAX'] = True

248
b2g/app/B2GLoader.cpp Normal file
View File

@ -0,0 +1,248 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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 "nsXULAppAPI.h"
#include "application.ini.h"
#include "nsXPCOMGlue.h"
#include "nsStringGlue.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "BinaryPath.h"
#include "nsAutoPtr.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <dlfcn.h>
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#define ASSERT(x) if (!(x)) { MOZ_CRASH(); }
// Functions being loaded by XPCOMGlue
XRE_ProcLoaderServiceRunType XRE_ProcLoaderServiceRun;
XRE_ProcLoaderClientInitType XRE_ProcLoaderClientInit;
XRE_ProcLoaderPreloadType XRE_ProcLoaderPreload;
extern XRE_CreateAppDataType XRE_CreateAppData;
extern XRE_GetFileFromPathType XRE_GetFileFromPath;
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_ProcLoaderServiceRun", (NSFuncPtr*) &XRE_ProcLoaderServiceRun },
{ "XRE_ProcLoaderClientInit", (NSFuncPtr*) &XRE_ProcLoaderClientInit },
{ "XRE_ProcLoaderPreload", (NSFuncPtr*) &XRE_ProcLoaderPreload },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ nullptr, nullptr }
};
static int
GetDirnameSlash(const char *aPath, char *aOutDir, int aMaxLen)
{
char *lastSlash = strrchr(aPath, XPCOM_FILE_PATH_SEPARATOR[0]);
if (lastSlash == nullptr) {
return 0;
}
int cpsz = lastSlash - aPath + 1; // include slash
if (aMaxLen <= cpsz) {
return 0;
}
strncpy(aOutDir, aPath, cpsz);
aOutDir[cpsz] = 0;
return cpsz;
}
static bool
GetXPCOMPath(const char *aProgram, char *aOutPath, int aMaxLen)
{
nsAutoArrayPtr<char> progBuf(new char[aMaxLen]);
nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf);
NS_ENSURE_SUCCESS(rv, false);
int len = GetDirnameSlash(progBuf, aOutPath, aMaxLen);
NS_ENSURE_TRUE(!!len, false);
NS_ENSURE_TRUE((len + sizeof(XPCOM_DLL)) < aMaxLen, false);
char *afterSlash = aOutPath + len;
strcpy(afterSlash, XPCOM_DLL);
return true;
}
static bool
LoadLibxul(const char *aXPCOMPath)
{
nsresult rv;
XPCOMGlueEnablePreload();
rv = XPCOMGlueStartup(aXPCOMPath);
NS_ENSURE_SUCCESS(rv, false);
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
/**
* Return true if |arg| matches the given argument name.
*/
static bool
IsArg(const char* arg, const char* s)
{
if (*arg == '-') {
if (*++arg == '-') {
++arg;
}
return !strcasecmp(arg, s);
}
#if defined(XP_WIN)
if (*arg == '/') {
return !strcasecmp(++arg, s);
}
#endif
return false;
}
static already_AddRefed<nsIFile>
GetAppIni(int argc, const char *argv[])
{
nsCOMPtr<nsIFile> appini;
nsresult rv;
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
// Note that -app must be the *first* argument.
const char *appDataFile = getenv("XUL_APP_FILE");
if (appDataFile && *appDataFile) {
rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
NS_ENSURE_SUCCESS(rv, nullptr);
} else if (argc > 1 && IsArg(argv[1], "app")) {
if (argc == 2) {
return nullptr;
}
rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
NS_ENSURE_SUCCESS(rv, nullptr);
char appEnv[MAXPATHLEN];
snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
if (putenv(appEnv)) {
return nullptr;
}
}
return appini.forget();
}
static bool
LoadStaticData(int argc, const char *argv[])
{
char xpcomPath[MAXPATHLEN];
bool ok = GetXPCOMPath(argv[0], xpcomPath, MAXPATHLEN);
NS_ENSURE_TRUE(ok, false);
ok = LoadLibxul(xpcomPath);
NS_ENSURE_TRUE(ok, false);
char progDir[MAXPATHLEN];
ok = GetDirnameSlash(xpcomPath, progDir, MAXPATHLEN);
NS_ENSURE_TRUE(ok, false);
nsCOMPtr<nsIFile> appini = GetAppIni(argc, argv);
const nsXREAppData *appData;
if (appini) {
nsresult rv =
XRE_CreateAppData(appini, const_cast<nsXREAppData**>(&appData));
NS_ENSURE_SUCCESS(rv, false);
} else {
appData = &sAppData;
}
XRE_ProcLoaderPreload(progDir, appData);
if (appini) {
XRE_FreeAppData(const_cast<nsXREAppData*>(appData));
}
return true;
}
/**
* Fork and run parent and child process.
*
* The parent is the b2g process and child for Nuwa.
*/
static int
RunProcesses(int argc, const char *argv[])
{
/*
* The original main() of the b2g process. It is renamed to
* b2g_main() for the b2g loader.
*/
int b2g_main(int argc, const char *argv[]);
int ipcSockets[2] = {-1, -1};
int r = socketpair(AF_LOCAL, SOCK_STREAM, 0, ipcSockets);
ASSERT(r == 0);
int parentSock = ipcSockets[0];
int childSock = ipcSockets[1];
r = fcntl(parentSock, F_SETFL, O_NONBLOCK);
ASSERT(r != -1);
r = fcntl(childSock, F_SETFL, O_NONBLOCK);
ASSERT(r != -1);
pid_t pid = fork();
ASSERT(pid >= 0);
bool isChildProcess = pid == 0;
close(isChildProcess ? parentSock : childSock);
if (isChildProcess) {
/* The Nuwa process */
/* This provides the IPC service of loading Nuwa at the process.
* The b2g process would send a IPC message of loading Nuwa
* as the replacement of forking and executing plugin-container.
*/
return XRE_ProcLoaderServiceRun(getppid(), childSock, argc, argv);
}
// The b2g process
int childPid = pid;
XRE_ProcLoaderClientInit(childPid, parentSock);
return b2g_main(argc, argv);
}
/**
* B2G Loader is responsible for loading the b2g process and the
* Nuwa process. It forks into the parent process, for the b2g
* process, and the child process, for the Nuwa process.
*
* The loader loads libxul and performs initialization of static data
* before forking, so relocation of libxul and static data can be
* shared between the b2g process, the Nuwa process, and the content
* processes.
*/
int
main(int argc, const char* argv[])
{
const char *program = argv[0];
/*
* Before fork(), libxul and static data of Gecko are loaded for
* sharing.
*/
bool ok = LoadStaticData(argc, argv);
if (!ok) {
return 255;
}
return RunProcesses(argc, argv);
}

View File

@ -9,6 +9,11 @@ if not CONFIG['LIBXUL_SDK']:
PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin"
else:
PROGRAM = CONFIG['MOZ_APP_NAME']
if CONFIG['MOZ_B2G_LOADER']:
SOURCES += [
'B2GLoader.cpp',
]
SOURCES += [
'nsBrowserApp.cpp',
]

View File

@ -17,6 +17,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "nsCOMPtr.h"
#include "nsIFile.h"
@ -163,9 +164,22 @@ static int do_main(int argc, char* argv[])
return XRE_main(argc, argv, &sAppData, 0);
}
int main(int argc, char* argv[])
#ifdef MOZ_B2G_LOADER
/*
* The main() in B2GLoader.cpp is the new main function instead of the
* main() here if it is enabled. So, rename it to b2g_man().
*/
#define main b2g_main
#define _CONST const
#else
#define _CONST
#endif
int main(int argc, _CONST char* argv[])
{
#ifndef MOZ_B2G_LOADER
char exePath[MAXPATHLEN];
#endif
#ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
@ -175,7 +189,9 @@ int main(int argc, char* argv[])
android::ProcessState::self()->startThreadPool();
#endif
nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
nsresult rv;
#ifndef MOZ_B2G_LOADER
rv = mozilla::BinaryPath::Get(argv[0], exePath);
if (NS_FAILED(rv)) {
Output("Couldn't calculate the application directory.\n");
return 255;
@ -186,6 +202,7 @@ int main(int argc, char* argv[])
return 255;
strcpy(++lastSlash, XPCOM_DLL);
#endif // MOZ_B2G_LOADER
#if defined(XP_UNIX)
// If the b2g app is launched from adb shell, then the shell will wind
@ -209,6 +226,9 @@ int main(int argc, char* argv[])
DllBlocklist_Initialize();
#endif
// B2G loader has already initialized Gecko so we can't initialize
// it again here.
#ifndef MOZ_B2G_LOADER
// We do this because of data in bug 771745
XPCOMGlueEnablePreload();
@ -219,6 +239,7 @@ int main(int argc, char* argv[])
}
// Reset exePath so that it is the directory name and not the xpcom dll name
*lastSlash = 0;
#endif // MOZ_B2G_LOADER
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
if (NS_FAILED(rv)) {
@ -253,7 +274,25 @@ int main(int argc, char* argv[])
int result;
{
ScopedLogging log;
result = do_main(argc, argv);
char **_argv;
/*
* Duplicate argument vector to conform non-const argv of
* do_main() since XRE_main() is very stupid with non-const argv.
*/
_argv = new char *[argc + 1];
for (int i = 0; i < argc; i++) {
_argv[i] = strdup(argv[i]);
MOZ_ASSERT(_argv[i] != nullptr);
}
_argv[argc] = nullptr;
result = do_main(argc, _argv);
for (int i = 0; i < argc; i++) {
free(_argv[i]);
}
delete[] _argv;
}
return result;

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="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="999e945b85c578c503ad445c2285940f16aacdae">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3842156466e71f41748f86777a1b8fbd379441c0",
"revision": "92b742f333b1f695de3de7c10316bc5ee652d084",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,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="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,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="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

View File

@ -17,7 +17,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="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -59,6 +59,7 @@ MOZ_B2G=1
if test "$OS_TARGET" = "Android"; then
MOZ_NUWA_PROCESS=1
MOZ_B2G_LOADER=1
fi
MOZ_FOLD_LIBS=1

View File

@ -8614,6 +8614,14 @@ if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
AC_DEFINE(MOZ_NUWA_PROCESS)
fi
AC_SUBST(MOZ_NUWA_PROCESS)
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_B2G_LOADER"; then
if test -z "$MOZ_NUWA_PROCESS"; then
AC_MSG_ERROR([B2G loader works with Nuwa]);
fi
export MOZ_B2G_LOADER
AC_DEFINE(MOZ_B2G_LOADER)
fi
AC_SUBST(MOZ_B2G_LOADER)
AC_SUBST(NSPR_CFLAGS)
AC_SUBST(NSPR_LIBS)

View File

@ -588,11 +588,6 @@ void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive)
if (cubeb_stream_set_panning(mCubebStream, 0.0) != CUBEB_OK) {
NS_WARNING("Could not pan audio output to the center.");
}
// This a microphone that goes through the headphone plug, reset the
// output to prevent echo building up.
if (strcmp(device->input_name, "emic") == 0) {
Reset();
}
}
cubeb_stream_device_destroy(mCubebStream, device);
}
@ -600,10 +595,30 @@ void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive)
#endif
}
void AudioStream::DeviceChangedCallback() {
void AudioStream::ResetStreamIfNeeded()
{
cubeb_device * device;
// Only reset a device if a mic is active, and this is a low latency stream.
if (!mMicrophoneActive || mLatencyRequest != LowLatency) {
return;
}
if (cubeb_stream_get_current_device(mCubebStream, &device) == CUBEB_OK) {
// This a microphone that goes through the headphone plug, reset the
// output to prevent echo building up.
if (strcmp(device->input_name, "emic") == 0) {
LOG(("Resetting audio output"));
Reset();
}
cubeb_stream_device_destroy(mCubebStream, device);
}
}
void AudioStream::DeviceChangedCallback()
{
MonitorAutoLock mon(mMonitor);
PanOutputIfNeeded(mMicrophoneActive);
mShouldDropFrames = true;
ResetStreamIfNeeded();
}
// This code used to live inside AudioStream::Init(), but on Mac (others?)
@ -1127,6 +1142,9 @@ AudioStream::GetTimeStretched(void* aBuffer, long aFrames, int64_t &aTimeMs)
void
AudioStream::Reset()
{
MOZ_ASSERT(mLatencyRequest == LowLatency, "We should only be reseting low latency streams");
mShouldDropFrames = true;
mNeedsStart = true;
@ -1160,21 +1178,13 @@ AudioStream::Reset()
mBuffer.Reset();
mBuffer.SetCapacity(bufferLimit);
if (mLatencyRequest == LowLatency) {
// Don't block this thread to initialize a cubeb stream.
// When this is done, it will start callbacks from Cubeb. Those will
// cause us to move from INITIALIZED to RUNNING. Until then, we
// can't access any cubeb functions.
// Use a RefPtr to avoid leaks if Dispatch fails
RefPtr<AudioInitTask> init = new AudioInitTask(this, mLatencyRequest, params);
init->Dispatch();
return;
}
// High latency - open synchronously
OpenCubeb(params, mLatencyRequest);
CheckForStart();
// Don't block this thread to initialize a cubeb stream.
// When this is done, it will start callbacks from Cubeb. Those will
// cause us to move from INITIALIZED to RUNNING. Until then, we
// can't access any cubeb functions.
// Use a RefPtr to avoid leaks if Dispatch fails
RefPtr<AudioInitTask> init = new AudioInitTask(this, mLatencyRequest, params);
init->Dispatch();
}
long

View File

@ -240,6 +240,7 @@ public:
// application.
void SetMicrophoneActive(bool aActive);
void PanOutputIfNeeded(bool aMicrophoneActive);
void ResetStreamIfNeeded();
// Block until buffered audio data has been consumed.
void Drain();

View File

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
ifeq ($(OS_ARCH),WINNT)
OS_CXXFLAGS += -DNOMINMAX
endif

View File

@ -42,3 +42,5 @@ LOCAL_INCLUDES += [
'/media/webrtc/trunk/webrtc/modules/video_capture/windows',
]
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['NOMINMAX'] = True

View File

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
ifeq ($(OS_ARCH),WINNT)
OS_CXXFLAGS += -DNOMINMAX
endif

View File

@ -131,6 +131,7 @@ AppleATDecoder::Drain()
{
LOG("Draining AudioToolbox AAC decoder");
mTaskQueue->AwaitIdle();
mCallback->DrainComplete();
return Flush();
}

View File

@ -111,19 +111,26 @@ AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample)
nsresult
AppleVTDecoder::Flush()
{
nsresult rv = WaitForAsynchronousFrames();
if (NS_FAILED(rv)) {
LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
}
mReorderQueue.Clear();
return Drain();
return rv;
}
nsresult
AppleVTDecoder::Drain()
{
OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession);
if (rv != noErr) {
LOG("Error %d draining frames", rv);
return NS_ERROR_FAILURE;
mTaskQueue->AwaitIdle();
nsresult rv = WaitForAsynchronousFrames();
if (NS_FAILED(rv)) {
LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
return rv;
}
return DrainReorderedFrames();
DrainReorderedFrames();
mCallback->DrainComplete();
return NS_OK;
}
//
@ -192,12 +199,22 @@ PlatformCallback(void* decompressionOutputRefCon,
}
nsresult
AppleVTDecoder::WaitForAsynchronousFrames()
{
OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession);
if (rv != noErr) {
LOG("AppleVTDecoder: Error %d waiting for asynchronous frames", rv);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void
AppleVTDecoder::DrainReorderedFrames()
{
while (!mReorderQueue.IsEmpty()) {
mCallback->Output(mReorderQueue.Pop());
}
return NS_OK;
}
// Copy and return a decoded frame.

View File

@ -52,7 +52,8 @@ private:
nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample);
// Method to set up the decompression session.
nsresult InitializeSession();
nsresult DrainReorderedFrames();
nsresult WaitForAsynchronousFrames();
void DrainReorderedFrames();
};
} // namespace mozilla

View File

@ -61,3 +61,6 @@ if CONFIG['MOZ_APPLEMEDIA']:
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['NOMINMAX'] = True

View File

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
ifeq ($(OS_ARCH),WINNT)
OS_CXXFLAGS += -DNOMINMAX
endif

View File

@ -27,3 +27,6 @@ SOURCES += [
FAIL_ON_WARNINGS = True
FINAL_LIBRARY = 'xul'
if CONFIG['OS_ARCH'] == 'WINNT':
DEFINES['NOMINMAX'] = True

View File

@ -44,6 +44,7 @@
#include "nsRect.h"
#include "prenv.h"
#include "nsIDOMWindow.h"
#include "nsIGlobalObject.h"
#include "nsIWebBrowserChrome.h"
#include "nsPoint.h"
#include "nsIObserverService.h"
@ -1008,6 +1009,7 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink)
*aSink = mContentListener;
}
else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) ||
aIID.Equals(NS_GET_IID(nsIGlobalObject)) ||
aIID.Equals(NS_GET_IID(nsPIDOMWindow)) ||
aIID.Equals(NS_GET_IID(nsIDOMWindow)) ||
aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) &&

View File

@ -23,7 +23,9 @@ let makeFile = CC('@mozilla.org/file/local;1',
'initWithPath');
let MutableArray = CC('@mozilla.org/array;1', 'nsIMutableArray');
const nsICache = Ci.nsICache;
let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
const nsICacheStorage = Ci.nsICacheStorage;
const nsIApplicationCache = Ci.nsIApplicationCache;
const applicationCacheService =
Cc['@mozilla.org/network/application-cache-service;1']
@ -47,32 +49,34 @@ function enableOfflineCacheForApp(origin, appId) {
function storeCache(applicationCache, url, file, itemType) {
let session = Services.cache.createSession(applicationCache.clientID,
nsICache.STORE_OFFLINE, true);
session.asyncOpenCacheEntry(url, nsICache.ACCESS_WRITE, {
onCacheEntryAvailable: function (cacheEntry, accessGranted, status) {
cacheEntry.setMetaDataElement('request-method', 'GET');
cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n');
let storage =
Services.cache2.appCacheStorage(LoadContextInfo.default, applicationCache);
let uri = Services.io.newURI(url, null, null);
storage.asyncOpenURI(uri, "", nsICacheStorage.OPEN_TRUNCATE, {
onCacheEntryAvailable:
function (cacheEntry, isNew, appCache, result) {
cacheEntry.setMetaDataElement('request-method', 'GET');
cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n');
let outputStream = cacheEntry.openOutputStream(0);
let outputStream = cacheEntry.openOutputStream(0);
// Input-Output stream machinery in order to push nsIFile content into cache
let inputStream = Cc['@mozilla.org/network/file-input-stream;1']
.createInstance(Ci.nsIFileInputStream);
inputStream.init(file, 1, -1, null);
let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1']
.createInstance(Ci.nsIBufferedOutputStream);
bufferedOutputStream.init(outputStream, 1024);
bufferedOutputStream.writeFrom(inputStream, inputStream.available());
bufferedOutputStream.flush();
bufferedOutputStream.close();
inputStream.close();
// Input-Output stream machinery in order to push nsIFile content into cache
let inputStream = Cc['@mozilla.org/network/file-input-stream;1']
.createInstance(Ci.nsIFileInputStream);
inputStream.init(file, 1, -1, null);
let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1']
.createInstance(Ci.nsIBufferedOutputStream);
bufferedOutputStream.init(outputStream, 1024);
bufferedOutputStream.writeFrom(inputStream, inputStream.available());
bufferedOutputStream.flush();
bufferedOutputStream.close();
inputStream.close();
cacheEntry.markValid();
debug (file.path + ' -> ' + url + ' (' + itemType + ')');
applicationCache.markEntry(url, itemType);
cacheEntry.close();
}
cacheEntry.markValid();
debug (file.path + ' -> ' + url + ' (' + itemType + ')');
applicationCache.markEntry(url, itemType);
cacheEntry.close();
}
});
}

View File

@ -3672,9 +3672,9 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
MaybeTransform transform;
forwarder->GetShadowManager()->SendGetAnimationTransform(
layer->AsShadowableLayer()->GetShadow(), &transform);
if (transform.type() == MaybeTransform::Tgfx3DMatrix) {
cssValue =
nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix());
if (transform.type() == MaybeTransform::TMatrix4x4) {
gfx3DMatrix matrix = To3DMatrix(transform.get_Matrix4x4());
cssValue = nsComputedDOMStyle::MatrixToCSSValue(matrix);
}
}
}

View File

@ -52,6 +52,32 @@ def isTypeCopyConstructible(type):
(type.isInterface() and type.isGeckoInterface()))
def idlTypeNeedsCycleCollection(type):
type = type.unroll() # Takes care of sequences and nullables
if ((type.isPrimitive() and type.tag() in builtinNames) or
type.isEnum() or
type.isDOMString() or
type.isByteString() or
type.isAny() or
type.isObject() or
type.isSpiderMonkeyInterface()):
return False
elif type.isCallback() or type.isGeckoInterface():
return True
elif type.isUnion():
return any(idlTypeNeedsCycleCollection(t) for t in type.flatMemberTypes)
elif type.isMozMap():
if idlTypeNeedsCycleCollection(type.inner):
raise TypeError("Cycle collection for type %s is not supported" % type)
return False
elif type.isDictionary():
if any(idlTypeNeedsCycleCollection(m.type) for m in type.inner.members):
raise TypeError("Cycle collection for type %s is not supported" % type)
return False
else:
raise TypeError("Don't know whether to cycle-collect type %s" % type)
def wantsAddProperty(desc):
return (desc.concrete and
desc.wrapperCache and
@ -1160,6 +1186,8 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
declarations = set()
unionStructs = dict()
owningUnionStructs = dict()
traverseMethods = dict()
unlinkMethods = dict()
for t, descriptor, dictionary in getAllTypes(descriptors, dictionaries, callbacks):
# Add info for the given type. descriptor and dictionary, if present, are
@ -1227,8 +1255,20 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
assert not f.nullable()
addHeadersForType(f)
if idlTypeNeedsCycleCollection(t):
declarations.add(("mozilla::dom::%s" % CGUnionStruct.unionTypeName(t, True), False))
traverseMethods[name] = CGCycleCollectionTraverseForOwningUnionMethod(t)
unlinkMethods[name] = CGCycleCollectionUnlinkForOwningUnionMethod(t)
# The order of items in CGList is important.
# Since the union structs friend the unlinkMethods, the forward-declaration
# for these methods should come before the class declaration. Otherwise
# some compilers treat the friend declaration as a forward-declaration in
# the class scope.
return (headers, implheaders, declarations,
CGList(SortedDictValues(unionStructs) +
CGList(SortedDictValues(traverseMethods) +
SortedDictValues(unlinkMethods) +
SortedDictValues(unionStructs) +
SortedDictValues(owningUnionStructs),
"\n"))
@ -3263,6 +3303,47 @@ class CGIsPermittedMethod(CGAbstractMethod):
switch = CGSwitch("propFirstChar", caseList)
return switch.define() + "\nreturn false;\n"
class CGCycleCollectionTraverseForOwningUnionMethod(CGAbstractMethod):
"""
ImplCycleCollectionUnlink for owning union type.
"""
def __init__(self, type):
self.type = type
args = [Argument("nsCycleCollectionTraversalCallback&", "aCallback"),
Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion"),
Argument("const char*", "aName"),
Argument("uint32_t", "aFlags", "0")]
CGAbstractMethod.__init__(self, None, "ImplCycleCollectionTraverse", "void", args)
def definition_body(self):
memberNames = [getUnionMemberName(t)
for t in self.type.flatMemberTypes
if idlTypeNeedsCycleCollection(t)]
assert memberNames
conditionTemplate = 'aUnion.Is%s()'
functionCallTemplate = 'ImplCycleCollectionTraverse(aCallback, aUnion.GetAs%s(), "m%s", aFlags);\n'
ifStaments = (CGIfWrapper(CGGeneric(functionCallTemplate % (m, m)),
conditionTemplate % m)
for m in memberNames)
return CGElseChain(ifStaments).define()
class CGCycleCollectionUnlinkForOwningUnionMethod(CGAbstractMethod):
"""
ImplCycleCollectionUnlink for owning union type.
"""
def __init__(self, type):
args = [Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion")]
CGAbstractMethod.__init__(self, None, "ImplCycleCollectionUnlink", "void", args)
def definition_body(self):
return "aUnion.Uninit();\n"
builtinNames = {
IDLType.Tags.bool: 'bool',
IDLType.Tags.int8: 'int8_t',
@ -8464,7 +8545,11 @@ class CGUnionStruct(CGThing):
else:
disallowCopyConstruction = True
friend = " friend class %sArgument;\n" % str(self.type) if not self.ownsMembers else ""
if self.ownsMembers:
friend = " friend void ImplCycleCollectionUnlink(%s& aUnion);\n" % CGUnionStruct.unionTypeName(self.type, True)
else:
friend = " friend class %sArgument;\n" % str(self.type)
bases = [ClassBase("AllOwningUnionBase")] if self.ownsMembers else []
return CGClass(selfName,
bases=bases,
@ -10695,7 +10780,7 @@ def initIdsClassMethod(identifiers, atomCacheName):
Argument("JSContext*", "cx"),
Argument("%s*" % atomCacheName, "atomsCache")
], static=True, body=body, visibility="private")
class CGDictionary(CGThing):
def __init__(self, dictionary, descriptorProvider):
self.dictionary = dictionary
@ -10884,7 +10969,7 @@ class CGDictionary(CGThing):
def initIdsMethod(self):
assert self.needToInitIds
return initIdsClassMethod([m.identifier.name for m in self.dictionary.members],
"%sAtoms" % self.makeClassName(self.dictionary))
"%sAtoms" % self.makeClassName(self.dictionary))
def traceDictionaryMethod(self):
body = ""
@ -14033,7 +14118,7 @@ class CGEventClass(CGBindingImplClass):
retVal = ""
for m in self.descriptor.interface.members:
# Unroll the type so we pick up sequences of interfaces too.
if m.isAttr() and m.type.unroll().isGeckoInterface():
if m.isAttr() and idlTypeNeedsCycleCollection(m.type):
retVal += (" NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" +
CGDictionary.makeMemberName(m.identifier.name) +
")\n")
@ -14045,7 +14130,7 @@ class CGEventClass(CGBindingImplClass):
if m.isAttr():
name = CGDictionary.makeMemberName(m.identifier.name)
# Unroll the type so we pick up sequences of interfaces too.
if m.type.unroll().isGeckoInterface():
if idlTypeNeedsCycleCollection(m.type):
retVal += " NS_IMPL_CYCLE_COLLECTION_UNLINK(" + name + ")\n"
elif m.type.isAny():
retVal += " tmp->" + name + ".setUndefined();\n"

View File

@ -10,6 +10,7 @@
#define mozilla_dom_OwningNonNull_h
#include "nsAutoPtr.h"
#include "nsCycleCollectionNoteChild.h"
namespace mozilla {
namespace dom {
@ -87,6 +88,16 @@ protected:
#endif
};
template <typename T>
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
OwningNonNull<T>& aField,
const char* aName,
uint32_t aFlags = 0)
{
CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
}
} // namespace dom
} // namespace mozilla

View File

@ -43,8 +43,8 @@ function runTest() {
}
addEventListener('testready', function() {
// Cause the grace period of priority privilege for this new process to time
// out after 1s.
// Cause the CPU wake lock taken on behalf of this new process to time out
// after 1s.
SpecialPowers.pushPrefEnv(
{set: [["dom.ipc.systemMessageCPULockTimeoutSec", 1]]},
runTest);

View File

@ -57,9 +57,9 @@ function runTest() {
}
addEventListener('testready', function() {
// We don't want the grace period of priority privilege to time out during the
// test; should it really happen, we would see BACKGROUND priority instead of
// BACKGROUND_PERCEIVABLE. So set the timeout to a large value.
// We don't want this wake lock to time out during the test; if it did, then
// we might see BACKGROUND priority instead of BACKGROUND_PERCEIVABLE. So
// set the timeout to a large value.
SpecialPowers.pushPrefEnv(
{set: [["dom.ipc.systemMessageCPULockTimeoutSec", 99999]]},
runTest);

View File

@ -69,8 +69,8 @@ function runTest() {
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv(
{set: [
/* Cause the grace period of priority privilege for the high-priority
* process to time out after 1s. */
/* Cause the CPU wake lock taken on behalf of the high-priority process
* to time out after 1s. */
["dom.ipc.systemMessageCPULockTimeoutSec", 1],
["dom.wakelock.enabled", true]
]},

View File

@ -65,8 +65,8 @@ function runTest() {
}
addEventListener('testready', function() {
// Cause the grace period of priority privilege for the high-priority process
// never to time out during this test.
// Cause the CPU wake lock taken on behalf of the high-priority process never
// to time out during this test.
SpecialPowers.pushPrefEnv(
{set: [["dom.ipc.systemMessageCPULockTimeoutSec", 1000]]},
runTest);

View File

@ -234,6 +234,7 @@ GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCam
nsresult rv = cameraHardware->Init();
if (NS_FAILED(rv)) {
DOM_CAMERA_LOGE("Failed to initialize camera hardware (0x%X)\n", rv);
cameraHardware->Close();
return nullptr;
}

View File

@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=940424
<script class="testbody" type="text/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
@ -27,24 +29,65 @@ var initialConfig = {
}
};
function end() {
CameraTest.end();
}
var tests = [
{
name: "init-failure",
key: "init-failure",
func: function testInitFailure(test) {
function onSuccess(camera, config) {
ok(false, "onSuccess called incorrectly");
camera.release();
test.next();
}
function onError(error) {
ok(true, "onError called correctly on init failure");
test.next();
}
info("Running test: init-failure");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
}
},
/* This test case (init-success) *must* follow the preceeding test case
(init-failure) in order for the desired condition to be verified */
{
name: "init-success",
key: "",
func: function(test) {
function onSuccess(camera, config) {
ok(true, "onSuccess called correctly");
camera.release();
test.next();
}
function onError(error) {
ok(false, "onError called incorrectly: " + error);
test.next();
}
info("Running test: init-success");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError)
}
}
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
CameraTest.begin("hardware", function(test) {
test.set("init-failure", function(type) {
function onSuccess(camera, config) {
ok(false, "onSuccess called incorrectly");
camera.release();
test.done(end);
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, CameraTest));
} catch(e) {
if (e instanceof StopIteration) {
CameraTest.end();
} else {
throw e;
}
}
function onError(error) {
ok(true, "onError called correctly on init failure");
test.done(end);
}
info("Running test: " + type);
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
});
};
CameraTest.next();
});
</script>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var video = document.createElement('video');
var track = video.addTextTrack('chapters');
window.meep = new TrackEvent("t", { "track": track });
document.documentElement.style.expando = null;
}
</script>
</head>
<body onload="boom();">
</body>
</html>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var video = document.createElement('video');
var track = video.addTextTrack('chapters');
track.expando = new TrackEvent("t", { "track": track })
}
</script>
</head>
<body onload="boom();">
</body>
</html>

View File

@ -6,6 +6,8 @@ load 457776-1.html
load 496308-1.html
load 682637-1.html
load 1033343.html
load 1035654-1.html
load 1035654-2.html
load eventctor-nulldictionary.html
load eventctor-nullstorage.html
load recursive-onload.html

View File

@ -41,6 +41,7 @@
#include "mozilla/dom/PFileDescriptorSetParent.h"
#include "mozilla/dom/PCycleCollectWithLogsParent.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/bluetooth/PBluetoothParent.h"
#include "mozilla/dom/PFMRadioParent.h"
@ -83,6 +84,7 @@
#include "nsIClipboard.h"
#include "nsICycleCollectorListener.h"
#include "nsIDOMGeoGeolocation.h"
#include "mozilla/dom/WakeLock.h"
#include "nsIDOMWindow.h"
#include "nsIExternalProtocolService.h"
#include "nsIGfxInfo.h"
@ -183,6 +185,7 @@ using base::KillProcess;
using namespace mozilla::dom::bluetooth;
using namespace mozilla::dom::devicestorage;
using namespace mozilla::dom::indexedDB;
using namespace mozilla::dom::power;
using namespace mozilla::dom::mobilemessage;
using namespace mozilla::dom::telephony;
using namespace mozilla::hal;
@ -836,95 +839,6 @@ ContentParent::AnswerBridgeToChildProcess(const uint64_t& id)
}
}
namespace {
class SystemMessageHandledListener MOZ_FINAL
: public nsITimerCallback
, public LinkedListElement<SystemMessageHandledListener>
{
public:
NS_DECL_ISUPPORTS
SystemMessageHandledListener() {}
static void OnSystemMessageHandled()
{
if (!sListeners) {
return;
}
SystemMessageHandledListener* listener = sListeners->popFirst();
if (!listener) {
return;
}
// Careful: ShutDown() may delete |this|.
listener->ShutDown();
}
void Init(ContentParent* aContentParent)
{
MOZ_ASSERT(!mContentParent);
MOZ_ASSERT(!mTimer);
// mTimer keeps a strong reference to |this|. When this object's
// destructor runs, it will remove itself from the LinkedList.
if (!sListeners) {
sListeners = new LinkedList<SystemMessageHandledListener>();
ClearOnShutdown(&sListeners);
}
sListeners->insertBack(this);
mContentParent = aContentParent;
mTimer = do_CreateInstance("@mozilla.org/timer;1");
uint32_t timeoutSec =
Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30);
mTimer->InitWithCallback(this, timeoutSec * 1000,
nsITimer::TYPE_ONE_SHOT);
}
NS_IMETHOD Notify(nsITimer* aTimer)
{
// Careful: ShutDown() may delete |this|.
ShutDown();
return NS_OK;
}
private:
~SystemMessageHandledListener() {}
static StaticAutoPtr<LinkedList<SystemMessageHandledListener> > sListeners;
void ShutDown()
{
ProcessPriorityManager::ResetProcessPriority(mContentParent, false);
nsRefPtr<SystemMessageHandledListener> kungFuDeathGrip = this;
if (mContentParent) {
mContentParent = nullptr;
}
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
}
nsRefPtr<ContentParent> mContentParent;
nsCOMPtr<nsITimer> mTimer;
};
StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
SystemMessageHandledListener::sListeners;
NS_IMPL_ISUPPORTS(SystemMessageHandledListener,
nsITimerCallback)
} // anonymous namespace
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
Element* aFrameElement,
@ -1129,20 +1043,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
return nullptr;
}
// Request a higher priority above BACKGROUND if the child process is
// "critical" and probably has system messages coming soon. (A CPU wake lock
// may already be controlled by the B2G process in SystemMessageInternal.js
// for message handling.) This privilege is revoked once the message is
// delivered, or the grace period is up, whichever comes first.
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aFrameElement);
if (browserFrame && browserFrame->GetIsExpectingSystemMessage()) {
ProcessPriorityManager::ResetProcessPriority(p, true);
// This object's Init() function keeps it alive.
nsRefPtr<SystemMessageHandledListener> listener =
new SystemMessageHandledListener();
listener->Init(p);
}
p->MaybeTakeCPUWakeLock(aFrameElement);
return static_cast<TabParent*>(browser);
}
@ -1206,6 +1107,117 @@ ContentParent::Init()
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
}
namespace {
class SystemMessageHandledListener MOZ_FINAL
: public nsITimerCallback
, public LinkedListElement<SystemMessageHandledListener>
{
public:
NS_DECL_ISUPPORTS
SystemMessageHandledListener() {}
static void OnSystemMessageHandled()
{
if (!sListeners) {
return;
}
SystemMessageHandledListener* listener = sListeners->popFirst();
if (!listener) {
return;
}
// Careful: ShutDown() may delete |this|.
listener->ShutDown();
}
void Init(WakeLock* aWakeLock)
{
MOZ_ASSERT(!mWakeLock);
MOZ_ASSERT(!mTimer);
// mTimer keeps a strong reference to |this|. When this object's
// destructor runs, it will remove itself from the LinkedList.
if (!sListeners) {
sListeners = new LinkedList<SystemMessageHandledListener>();
ClearOnShutdown(&sListeners);
}
sListeners->insertBack(this);
mWakeLock = aWakeLock;
mTimer = do_CreateInstance("@mozilla.org/timer;1");
uint32_t timeoutSec =
Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30);
mTimer->InitWithCallback(this, timeoutSec * 1000,
nsITimer::TYPE_ONE_SHOT);
}
NS_IMETHOD Notify(nsITimer* aTimer)
{
// Careful: ShutDown() may delete |this|.
ShutDown();
return NS_OK;
}
private:
~SystemMessageHandledListener() {}
static StaticAutoPtr<LinkedList<SystemMessageHandledListener> > sListeners;
void ShutDown()
{
nsRefPtr<SystemMessageHandledListener> kungFuDeathGrip = this;
ErrorResult rv;
mWakeLock->Unlock(rv);
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
}
nsRefPtr<WakeLock> mWakeLock;
nsCOMPtr<nsITimer> mTimer;
};
StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
SystemMessageHandledListener::sListeners;
NS_IMPL_ISUPPORTS(SystemMessageHandledListener,
nsITimerCallback)
} // anonymous namespace
void
ContentParent::MaybeTakeCPUWakeLock(Element* aFrameElement)
{
// Take the CPU wake lock on behalf of this processs if it's expecting a
// system message. We'll release the CPU lock once the message is
// delivered, or after some period of time, which ever comes first.
nsCOMPtr<nsIMozBrowserFrame> browserFrame =
do_QueryInterface(aFrameElement);
if (!browserFrame ||
!browserFrame->GetIsExpectingSystemMessage()) {
return;
}
nsRefPtr<PowerManagerService> pms = PowerManagerService::GetInstance();
nsRefPtr<WakeLock> lock =
pms->NewWakeLockOnBehalfOfProcess(NS_LITERAL_STRING("cpu"), this);
// This object's Init() function keeps it alive.
nsRefPtr<SystemMessageHandledListener> listener =
new SystemMessageHandledListener();
listener->Init(lock);
}
bool
ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
{

View File

@ -332,6 +332,12 @@ private:
void Init();
// If the frame element indicates that the child process is "critical" and
// has a pending system message, this function acquires the CPU wake lock on
// behalf of the child. We'll release the lock when the system message is
// handled or after a timeout, whichever comes first.
void MaybeTakeCPUWakeLock(Element* aFrameElement);
// Set the child process's priority and then check whether the child is
// still alive. Returns true if the process is still alive, and false
// otherwise. If you pass a FOREGROUND* priority here, it's (hopefully)

View File

@ -131,12 +131,6 @@ public:
ProcessPriority aPriority,
uint32_t aBackgroundLRU = 0);
/**
* This function implements ProcessPriorityManager::ResetProcessPriority.
*/
void ResetProcessPriority(ContentParent* aContentParent,
bool aHandleSystemMessage);
/**
* If a magic testing-only pref is set, notify the observer service on the
* given topic with the given data. This is used for testing
@ -293,8 +287,6 @@ public:
void ShutDown();
void SetHandlesSystemMessage(bool aHandlesSystemMessage);
private:
void FireTestOnlyObserverNotification(
const char* aTopic,
@ -310,7 +302,6 @@ private:
ProcessCPUPriority mCPUPriority;
bool mHoldsCPUWakeLock;
bool mHoldsHighPriorityWakeLock;
bool mHandlesSystemMessage;
/**
* Used to implement NameWithComma().
@ -505,17 +496,6 @@ ProcessPriorityManagerImpl::SetProcessPriority(ContentParent* aContentParent,
pppm->SetPriorityNow(aPriority, aBackgroundLRU);
}
void
ProcessPriorityManagerImpl::ResetProcessPriority(ContentParent* aContentParent,
bool aHandleSystemMessage)
{
MOZ_ASSERT(aContentParent);
nsRefPtr<ParticularProcessPriorityManager> pppm =
GetParticularProcessPriorityManager(aContentParent);
pppm->SetHandlesSystemMessage(aHandleSystemMessage);
pppm->ResetPriorityNow();
}
void
ProcessPriorityManagerImpl::ObserveContentParentCreated(
nsISupports* aContentParent)
@ -667,7 +647,6 @@ ParticularProcessPriorityManager::ParticularProcessPriorityManager(
, mCPUPriority(PROCESS_CPU_PRIORITY_NORMAL)
, mHoldsCPUWakeLock(false)
, mHoldsHighPriorityWakeLock(false)
, mHandlesSystemMessage(false)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
LOGP("Creating ParticularProcessPriorityManager.");
@ -990,7 +969,7 @@ ParticularProcessPriorityManager::CurrentPriority()
ProcessPriority
ParticularProcessPriorityManager::ComputePriority()
{
if ((mHandlesSystemMessage || mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) &&
if ((mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) &&
HasAppType("critical")) {
return PROCESS_PRIORITY_FOREGROUND_HIGH;
}
@ -1011,7 +990,7 @@ ParticularProcessPriorityManager::ComputePriority()
PROCESS_PRIORITY_FOREGROUND;
}
if ((mHandlesSystemMessage || mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) &&
if ((mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) &&
IsExpectingSystemMessage()) {
return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE;
}
@ -1158,12 +1137,6 @@ ParticularProcessPriorityManager::ShutDown()
mContentParent = nullptr;
}
void
ParticularProcessPriorityManager::SetHandlesSystemMessage(bool aHandlesSystemMessage)
{
mHandlesSystemMessage = aHandlesSystemMessage;
}
void
ProcessPriorityManagerImpl::FireTestOnlyObserverNotification(
const char* aTopic,
@ -1500,19 +1473,6 @@ ProcessPriorityManager::SetProcessPriority(ContentParent* aContentParent,
}
}
/* static */ void
ProcessPriorityManager::ResetProcessPriority(ContentParent* aContentParent,
bool aHandleSystemMessage)
{
MOZ_ASSERT(aContentParent);
ProcessPriorityManagerImpl* singleton =
ProcessPriorityManagerImpl::GetSingleton();
if (singleton) {
singleton->ResetProcessPriority(aContentParent, aHandleSystemMessage);
}
}
/* static */ void
ProcessPriorityManager::RemoveFromBackgroundLRUPool(
ContentParent* aContentParent)

View File

@ -59,20 +59,6 @@ public:
static void SetProcessPriority(dom::ContentParent* aContentParent,
hal::ProcessPriority aPriority);
/**
* Reset the process priority of a given ContentParent's process in
* consideration of system message handling.
*
* Note that because this method takes a ContentParent*, you can only set the
* priority of your subprocesses. In fact, because we don't support nested
* content processes (bug 761935), you can only call this method from the
* main process.
*
* The process priority manager will determine a new appropriate priority.
*/
static void ResetProcessPriority(dom::ContentParent* aContentParent,
bool aHandleSystemMessage);
/**
* Returns true iff this process's priority is FOREGROUND*.
*

View File

@ -39,16 +39,6 @@ try {
kMaxPendingMessages = 5;
}
//Limit the duration to hold the CPU wake lock.
let kCpuWakeLockTimeoutSec;
try {
kCpuWakeLockTimeoutSec =
Services.prefs.getIntPref("dom.ipc.systemMessageCPULockTimeoutSec");
} catch (e) {
// getIntPref throws when the pref is not set.
kCpuWakeLockTimeoutSec = 30;
}
const kMessages =["SystemMessageManager:GetPendingMessages",
"SystemMessageManager:HasPendingMessages",
"SystemMessageManager:Register",
@ -159,7 +149,7 @@ SystemMessageInternal.prototype = {
debug("Releasing the CPU wake lock because the system messages " +
"were not handled by its registered page before time out.");
this._cancelCpuWakeLock(aPageKey);
}.bind(this), kCpuWakeLockTimeoutSec * 1000, Ci.nsITimer.TYPE_ONE_SHOT);
}.bind(this), 30000, Ci.nsITimer.TYPE_ONE_SHOT);
},
_releaseCpuWakeLock: function _releaseCpuWakeLock(aPageKey, aHandledCount) {

View File

@ -108,8 +108,10 @@ SystemMessageManager.prototype = {
this._dispatchMessage(aType, aDispatcher, aDispatcher.messages.shift());
} else {
// No more messages that need to be handled, we can notify the
// ContentChild to propogate the event, so that the ContentParent can
// reset the process's priority.
// ContentChild to release the CPU wake lock grabbed by the ContentParent
// (i.e. NewWakeLockOnBehalfOfProcess()) and reset the process's priority.
//
// TODO: Bug 874353 - Remove SystemMessageHandledListener in ContentParent
Services.obs.notifyObservers(/* aSubject */ null,
"handle-system-messages-done",
/* aData */ null);
@ -247,8 +249,11 @@ SystemMessageManager.prototype = {
pageURL: this._pageURL,
handledCount: messages.length });
// We also need to notify the ContentChild to propogate the event, so that
// the ContentParent can reset the process's priority.
// We also need to notify the ContentChild to release the CPU wake lock
// grabbed by the ContentParent (i.e. NewWakeLockOnBehalfOfProcess()) and
// reset the process's priority.
//
// TODO: Bug 874353 - Remove SystemMessageHandledListener in ContentParent
Services.obs.notifyObservers(/* aSubject */ null,
"handle-system-messages-done",
/* aData */ null);

View File

@ -14,6 +14,7 @@
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/WeakPtr.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
#include "js/TypeDecls.h"
@ -50,7 +51,8 @@ public:
};
class Promise MOZ_FINAL : public nsISupports,
public nsWrapperCache
public nsWrapperCache,
public SupportsWeakPtr<Promise>
{
friend class NativePromiseCallback;
friend class PromiseResolverMixin;
@ -71,6 +73,7 @@ class Promise MOZ_FINAL : public nsISupports,
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
MOZ_DECLARE_REFCOUNTED_TYPENAME(Promise)
// Promise creation tries to create a JS reflector for the Promise, so is
// fallible. Furthermore, we don't want to do JS-wrapping on a 0-refcount

View File

@ -66,10 +66,10 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin
RuntimeService* rs = RuntimeService::GetOrCreateService();
MOZ_ASSERT(rs);
nsTArray<nsTWeakRef<Promise>> array;
nsTArray<WeakPtr<Promise>> array;
array.SwapElements(mPromises);
for (uint32_t i = 0; i < array.Length(); ++i) {
nsTWeakRef<Promise>& pendingPromise = array.ElementAt(i);
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
if (pendingPromise) {
nsCOMPtr<nsIGlobalObject> go =
do_QueryInterface(pendingPromise->GetParentObject());
@ -103,10 +103,10 @@ UpdatePromise::RejectAllPromises(nsresult aRv)
MOZ_ASSERT(mState == Pending);
mState = Rejected;
nsTArray<nsTWeakRef<Promise>> array;
nsTArray<WeakPtr<Promise>> array;
array.SwapElements(mPromises);
for (uint32_t i = 0; i < array.Length(); ++i) {
nsTWeakRef<Promise>& pendingPromise = array.ElementAt(i);
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
if (pendingPromise) {
// Since ServiceWorkerContainer is only exposed to windows we can be
// certain about this cast.
@ -125,10 +125,10 @@ UpdatePromise::RejectAllPromises(const ErrorEventInit& aErrorDesc)
MOZ_ASSERT(mState == Pending);
mState = Rejected;
nsTArray<nsTWeakRef<Promise>> array;
nsTArray<WeakPtr<Promise>> array;
array.SwapElements(mPromises);
for (uint32_t i = 0; i < array.Length(); ++i) {
nsTWeakRef<Promise>& pendingPromise = array.ElementAt(i);
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
if (pendingPromise) {
// Since ServiceWorkerContainer is only exposed to windows we can be
// certain about this cast.

View File

@ -13,12 +13,12 @@
#include "mozilla/Preferences.h"
#include "mozilla/TypedEnum.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Promise.h"
#include "nsRefPtrHashtable.h"
#include "nsTArrayForwardDeclare.h"
#include "nsTObserverArray.h"
#include "nsTWeakRef.h"
class nsIScriptError;
@ -65,7 +65,7 @@ private:
// XXXnsm: Right now we don't need to support AddPromise() after
// already being resolved (i.e. true Promise-like behaviour).
nsTArray<nsTWeakRef<Promise>> mPromises;
nsTArray<WeakPtr<Promise>> mPromises;
};
/*

View File

@ -8,11 +8,10 @@
#include "jsapi.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
#include "nsIGlobalObject.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
#include "nsXBLProtoImplMethod.h"
#include "nsIScriptContext.h"
#include "nsJSUtils.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
@ -20,6 +19,7 @@
#include "nsIXPConnect.h"
#include "xpcpublic.h"
#include "nsXBLPrototypeBinding.h"
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla;
@ -278,20 +278,18 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
// nsXBLProtoImpl::InstallImplementation does.
nsIDocument* document = aBoundElement->OwnerDoc();
nsCOMPtr<nsIScriptGlobalObject> global =
do_QueryInterface(document->GetWindow());
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(document->GetInnerWindow());
if (!global) {
return NS_OK;
}
nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (!context) {
return NS_OK;
}
nsAutoMicroTask mt;
AutoPushJSContext cx(context->GetNativeContext());
// We are going to run script via JS::Call, so we need a script entry point,
// but as this is XBL related it does not appear in the HTML spec.
dom::AutoEntryScript aes(global);
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
@ -299,15 +297,6 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
nsresult rv = nsContentUtils::WrapNative(cx, aBoundElement, &v);
NS_ENSURE_SUCCESS(rv, rv);
// Use nsCxPusher to make sure we call ScriptEvaluated when we're done.
//
// Make sure to do this before entering the compartment, since pushing Push()
// may call JS_SaveFrameChain(), which puts us back in an unentered state.
nsCxPusher pusher;
if (!pusher.Push(aBoundElement))
return NS_ERROR_UNEXPECTED;
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
JS::Rooted<JSObject*> thisObject(cx, &v.toObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);

View File

@ -1,4 +1,4 @@
57222
57238
0/nm
0th/pt
1/n1
@ -16232,6 +16232,7 @@ Yolane/M
Yolanthe/M
Yong/M
Yonkers
Yooper/MS
Yorgo/MS
York/MR
Yorke/M
@ -24946,6 +24947,8 @@ crow/MDGS
crowbar/MS
crowd/SMDG
crowded/U
crowdfunded
crowdfunding
crowfeet
crowfoot/M
crown/SMDG
@ -30603,6 +30606,8 @@ foyer/SM
fps
fr
fracas/MS
frack/DRGS
fracker/S
fractal/SM
fraction/IASM
fractional/Y
@ -30672,6 +30677,7 @@ freeborn
freedman/M
freedmen
freedom/SM
freegan/S
freehand
freehold/ZMRS
freeholder/M
@ -31098,6 +31104,7 @@ gamester/MS
gamete/SM
gametic
gamey
gamify/NGDS
gamin/SM
gamine/SM
gaminess/M
@ -32721,6 +32728,7 @@ harvester/M
hash/AMDSG
hasheesh/M
hashish/M
hashtag/S
hasn't
hasp/MS
hassle/DSMG
@ -43221,6 +43229,7 @@ phlegmatically
phloem/M
phlogiston
phlox/M
pho
phobia/MS
phobic/MS
phoebe/MS
@ -44254,6 +44263,7 @@ pounding/SM
pour/GDSBJ
pout/ZGMDRS
pouter/M
poutine/S
poverty/M
pow
powder/GSMD
@ -48346,9 +48356,12 @@ selenium/M
selenographer/MS
selenography/M
selenology
self/M
self/MG
selfie/S
selfish/UYP
selfishness/UM
selfism
selfist/S
selfless/YP
selflessness/M
selfsame
@ -50850,6 +50863,7 @@ steamer/M
steamfitter/MS
steamfitting/M
steaminess/M
steampunk
steamroll/ZGDRS
steamroller/MDG
steamship/MS
@ -54250,6 +54264,7 @@ turbot/SM
turbulence/M
turbulent/Y
turd/MS
turducken
tureen/SM
turf/MDSG
turfy/RT
@ -54313,6 +54328,7 @@ tweed/SM
tweeds/M
tweedy/RT
tween
tweep/S
tweet/SMDRZG
tweeter/M
tweezers/M

View File

@ -288,6 +288,9 @@ public:
Matrix mMatrix; //!< Transforms the pattern into user space
};
class StoredPattern;
class DrawTargetCaptureImpl;
/**
* This is the base class for source surfaces. These objects are surfaces
* which may be used as a source in a SurfacePattern or a DrawSurface call.
@ -331,6 +334,15 @@ public:
}
protected:
friend class DrawTargetCaptureImpl;
friend class StoredPattern;
// This is for internal use, it ensures the SourceSurface's data remains
// valid during the lifetime of the SourceSurface.
// @todo XXX - We need something better here :(. But we may be able to get rid
// of CreateWrappingDataSourceSurface in the future.
virtual void GuaranteePersistance() {}
UserData mUserData;
};
@ -395,6 +407,7 @@ public:
*/
virtual TemporaryRef<DataSourceSurface> GetDataSurface();
protected:
bool mIsMapped;
};
@ -608,6 +621,8 @@ protected:
GlyphRenderingOptions() {}
};
class DrawTargetCapture;
/** This is the main class used for all the drawing. It is created through the
* factory and accepts drawing commands. The results of drawing to a target
* may be used either through a Snapshot or by flushing the target and directly
@ -646,6 +661,15 @@ public:
*/
virtual void Flush() = 0;
/**
* Realize a DrawTargetCapture onto the draw target.
*
* @param aSource Capture DrawTarget to draw
* @param aTransform Transform to apply when replaying commands
*/
virtual void DrawCapturedDT(DrawTargetCapture *aCaptureDT,
const Matrix& aTransform);
/**
* Draw a surface to the draw target. Possibly doing partial drawing or
* applying scaling. No sampling happens outside the source.
@ -881,6 +905,14 @@ public:
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
/**
* Create a DrawTarget that captures the drawing commands and can be replayed
* onto a compatible DrawTarget afterwards.
*
* @param aSize Size of the area this DT will capture.
*/
virtual TemporaryRef<DrawTargetCapture> CreateCaptureDT(const IntSize& aSize);
/**
* Create a draw target optimized for drawing a shadow.
*
@ -993,6 +1025,10 @@ protected:
SurfaceFormat mFormat;
};
class DrawTargetCapture : public DrawTarget
{
};
class DrawEventRecorder : public RefCounted<DrawEventRecorder>
{
public:

504
gfx/2d/DrawCommand.h Normal file
View File

@ -0,0 +1,504 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_DRAWCOMMAND_H_
#define MOZILLA_GFX_DRAWCOMMAND_H_
#include "2D.h"
#include "Filters.h"
#include <vector>
namespace mozilla {
namespace gfx {
MOZ_BEGIN_ENUM_CLASS(CommandType, int8_t)
DRAWSURFACE = 0,
DRAWFILTER,
DRAWSURFACEWITHSHADOW,
CLEARRECT,
COPYSURFACE,
COPYRECT,
FILLRECT,
STROKERECT,
STROKELINE,
STROKE,
FILL,
FILLGLYPHS,
MASK,
MASKSURFACE,
PUSHCLIP,
PUSHCLIPRECT,
POPCLIP,
SETTRANSFORM
MOZ_END_ENUM_CLASS(CommandType)
class DrawingCommand
{
public:
virtual ~DrawingCommand() {}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aTransform) = 0;
protected:
DrawingCommand(CommandType aType)
: mType(aType)
{
}
CommandType GetType() { return mType; }
private:
CommandType mType;
};
class StoredPattern
{
public:
StoredPattern(const Pattern& aPattern)
{
Assign(aPattern);
}
void Assign(const Pattern& aPattern)
{
switch (aPattern.GetType()) {
case PatternType::COLOR:
new (mColor)ColorPattern(*static_cast<const ColorPattern*>(&aPattern));
return;
case PatternType::SURFACE:
{
SurfacePattern* surfPat = new (mColor)SurfacePattern(*static_cast<const SurfacePattern*>(&aPattern));
surfPat->mSurface->GuaranteePersistance();
return;
}
case PatternType::LINEAR_GRADIENT:
new (mColor)LinearGradientPattern(*static_cast<const LinearGradientPattern*>(&aPattern));
return;
case PatternType::RADIAL_GRADIENT:
new (mColor)RadialGradientPattern(*static_cast<const RadialGradientPattern*>(&aPattern));
return;
}
}
~StoredPattern()
{
reinterpret_cast<Pattern*>(mColor)->~Pattern();
}
operator Pattern&()
{
return *reinterpret_cast<Pattern*>(mColor);
}
operator const Pattern&() const
{
return *reinterpret_cast<const Pattern*>(mColor);
}
StoredPattern(const StoredPattern& aPattern)
{
Assign(aPattern);
}
private:
StoredPattern operator=(const StoredPattern& aOther)
{
// Block this so that we notice if someone's doing excessive assigning.
return *this;
}
union {
char mColor[sizeof(ColorPattern)];
char mLinear[sizeof(LinearGradientPattern)];
char mRadial[sizeof(RadialGradientPattern)];
char mSurface[sizeof(SurfacePattern)];
};
};
class DrawSurfaceCommand : public DrawingCommand
{
public:
DrawSurfaceCommand(SourceSurface *aSurface, const Rect& aDest,
const Rect& aSource, const DrawSurfaceOptions& aSurfOptions,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::DRAWSURFACE)
, mSurface(aSurface), mDest(aDest)
, mSource(aSource), mSurfOptions(aSurfOptions)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions);
}
private:
RefPtr<SourceSurface> mSurface;
Rect mDest;
Rect mSource;
DrawSurfaceOptions mSurfOptions;
DrawOptions mOptions;
};
class DrawFilterCommand : public DrawingCommand
{
public:
DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
const Point& aDestPoint, const DrawOptions& aOptions)
: DrawingCommand(CommandType::DRAWSURFACE)
, mFilter(aFilter), mSourceRect(aSourceRect)
, mDestPoint(aDestPoint), mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->DrawFilter(mFilter, mSourceRect, mDestPoint, mOptions);
}
private:
RefPtr<FilterNode> mFilter;
Rect mSourceRect;
Point mDestPoint;
DrawOptions mOptions;
};
class ClearRectCommand : public DrawingCommand
{
public:
ClearRectCommand(const Rect& aRect)
: DrawingCommand(CommandType::CLEARRECT)
, mRect(aRect)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->ClearRect(mRect);
}
private:
Rect mRect;
};
class CopySurfaceCommand : public DrawingCommand
{
public:
CopySurfaceCommand(SourceSurface* aSurface,
const IntRect& aSourceRect,
const IntPoint& aDestination)
: DrawingCommand(CommandType::COPYSURFACE)
, mSurface(aSurface)
, mSourceRect(aSourceRect)
, mDestination(aDestination)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aTransform)
{
MOZ_ASSERT(!aTransform.HasNonIntegerTranslation());
Point dest(Float(mDestination.x), Float(mDestination.y));
dest = aTransform * dest;
aDT->CopySurface(mSurface, mSourceRect, IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
}
private:
RefPtr<SourceSurface> mSurface;
IntRect mSourceRect;
IntPoint mDestination;
};
class FillRectCommand : public DrawingCommand
{
public:
FillRectCommand(const Rect& aRect,
const Pattern& aPattern,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::FILLRECT)
, mRect(aRect)
, mPattern(aPattern)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->FillRect(mRect, mPattern, mOptions);
}
private:
Rect mRect;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeRectCommand : public DrawingCommand
{
public:
StrokeRectCommand(const Rect& aRect,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::STROKERECT)
, mRect(aRect)
, mPattern(aPattern)
, mStrokeOptions(aStrokeOptions)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions);
}
private:
Rect mRect;
StoredPattern mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class StrokeLineCommand : public DrawingCommand
{
public:
StrokeLineCommand(const Point& aStart,
const Point& aEnd,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::STROKELINE)
, mStart(aStart)
, mEnd(aEnd)
, mPattern(aPattern)
, mStrokeOptions(aStrokeOptions)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
}
private:
Point mStart;
Point mEnd;
StoredPattern mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class FillCommand : public DrawingCommand
{
public:
FillCommand(const Path* aPath,
const Pattern& aPattern,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::FILL)
, mPath(const_cast<Path*>(aPath))
, mPattern(aPattern)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->Fill(mPath, mPattern, mOptions);
}
private:
RefPtr<Path> mPath;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeCommand : public DrawingCommand
{
public:
StrokeCommand(const Path* aPath,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::STROKE)
, mPath(const_cast<Path*>(aPath))
, mPattern(aPattern)
, mStrokeOptions(aStrokeOptions)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions);
}
private:
RefPtr<Path> mPath;
StoredPattern mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class FillGlyphsCommand : public DrawingCommand
{
public:
FillGlyphsCommand(ScaledFont* aFont,
const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const DrawOptions& aOptions,
const GlyphRenderingOptions* aRenderingOptions)
: DrawingCommand(CommandType::FILLGLYPHS)
, mFont(aFont)
, mPattern(aPattern)
, mOptions(aOptions)
, mRenderingOptions(const_cast<GlyphRenderingOptions*>(aRenderingOptions))
{
mGlyphs.resize(aBuffer.mNumGlyphs);
memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs);
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
GlyphBuffer buf;
buf.mNumGlyphs = mGlyphs.size();
buf.mGlyphs = &mGlyphs.front();
aDT->FillGlyphs(mFont, buf, mPattern, mOptions, mRenderingOptions);
}
private:
RefPtr<ScaledFont> mFont;
std::vector<Glyph> mGlyphs;
StoredPattern mPattern;
DrawOptions mOptions;
RefPtr<GlyphRenderingOptions> mRenderingOptions;
};
class MaskCommand : public DrawingCommand
{
public:
MaskCommand(const Pattern& aSource,
const Pattern& aMask,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::MASK)
, mSource(aSource)
, mMask(aMask)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->Mask(mSource, mMask, mOptions);
}
private:
StoredPattern mSource;
StoredPattern mMask;
DrawOptions mOptions;
};
class MaskSurfaceCommand : public DrawingCommand
{
public:
MaskSurfaceCommand(const Pattern& aSource,
const SourceSurface* aMask,
const Point& aOffset,
const DrawOptions& aOptions)
: DrawingCommand(CommandType::MASKSURFACE)
, mSource(aSource)
, mMask(const_cast<SourceSurface*>(aMask))
, mOffset(aOffset)
, mOptions(aOptions)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->MaskSurface(mSource, mMask, mOffset, mOptions);
}
private:
StoredPattern mSource;
RefPtr<SourceSurface> mMask;
Point mOffset;
DrawOptions mOptions;
};
class PushClipCommand : public DrawingCommand
{
public:
PushClipCommand(const Path* aPath)
: DrawingCommand(CommandType::PUSHCLIP)
, mPath(const_cast<Path*>(aPath))
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->PushClip(mPath);
}
private:
RefPtr<Path> mPath;
};
class PushClipRectCommand : public DrawingCommand
{
public:
PushClipRectCommand(const Rect& aRect)
: DrawingCommand(CommandType::PUSHCLIPRECT)
, mRect(aRect)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->PushClipRect(mRect);
}
private:
Rect mRect;
};
class PopClipCommand : public DrawingCommand
{
public:
PopClipCommand()
: DrawingCommand(CommandType::POPCLIP)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->PopClip();
}
};
class SetTransformCommand : public DrawingCommand
{
public:
SetTransformCommand(const Matrix& aTransform)
: DrawingCommand(CommandType::SETTRANSFORM)
, mTransform(aTransform)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aMatrix)
{
Matrix transform = mTransform;
transform *= aMatrix;
aDT->SetTransform(transform);
}
private:
Matrix mTransform;
};
} /* namespace mozilla */
} /* namespace gfx */
#endif /* MOZILLA_GFX_DRAWCOMMAND_H_ */

39
gfx/2d/DrawTarget.cpp Normal file
View File

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "2D.h"
#include "Logging.h"
#include "DrawTargetCapture.h"
namespace mozilla {
namespace gfx {
TemporaryRef<DrawTargetCapture>
DrawTarget::CreateCaptureDT(const IntSize& aSize)
{
RefPtr<DrawTargetCaptureImpl> dt = new DrawTargetCaptureImpl();
if (!dt->Init(aSize, this)) {
gfxWarning() << "Failed to initialize Capture DrawTarget!";
return nullptr;
}
return dt;
}
void
DrawTarget::DrawCapturedDT(DrawTargetCapture *aCaptureDT,
const Matrix& aTransform)
{
if (aTransform.HasNonIntegerTranslation()) {
gfxWarning() << "Non integer translations are not supported for DrawCaptureDT at this time!";
return;
}
static_cast<DrawTargetCaptureImpl*>(aCaptureDT)->ReplayToDrawTarget(this, aTransform);
}
}
}

View File

@ -0,0 +1,197 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DrawTargetCapture.h"
#include "DrawCommand.h"
namespace mozilla {
namespace gfx {
DrawTargetCaptureImpl::~DrawTargetCaptureImpl()
{
uint8_t* start = &mDrawCommandStorage.front();
uint8_t* current = start;
while (current < start + mDrawCommandStorage.size()) {
reinterpret_cast<DrawingCommand*>(current + sizeof(uint32_t))->~DrawingCommand();
current += *(uint32_t*)current;
}
}
bool
DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT)
{
if (!aRefDT) {
return false;
}
mRefDT = aRefDT;
mSize = aSize;
return true;
}
TemporaryRef<SourceSurface>
DrawTargetCaptureImpl::Snapshot()
{
RefPtr<DrawTarget> dt = mRefDT->CreateSimilarDrawTarget(mSize, mRefDT->GetFormat());
ReplayToDrawTarget(dt, Matrix());
return dt->Snapshot();
}
#define AppendCommand(arg) new (AppendToCommandList<arg>()) arg
void
DrawTargetCaptureImpl::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aOptions)
{
aSurface->GuaranteePersistance();
AppendCommand(DrawSurfaceCommand)(aSurface, aDest, aSource, aSurfOptions, aOptions);
}
void
DrawTargetCaptureImpl::DrawFilter(FilterNode *aNode,
const Rect &aSourceRect,
const Point &aDestPoint,
const DrawOptions &aOptions)
{
// @todo XXX - this won't work properly long term yet due to filternodes not
// being immutable.
AppendCommand(DrawFilterCommand)(aNode, aSourceRect, aDestPoint, aOptions);
}
void
DrawTargetCaptureImpl::ClearRect(const Rect &aRect)
{
AppendCommand(ClearRectCommand)(aRect);
}
void
DrawTargetCaptureImpl::MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aOptions)
{
aMask->GuaranteePersistance();
AppendCommand(MaskSurfaceCommand)(aSource, aMask, aOffset, aOptions);
}
void
DrawTargetCaptureImpl::CopySurface(SourceSurface* aSurface,
const IntRect& aSourceRect,
const IntPoint& aDestination)
{
aSurface->GuaranteePersistance();
AppendCommand(CopySurfaceCommand)(aSurface, aSourceRect, aDestination);
}
void
DrawTargetCaptureImpl::FillRect(const Rect& aRect,
const Pattern& aPattern,
const DrawOptions& aOptions)
{
AppendCommand(FillRectCommand)(aRect, aPattern, aOptions);
}
void
DrawTargetCaptureImpl::StrokeRect(const Rect& aRect,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
{
AppendCommand(StrokeRectCommand)(aRect, aPattern, aStrokeOptions, aOptions);
}
void
DrawTargetCaptureImpl::StrokeLine(const Point& aStart,
const Point& aEnd,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
{
AppendCommand(StrokeLineCommand)(aStart, aEnd, aPattern, aStrokeOptions, aOptions);
}
void
DrawTargetCaptureImpl::Stroke(const Path* aPath,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
{
AppendCommand(StrokeCommand)(aPath, aPattern, aStrokeOptions, aOptions);
}
void
DrawTargetCaptureImpl::Fill(const Path* aPath,
const Pattern& aPattern,
const DrawOptions& aOptions)
{
AppendCommand(FillCommand)(aPath, aPattern, aOptions);
}
void
DrawTargetCaptureImpl::FillGlyphs(ScaledFont* aFont,
const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const DrawOptions& aOptions,
const GlyphRenderingOptions* aRenderingOptions)
{
AppendCommand(FillGlyphsCommand)(aFont, aBuffer, aPattern, aOptions, aRenderingOptions);
}
void
DrawTargetCaptureImpl::Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions)
{
AppendCommand(MaskCommand)(aSource, aMask, aOptions);
}
void
DrawTargetCaptureImpl::PushClip(const Path* aPath)
{
AppendCommand(PushClipCommand)(aPath);
}
void
DrawTargetCaptureImpl::PushClipRect(const Rect& aRect)
{
AppendCommand(PushClipRectCommand)(aRect);
}
void
DrawTargetCaptureImpl::PopClip()
{
AppendCommand(PopClipCommand)();
}
void
DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform)
{
AppendCommand(SetTransformCommand)(aTransform);
}
void
DrawTargetCaptureImpl::ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform)
{
uint8_t* start = &mDrawCommandStorage.front();
uint8_t* current = start;
while (current < start + mDrawCommandStorage.size()) {
reinterpret_cast<DrawingCommand*>(current + sizeof(uint32_t))->ExecuteOnDT(aDT, aTransform);
current += *(uint32_t*)current;
}
}
}
}

163
gfx/2d/DrawTargetCapture.h Normal file
View File

@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_DRAWTARGETCAPTURE_H_
#define MOZILLA_GFX_DRAWTARGETCAPTURE_H_
#include "2D.h"
#include <vector>
#include "Filters.h"
namespace mozilla {
namespace gfx {
class DrawingCommand;
class DrawTargetCaptureImpl : public DrawTargetCapture
{
public:
DrawTargetCaptureImpl()
{}
bool Init(const IntSize& aSize, DrawTarget* aRefDT);
virtual BackendType GetBackendType() const { return mRefDT->GetBackendType(); }
virtual DrawTargetType GetType() const { return mRefDT->GetType(); }
virtual TemporaryRef<SourceSurface> Snapshot();
virtual IntSize GetSize() { return mSize; }
virtual void Flush() {}
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aOptions);
virtual void DrawFilter(FilterNode *aNode,
const Rect &aSourceRect,
const Point &aDestPoint,
const DrawOptions &aOptions = DrawOptions());
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator) { /* Not implemented */ }
virtual void ClearRect(const Rect &aRect);
virtual void MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aOptions = DrawOptions());
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination);
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions(),
const GlyphRenderingOptions *aRenderingOptions = nullptr);
virtual void Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions = DrawOptions());
virtual void PushClip(const Path *aPath);
virtual void PushClipRect(const Rect &aRect);
virtual void PopClip();
virtual void SetTransform(const Matrix &aTransform);
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const
{
return mRefDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
}
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const
{
return mRefDT->OptimizeSourceSurface(aSurface);
}
virtual TemporaryRef<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
{
return mRefDT->CreateSourceSurfaceFromNativeSurface(aSurface);
}
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
return mRefDT->CreateSimilarDrawTarget(aSize, aFormat);
}
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const
{
return mRefDT->CreatePathBuilder(aFillRule);
}
virtual TemporaryRef<GradientStops>
CreateGradientStops(GradientStop *aStops,
uint32_t aNumStops,
ExtendMode aExtendMode = ExtendMode::CLAMP) const
{
return mRefDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
}
virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType)
{
return mRefDT->CreateFilter(aType);
}
void ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform);
protected:
~DrawTargetCaptureImpl();
private:
// This storage system was used to minimize the amount of heap allocations
// that are required while recording. It should be noted there's no
// guarantees on the alignments of DrawingCommands allocated in this array.
template<typename T>
T* AppendToCommandList()
{
size_t oldSize = mDrawCommandStorage.size();
mDrawCommandStorage.resize(mDrawCommandStorage.size() + sizeof(T) + sizeof(uint32_t));
uint8_t* nextDrawLocation = &mDrawCommandStorage.front() + oldSize;
*(uint32_t*)(nextDrawLocation) = sizeof(T) + sizeof(uint32_t);
return reinterpret_cast<T*>(nextDrawLocation + sizeof(uint32_t));
}
RefPtr<DrawTarget> mRefDT;
IntSize mSize;
std::vector<uint8_t> mDrawCommandStorage;
};
} /* namespace mozilla */
} /* namespace gfx */
#endif /* MOZILLA_GFX_DRAWTARGETCAPTURE_H_ */

View File

@ -14,6 +14,11 @@
namespace mozilla {
namespace gfx {
static bool FuzzyEqual(Float aV1, Float aV2) {
// XXX - Check if fabs does the smart thing and just negates the sign bit.
return fabs(aV2 - aV1) < 1e-6;
}
class Matrix
{
public:
@ -219,6 +224,16 @@ public:
!FuzzyEqual(_12, 0.0) || !FuzzyEqual(_21, 0.0);
}
/**
* Returns true if the matrix has any transform other
* than a translation or a -1 y scale (y axis flip)
*/
bool HasNonTranslationOrFlip() const {
return !FuzzyEqual(_11, 1.0) ||
(!FuzzyEqual(_22, 1.0) && !FuzzyEqual(_22, -1.0)) ||
!FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
}
/* Returns true if the matrix is an identity matrix.
*/
bool IsIdentity() const
@ -279,12 +294,6 @@ public:
return !FuzzyEqual(_11, floor(_11 + 0.5)) ||
!FuzzyEqual(_22, floor(_22 + 0.5));
}
private:
static bool FuzzyEqual(Float aV1, Float aV2) {
// XXX - Check if fabs does the smart thing and just negates the sign bit.
return fabs(aV2 - aV1) < 1e-6;
}
};
class Matrix4x4
@ -556,6 +565,85 @@ public:
bool Invert();
void ScalePost(Float aX, Float aY, Float aZ)
{
_11 *= aX;
_21 *= aX;
_31 *= aX;
_41 *= aX;
_12 *= aY;
_22 *= aY;
_32 *= aY;
_42 *= aY;
_13 *= aZ;
_23 *= aZ;
_33 *= aZ;
_43 *= aZ;
}
void TranslatePost(Float aX, Float aY, Float aZ)
{
_11 += _14 * aX;
_21 += _24 * aX;
_31 += _34 * aX;
_41 += _44 * aX;
_12 += _14 * aY;
_22 += _24 * aY;
_32 += _34 * aY;
_42 += _44 * aY;
_13 += _14 * aZ;
_23 += _24 * aZ;
_33 += _34 * aZ;
_43 += _44 * aZ;
}
bool FuzzyEqual(const Matrix4x4& o) const
{
return gfx::FuzzyEqual(_11, o._11) && gfx::FuzzyEqual(_12, o._12) &&
gfx::FuzzyEqual(_13, o._13) && gfx::FuzzyEqual(_14, o._14) &&
gfx::FuzzyEqual(_21, o._21) && gfx::FuzzyEqual(_22, o._22) &&
gfx::FuzzyEqual(_23, o._23) && gfx::FuzzyEqual(_24, o._24) &&
gfx::FuzzyEqual(_31, o._31) && gfx::FuzzyEqual(_32, o._32) &&
gfx::FuzzyEqual(_33, o._33) && gfx::FuzzyEqual(_34, o._34) &&
gfx::FuzzyEqual(_41, o._41) && gfx::FuzzyEqual(_42, o._42) &&
gfx::FuzzyEqual(_43, o._43) && gfx::FuzzyEqual(_44, o._44);
}
bool IsBackfaceVisible() const
{
// Inverse()._33 < 0;
Float det = Determinant();
Float __33 = _12*_24*_41 - _14*_22*_41 +
_14*_21*_42 - _11*_24*_42 -
_12*_21*_44 + _11*_22*_44;
return (__33 * det) < 0;
}
void NudgeToIntegersFixedEpsilon()
{
static const float error = 1e-5f;
NudgeToInteger(&_11, error);
NudgeToInteger(&_12, error);
NudgeToInteger(&_13, error);
NudgeToInteger(&_14, error);
NudgeToInteger(&_21, error);
NudgeToInteger(&_22, error);
NudgeToInteger(&_23, error);
NudgeToInteger(&_24, error);
NudgeToInteger(&_31, error);
NudgeToInteger(&_32, error);
NudgeToInteger(&_33, error);
NudgeToInteger(&_34, error);
NudgeToInteger(&_41, error);
NudgeToInteger(&_42, error);
NudgeToInteger(&_43, error);
NudgeToInteger(&_44, error);
}
// Set all the members of the matrix to NaN
void SetNAN();
};

View File

@ -28,6 +28,20 @@ SourceSurfaceRawData::InitWrappingData(uint8_t *aData,
return true;
}
void
SourceSurfaceRawData::GuaranteePersistance()
{
if (mOwnData) {
return;
}
uint8_t* oldData = mRawData;
mRawData = new uint8_t[mStride * mSize.height];
memcpy(mRawData, oldData, mStride * mSize.height);
mOwnData = true;
}
bool
SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
SurfaceFormat aFormat)

View File

@ -32,6 +32,8 @@ public:
SurfaceFormat aFormat,
bool aOwnData);
virtual void GuaranteePersistance();
private:
uint8_t *mRawData;
int32_t mStride;

View File

@ -97,7 +97,9 @@ UNIFIED_SOURCES += [
'DataSourceSurface.cpp',
'DataSurfaceHelpers.cpp',
'DrawEventRecorder.cpp',
'DrawTarget.cpp',
'DrawTargetCairo.cpp',
'DrawTargetCapture.cpp',
'DrawTargetDual.cpp',
'DrawTargetRecording.cpp',
'DrawTargetTiled.cpp',

View File

@ -10,7 +10,6 @@
#include "GLTypes.h"
#include "nsRect.h"
#include "nsTArray.h"
#include "gfx3DMatrix.h"
namespace mozilla {
namespace gl {

View File

@ -29,7 +29,6 @@
#include "GLDefs.h"
#include "GLLibraryLoader.h"
#include "gfx3DMatrix.h"
#include "nsISupportsImpl.h"
#include "plstr.h"
#include "nsDataHashtable.h"

View File

@ -13,11 +13,11 @@
#include <stdint.h>
#include "gfx3DMatrix.h"
#include "gfxColor.h"
#include "mozilla/gfx/Matrix.h"
#include "GraphicsFilter.h"
#include "gfxPoint.h"
#include "gfxPoint3D.h"
#include "gfxRect.h"
#include "nsRect.h"
#include "nsRegion.h"
@ -217,32 +217,6 @@ struct ParamTraits<gfxRect>
}
};
template<>
struct ParamTraits<gfx3DMatrix>
{
typedef gfx3DMatrix paramType;
static void Write(Message* msg, const paramType& param)
{
#define Wr(_f) WriteParam(msg, param. _f)
Wr(_11); Wr(_12); Wr(_13); Wr(_14);
Wr(_21); Wr(_22); Wr(_23); Wr(_24);
Wr(_31); Wr(_32); Wr(_33); Wr(_34);
Wr(_41); Wr(_42); Wr(_43); Wr(_44);
#undef Wr
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
#define Rd(_f) ReadParam(msg, iter, &result-> _f)
return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44));
#undef Rd
}
};
template <>
struct ParamTraits<gfxContentType>
: public ContiguousTypedEnumSerializer<

View File

@ -8,7 +8,6 @@
#include "ImageContainer.h" // for ImageContainer
#include "ImageLayers.h" // for ImageLayer, etc
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxColor.h" // for gfxRGBA
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPoint3D.h" // for gfxPoint3D
@ -26,6 +25,8 @@
#include "nsRect.h" // for nsIntRect
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
@ -33,18 +34,18 @@ struct LayerPropertiesBase;
LayerPropertiesBase* CloneLayerTreePropertiesInternal(Layer* aRoot);
static nsIntRect
TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform)
TransformRect(const nsIntRect& aRect, const Matrix4x4& aTransform)
{
if (aRect.IsEmpty()) {
return nsIntRect();
}
gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
Rect rect(aRect.x, aRect.y, aRect.width, aRect.height);
rect = aTransform.TransformBounds(rect);
rect.RoundOut();
nsIntRect intRect;
if (!gfxUtils::GfxRectToIntRect(rect, &intRect)) {
if (!gfxUtils::GfxRectToIntRect(ThebesRect(rect), &intRect)) {
return nsIntRect();
}
@ -52,7 +53,7 @@ TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform)
}
static void
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const gfx3DMatrix& aTransform)
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform)
{
nsIntRegionRectIterator iter(aSource);
const nsIntRect *r;
@ -114,7 +115,7 @@ struct LayerPropertiesBase : public LayerProperties
if (mUseClipRect) {
mClipRect = *aLayer->GetClipRect();
}
mTransform = gfx::To3DMatrix(aLayer->GetTransform());
mTransform = aLayer->GetTransform();
}
LayerPropertiesBase()
: mLayer(nullptr)
@ -136,8 +137,7 @@ struct LayerPropertiesBase : public LayerProperties
nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
gfx3DMatrix transform = gfx::To3DMatrix(mLayer->GetTransform());
bool transformChanged = !mTransform.FuzzyEqual(transform) ||
bool transformChanged = !mTransform.FuzzyEqual(mLayer->GetTransform()) ||
mLayer->GetPostXScale() != mPostXScale ||
mLayer->GetPostYScale() != mPostYScale;
Layer* otherMask = mLayer->GetMaskLayer();
@ -184,8 +184,7 @@ struct LayerPropertiesBase : public LayerProperties
nsIntRect NewTransformedBounds()
{
return TransformRect(mLayer->GetVisibleRegion().GetBounds(),
gfx::To3DMatrix(mLayer->GetTransform()));
return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetTransform());
}
nsIntRect OldTransformedBounds()
@ -203,7 +202,7 @@ struct LayerPropertiesBase : public LayerProperties
nsAutoPtr<LayerPropertiesBase> mMaskLayer;
nsIntRegion mVisibleRegion;
nsIntRegion mInvalidRegion;
gfx3DMatrix mTransform;
Matrix4x4 mTransform;
float mPostXScale;
float mPostYScale;
float mOpacity;
@ -292,8 +291,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
}
if (invalidateChildsCurrentArea) {
aGeometryChanged = true;
AddTransformedRegion(result, child->GetVisibleRegion(),
gfx::To3DMatrix(child->GetTransform()));
AddTransformedRegion(result, child->GetVisibleRegion(), child->GetTransform());
if (aCallback) {
NotifySubdocumentInvalidationRecursive(child, aCallback);
} else {
@ -442,8 +440,8 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu
} else {
ClearInvalidations(aRoot);
}
gfx3DMatrix transform = gfx::To3DMatrix(aRoot->GetTransform());
nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), transform);
nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(),
aRoot->GetTransform());
result = result.Union(OldTransformedBounds());
if (aGeometryChanged != nullptr) {
*aGeometryChanged = true;
@ -458,11 +456,11 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu
return invalid;
}
}
void
void
LayerPropertiesBase::MoveBy(const nsIntPoint& aOffset)
{
mTransform.TranslatePost(gfxPoint3D(aOffset.x, aOffset.y, 0));
mTransform.TranslatePost(aOffset.x, aOffset.y, 0);
}
} // namespace layers

View File

@ -7,7 +7,6 @@
#include "LayersLogging.h"
#include <stdint.h> // for uint8_t
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxColor.h" // for gfxRGBA
#include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix
#include "nsDebug.h" // for NS_ERROR

View File

@ -7,7 +7,6 @@
#include <sys/types.h> // for int32_t
#include "Layers.h" // for Layer, ThebesLayer, etc
#include "ReadbackLayer.h" // for ReadbackLayer, ReadbackSink
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxColor.h" // for gfxRGBA
#include "gfxContext.h" // for gfxContext
#include "gfxRect.h" // for gfxRect

View File

@ -24,14 +24,14 @@ static gfx::Matrix4x4 GetRootTransform(Layer *aLayer) {
return layerTrans;
}
void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform, bool aReset) {
void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset) {
if (!aLayer)
return;
gfx3DMatrix trans = aRootTransform * aLayer->GetTransform();
gfx::Matrix4x4 trans = aRootTransform * aLayer->GetTransform();
trans.ProjectTo2D();
nsIntRect clipRect = aLayer->GetEffectiveVisibleRegion().GetBounds();
gfxRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
trans.TransformBounds(rect);
if (strcmp(aLayer->Name(), "ContainerLayer") != 0 &&

View File

@ -15,15 +15,15 @@
#ifndef GFX_RENDERTRACE_H
#define GFX_RENDERTRACE_H
#include "gfx3DMatrix.h"
#include "nsRect.h"
#include "mozilla/gfx/Matrix.h"
namespace mozilla {
namespace layers {
class Layer;
void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform = gfx3DMatrix(), bool aReset = true);
void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform = gfx::Matrix4x4(), bool aReset = true);
void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect);
void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor);
@ -49,7 +49,7 @@ private:
};
#ifndef MOZ_RENDERTRACE
inline void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform, bool aReset)
inline void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset)
{}
inline void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect)

View File

@ -8,7 +8,6 @@
#include "CompositorParent.h" // for CompositorParent, etc
#include "InputData.h" // for InputData, etc
#include "Layers.h" // for ContainerLayer, Layer, etc
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/dom/Touch.h" // for Touch
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
@ -32,6 +31,9 @@
namespace mozilla {
namespace layers {
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
float APZCTreeManager::sDPI = 160.0;
APZCTreeManager::APZCTreeManager()
@ -139,7 +141,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
aRoot,
// aCompositor is null in gtest scenarios
aCompositor ? aCompositor->RootLayerTreeId() : 0,
gfx3DMatrix(), nullptr, nullptr,
Matrix4x4(), nullptr, nullptr,
aIsFirstPaint, aOriginatingLayersId,
paintLogger, &apzcsToDestroy, nsIntRegion());
mApzcTreeLog << "[end]\n";
@ -154,7 +156,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
AsyncPanZoomController*
APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
Layer* aLayer, uint64_t aLayersId,
gfx3DMatrix aTransform,
Matrix4x4 aTransform,
AsyncPanZoomController* aParent,
AsyncPanZoomController* aNextSibling,
bool aIsFirstPaint,
@ -165,7 +167,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
{
mTreeLock.AssertCurrentThreadOwns();
gfx3DMatrix transform = gfx::To3DMatrix(aLayer->GetTransform());
Matrix4x4 transform = aLayer->GetTransform();
ContainerLayer* container = aLayer->AsContainerLayer();
AsyncPanZoomController* apzc = nullptr;
@ -320,7 +322,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
// Accumulate the CSS transform between layers that have an APZC, but exclude any
// any layers that do have an APZC, and reset the accumulation at those layers.
if (apzc) {
aTransform = gfx3DMatrix();
aTransform = Matrix4x4();
} else {
// Multiply child layer transforms on the left so they get applied first
aTransform = transform * aTransform;
@ -342,7 +344,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
// have to check for mask layers and so on in order to properly handle
// that case.
obscured = aObscured;
obscured.Transform(transform.Inverse());
obscured.Transform(To3DMatrix(transform).Inverse());
}
// If there's no APZC at this level, any APZCs for our child layers will
@ -379,25 +381,25 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
}
/*static*/ template<class T> void
ApplyTransform(gfx::PointTyped<T>* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(gfx::PointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
Point result = aMatrix * aPoint->ToUnknownPoint();
aPoint->x = result.x;
aPoint->y = result.y;
}
/*static*/ template<class T> void
ApplyTransform(gfx::IntPointTyped<T>* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(gfx::IntPointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
aPoint->x = NS_lround(result.x);
aPoint->y = NS_lround(result.y);
Point result = aMatrix * aPoint->ToUnknownPoint();
aPoint->x = result.x;
aPoint->y = result.y;
}
/*static*/ void
ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(nsIntPoint* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
Point result = aMatrix * Point(aPoint->x, aPoint->y);
aPoint->x = NS_lround(result.x);
aPoint->y = NS_lround(result.y);
}
@ -405,7 +407,7 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
/*static*/ template<class T> void
TransformScreenToGecko(T* aPoint, AsyncPanZoomController* aApzc, APZCTreeManager* aApzcTm)
{
gfx3DMatrix transformToApzc, transformToGecko;
Matrix4x4 transformToApzc, transformToGecko;
aApzcTm->GetInputTransforms(aApzc, transformToApzc, transformToGecko);
ApplyTransform(aPoint, transformToApzc * transformToGecko);
}
@ -415,8 +417,8 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
ScrollableLayerGuid* aOutTargetGuid)
{
nsEventStatus result = nsEventStatus_eIgnore;
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
@ -560,11 +562,11 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
if (mApzcForInputBlock) {
// Cache apz transform so it can be used for future events in this block.
gfx3DMatrix transformToGecko;
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, mCachedTransformToApzcForInputBlock, transformToGecko);
} else {
// Reset the cached apz transform
mCachedTransformToApzcForInputBlock = gfx3DMatrix();
mCachedTransformToApzcForInputBlock = Matrix4x4();
}
} else if (mApzcForInputBlock) {
APZCTM_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
@ -597,7 +599,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// For computing the input for the APZC, used the cached transform.
// This ensures that the sequence of touch points an APZC sees in an
// input block are all in the same coordinate space.
gfx3DMatrix transformToApzc = mCachedTransformToApzcForInputBlock;
Matrix4x4 transformToApzc = mCachedTransformToApzcForInputBlock;
MultiTouchInput inputForApzc(aInput);
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
@ -607,9 +609,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// For computing the event to pass back to Gecko, use the up-to-date transforms.
// This ensures that transformToApzc and transformToGecko are in sync
// (note that transformToGecko isn't cached).
gfx3DMatrix transformToGecko;
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
ApplyTransform(&(aInput.mTouches[i].mScreenPoint), outTransform);
}
@ -650,10 +652,10 @@ APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
MOZ_ASSERT(aOutTransformedPoint);
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aPoint, nullptr);
if (apzc && aOutTransformedPoint) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
aOutTransformedPoint->x = aPoint.x;
aOutTransformedPoint->y = aPoint.y;
ApplyTransform(aOutTransformedPoint, outTransform);
@ -673,10 +675,10 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
&inOverscrolledApzc);
if (apzc) {
apzc->GetGuid(aOutTargetGuid);
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
ApplyTransform(&(aEvent.refPoint), outTransform);
}
return inOverscrolledApzc ? nsEventStatus_eConsumeNoDefault
@ -805,13 +807,15 @@ TransformDisplacement(APZCTreeManager* aTreeManager,
AsyncPanZoomController* aTarget,
ScreenPoint& aStartPoint,
ScreenPoint& aEndPoint) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko; // ignored
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko; // ignored
// Convert start and end points to untransformed screen coordinates.
aTreeManager->GetInputTransforms(aSource, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc.Inverse());
ApplyTransform(&aEndPoint, transformToApzc.Inverse());
Matrix4x4 untransformToApzc = transformToApzc;
untransformToApzc.Invert();
ApplyTransform(&aStartPoint, untransformToApzc);
ApplyTransform(&aEndPoint, untransformToApzc);
// Convert start and end points to aTarget's transformed screen coordinates.
aTreeManager->GetInputTransforms(aTarget, transformToApzc, transformToGecko);
@ -1183,12 +1187,13 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
// to aApzc's parent layer's layer coordinates.
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
// and RC.Inverse() * QC.Inverse() at recursion level for P.
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform();
ancestorUntransform.Invert();
// Hit testing for this layer takes place in our parent layer coordinates,
// since the composition bounds (used to initialize the visible rect against
// which we hit test are in those coordinates).
gfxPointH3D hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
gfxPointH3D hitTestPointForThisLayer = To3DMatrix(ancestorUntransform).ProjectPoint(aHitTestPoint);
APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
@ -1197,10 +1202,12 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
// to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates).
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P.
gfx3DMatrix childUntransform = ancestorUntransform
* aApzc->GetCSSTransform().Inverse()
* gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
gfxPointH3D hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
Matrix4x4 cssUntransform = aApzc->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
Matrix4x4 childUntransform = ancestorUntransform * cssUntransform * asyncUntransform;
gfxPointH3D hitTestPointForChildLayers = To3DMatrix(childUntransform).ProjectPoint(aHitTestPoint);
APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
@ -1333,8 +1340,8 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
required can be generated.
*/
void
APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut)
APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, Matrix4x4& aTransformToApzcOut,
Matrix4x4& aTransformToGeckoOut)
{
MonitorAutoLock lock(mTreeLock);
@ -1345,26 +1352,36 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix&
// leftmost matrix in a multiplication is applied first.
// ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse()
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is LA.Inverse()
gfx3DMatrix asyncUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// nontransientAsyncTransform is LN
gfx3DMatrix nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform();
Matrix4x4 nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform();
// transientAsyncUntransform is LT.Inverse()
gfx3DMatrix transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform;
Matrix4x4 transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform;
// aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = ancestorUntransform * aApzc->GetCSSTransform().Inverse() * nontransientAsyncTransform.Inverse();
Matrix4x4 cssUntransform = aApzc->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 nontransientAsyncUntransform = nontransientAsyncTransform;
nontransientAsyncUntransform.Invert();
aTransformToApzcOut = ancestorUntransform * cssUntransform * nontransientAsyncUntransform;
// aTransformToGeckoOut is initialized to LT.Inverse() * LD * LC * MC * NC * OC
aTransformToGeckoOut = transientAsyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetCSSTransform() * aApzc->GetAncestorTransform();
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform().Inverse();
ancestorUntransform = parent->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is updated to PA.Inverse() when parent == P
asyncUntransform = gfx3DMatrix(parent->GetCurrentAsyncTransform()).Inverse();
asyncUntransform = parent->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse()
gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * parent->GetCSSTransform().Inverse() * asyncUntransform;
cssUntransform = parent->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 untransformSinceLastApzc = ancestorUntransform * cssUntransform * asyncUntransform;
// aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut;

View File

@ -10,10 +10,10 @@
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "Units.h" // for CSSPoint, CSSRect, etc
#include "gfxPoint.h" // for gfxPoint
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/EventForwards.h" // for WidgetInputEvent, nsEventStatus
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
@ -21,7 +21,6 @@
#include "nsTArrayForwardDeclare.h" // for nsTArray, nsTArray_Impl, etc
#include "mozilla/gfx/Logging.h" // for gfx::TreeLog
class gfx3DMatrix;
class nsIntRegion;
namespace mozilla {
@ -327,8 +326,8 @@ public:
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
bool* aOutInOverscrolledApzc);
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut);
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx::Matrix4x4& aTransformToApzcOut,
gfx::Matrix4x4& aTransformToGeckoOut);
private:
/* Helpers */
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, FrameMetrics::ViewID aScrollId);
@ -358,7 +357,7 @@ private:
*/
AsyncPanZoomController* UpdatePanZoomControllerTree(CompositorParent* aCompositor,
Layer* aLayer, uint64_t aLayersId,
gfx3DMatrix aTransform,
gfx::Matrix4x4 aTransform,
AsyncPanZoomController* aParent,
AsyncPanZoomController* aNextSibling,
bool aIsFirstPaint,
@ -401,7 +400,7 @@ private:
* but for some operations we need to use the initial transform.
* Meaningless if mApzcForInputBlock is nullptr.
*/
gfx3DMatrix mCachedTransformToApzcForInputBlock;
gfx::Matrix4x4 mCachedTransformToApzcForInputBlock;
/* The chain of APZCs that will handle pans for the current touch input
* block, in the order in which they will be scrolled. When one APZC has
* been scrolled as far as it can, any overscroll will be handed off to

View File

@ -130,6 +130,8 @@ namespace layers {
typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
typedef GeckoContentController::APZStateChange APZStateChange;
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
/*
* The following prefs are used to control the behaviour of the APZC.
@ -1293,10 +1295,10 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut
{
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
treeManagerLocal->GetInputTransforms(this, transformToApzc, transformToGecko);
gfxPoint result = transformToGecko.Transform(gfxPoint(aPoint.x, aPoint.y));
Point result = transformToGecko * Point(aPoint.x, aPoint.y);
// NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
// for this coordinate space and it maps the closest to LayoutDevicePoint.
LayoutDevicePoint layoutPoint = LayoutDevicePoint(result.x, result.y);
@ -2300,20 +2302,20 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
/ mFrameMetrics.GetParentResolution());
}
gfx3DMatrix AsyncPanZoomController::GetNontransientAsyncTransform() {
Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() {
ReentrantMonitorAutoEnter lock(mMonitor);
return gfx3DMatrix::ScalingMatrix(mLastContentPaintMetrics.mResolution.scale,
mLastContentPaintMetrics.mResolution.scale,
1.0f);
return Matrix4x4().Scale(mLastContentPaintMetrics.mResolution.scale,
mLastContentPaintMetrics.mResolution.scale,
1.0f);
}
gfx3DMatrix AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
ReentrantMonitorAutoEnter lock(mMonitor);
LayerPoint scrollChange = (mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale;
return gfx3DMatrix::Translation(scrollChange.x, scrollChange.y, 0) *
gfx3DMatrix::ScalingMatrix(zoomChange, zoomChange, 1);
return Matrix4x4().Translate(scrollChange.x, scrollChange.y, 0) *
Matrix4x4().Scale(zoomChange, zoomChange, 1);
}
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
@ -2861,16 +2863,16 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint)
{
return TransformTo<ParentLayerPixel>(GetNontransientAsyncTransform() * GetCSSTransform(), aPoint);
return TransformTo<ParentLayerPixel>(To3DMatrix(GetNontransientAsyncTransform() * GetCSSTransform()), aPoint);
}
void AsyncPanZoomController::UpdateTransformScale()
{
gfx3DMatrix nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform();
if (!FuzzyEqualsMultiplicative(nontransientTransforms.GetXScale(), nontransientTransforms.GetYScale())) {
Matrix4x4 nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform();
if (!FuzzyEqualsMultiplicative(nontransientTransforms._11, nontransientTransforms._22)) {
NS_WARNING("The x- and y-scales of the nontransient transforms should be equal");
}
mFrameMetrics.mTransformScale.scale = nontransientTransforms.GetXScale();
mFrameMetrics.mTransformScale.scale = nontransientTransforms._11;
}
}

View File

@ -20,7 +20,7 @@
#include "InputData.h"
#include "Axis.h"
#include "TaskThrottler.h"
#include "gfx3DMatrix.h"
#include "mozilla/gfx/Matrix.h"
#include "nsRegion.h"
#include "base/message_loop.h"
@ -69,6 +69,7 @@ class AsyncPanZoomController {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController)
typedef mozilla::MonitorAutoLock MonitorAutoLock;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef uint32_t TouchBehaviorFlags;
public:
@ -221,9 +222,9 @@ public:
/**
* Returns the part of the async transform that will remain once Gecko does a
* repaint at the desired metrics. That is, in the steady state:
* gfx3DMatrix(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
* Matrix4x4(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
*/
gfx3DMatrix GetNontransientAsyncTransform();
Matrix4x4 GetNontransientAsyncTransform();
/**
* Returns the transform to take something from the coordinate space of the
@ -232,7 +233,7 @@ public:
* processed, this is needed to transform input events properly into a space
* gecko will understand.
*/
gfx3DMatrix GetTransformToLastDispatchedPaint();
Matrix4x4 GetTransformToLastDispatchedPaint();
/**
* Recalculates the displayport. Ideally, this should paint an area bigger
@ -942,19 +943,19 @@ private:
* hit-testing to see which APZC instance should handle touch events.
*/
public:
void SetLayerHitTestData(const nsIntRegion& aRegion, const gfx3DMatrix& aTransformToLayer,
const gfx3DMatrix& aTransformForLayer) {
void SetLayerHitTestData(const nsIntRegion& aRegion, const Matrix4x4& aTransformToLayer,
const Matrix4x4& aTransformForLayer) {
mVisibleRegion = aRegion;
mAncestorTransform = aTransformToLayer;
mCSSTransform = aTransformForLayer;
UpdateTransformScale();
}
gfx3DMatrix GetAncestorTransform() const {
Matrix4x4 GetAncestorTransform() const {
return mAncestorTransform;
}
gfx3DMatrix GetCSSTransform() const {
Matrix4x4 GetCSSTransform() const {
return mCSSTransform;
}
@ -974,9 +975,9 @@ private:
nsIntRegion mVisibleRegion;
/* This is the cumulative CSS transform for all the layers between the parent
* APZC and this one (not inclusive) */
gfx3DMatrix mAncestorTransform;
Matrix4x4 mAncestorTransform;
/* This is the CSS transform for this APZC's layer. */
gfx3DMatrix mCSSTransform;
Matrix4x4 mCSSTransform;
/* ===================================================================

View File

@ -7,7 +7,6 @@
#include "Units.h" // for ScreenIntRect, CSSPoint, etc
#include "UnitTransforms.h" // for TransformTo
#include "ClientLayerManager.h" // for ClientLayerManager, etc
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxRect.h" // for gfxRect
@ -58,12 +57,12 @@ ClientTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
}
static LayerRect
ApplyParentLayerToLayerTransform(const gfx3DMatrix& aTransform, const ParentLayerRect& aParentLayerRect)
ApplyParentLayerToLayerTransform(const gfx::Matrix4x4& aTransform, const ParentLayerRect& aParentLayerRect)
{
return TransformTo<LayerPixel>(aTransform, aParentLayerRect);
return TransformTo<LayerPixel>(gfx::To3DMatrix(aTransform), aParentLayerRect);
}
static gfx3DMatrix
static gfx::Matrix4x4
GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor)
{
gfx::Matrix4x4 transform;
@ -77,7 +76,7 @@ GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor)
}
transform = transform * iter->GetTransform();
}
return gfx::To3DMatrix(transform);
return transform;
}
void
@ -145,8 +144,9 @@ ClientTiledThebesLayer::BeginPaint()
// Calculate the transform required to convert ParentLayer space of our
// display port ancestor to the Layer space of this layer.
gfx3DMatrix transformDisplayPortToLayer =
GetTransformToAncestorsParentLayer(this, displayPortAncestor).Inverse();
gfx::Matrix4x4 transformDisplayPortToLayer =
GetTransformToAncestorsParentLayer(this, displayPortAncestor);
transformDisplayPortToLayer.Invert();
// Note that below we use GetZoomToParent() in a number of places. Because this
// code runs on the client side, the mTransformScale field of the FrameMetrics
@ -171,8 +171,10 @@ ClientTiledThebesLayer::BeginPaint()
// Store the applicable composition bounds in this layer's Layer units.
mPaintData.mTransformToCompBounds =
GetTransformToAncestorsParentLayer(this, scrollAncestor);
gfx::Matrix4x4 transformToBounds = mPaintData.mTransformToCompBounds;
transformToBounds.Invert();
mPaintData.mCompositionBounds = ApplyParentLayerToLayerTransform(
mPaintData.mTransformToCompBounds.Inverse(), scrollMetrics.mCompositionBounds);
transformToBounds, scrollMetrics.mCompositionBounds);
TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());
// Calculate the scroll offset since the last transaction

View File

@ -1126,30 +1126,31 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
*/
static LayerRect
GetCompositorSideCompositionBounds(ContainerLayer* aScrollAncestor,
const gfx3DMatrix& aTransformToCompBounds,
const Matrix4x4& aTransformToCompBounds,
const ViewTransform& aAPZTransform)
{
gfx3DMatrix nonTransientAPZTransform = gfx3DMatrix::ScalingMatrix(
Matrix4x4 nonTransientAPZUntransform = Matrix4x4().Scale(
aScrollAncestor->GetFrameMetrics().mResolution.scale,
aScrollAncestor->GetFrameMetrics().mResolution.scale,
1.f);
nonTransientAPZUntransform.Invert();
gfx3DMatrix layerTransform = gfx::To3DMatrix(aScrollAncestor->GetTransform());
Matrix4x4 layerTransform = aScrollAncestor->GetTransform();
Matrix4x4 layerUntransform = layerTransform;
layerUntransform.Invert();
// First take off the last two "terms" of aTransformToCompBounds, which
// are the scroll ancestor's local transform and the APZ's nontransient async
// transform.
gfx3DMatrix transform = aTransformToCompBounds;
transform = transform * layerTransform.Inverse();
transform = transform * nonTransientAPZTransform.Inverse();
Matrix4x4 transform = aTransformToCompBounds * layerUntransform * nonTransientAPZUntransform;
// Next, apply the APZ's async transform (this includes the nontransient component
// as well).
transform = transform * gfx3DMatrix(aAPZTransform);
transform = transform * Matrix4x4(aAPZTransform);
// Finally, put back the scroll ancestor's local transform.
transform = transform * layerTransform;
return TransformTo<LayerPixel>(transform.Inverse(),
return TransformTo<LayerPixel>(To3DMatrix(transform).Inverse(),
aScrollAncestor->GetFrameMetrics().mCompositionBounds);
}

View File

@ -12,7 +12,6 @@
#include "Layers.h" // for LayerManager, etc
#include "TiledLayerBuffer.h" // for TiledLayerBuffer
#include "Units.h" // for CSSPoint
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxTypes.h"
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr
@ -289,7 +288,7 @@ struct BasicTiledLayerPaintData {
* the closest ancestor layer which scrolls, and is used to obtain
* the composition bounds that are relevant for this layer.
*/
gfx3DMatrix mTransformToCompBounds;
gfx::Matrix4x4 mTransformToCompBounds;
/*
* The critical displayport of the content from the nearest ancestor layer

View File

@ -509,9 +509,9 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
}
Matrix4x4
AdjustAndCombineWithCSSTransform(const gfx3DMatrix& asyncTransform, Layer* aLayer)
AdjustAndCombineWithCSSTransform(const Matrix4x4& asyncTransform, Layer* aLayer)
{
Matrix4x4 result = ToMatrix4x4(asyncTransform);
Matrix4x4 result = asyncTransform;
// Container layers start at the origin, but they are clipped to where they
// actually have content on the screen. The tree transform is meant to apply
@ -675,9 +675,11 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer
apzc->SampleContentTransformForFrame(aCurrentFrame, &asyncTransform, scrollOffset);
}
gfx3DMatrix asyncTransform = gfx3DMatrix(apzc->GetCurrentAsyncTransform());
gfx3DMatrix nontransientTransform = apzc->GetNontransientAsyncTransform();
gfx3DMatrix transientTransform = asyncTransform * nontransientTransform.Inverse();
Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform();
Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform();
Matrix4x4 nontransientUntransform = nontransientTransform;
nontransientUntransform.Invert();
Matrix4x4 transientTransform = asyncTransform * nontransientUntransform;
// |transientTransform| represents the amount by which we have scrolled and
// zoomed since the last paint. Because the scrollbar was sized and positioned based
@ -695,12 +697,12 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer
Matrix4x4 scrollbarTransform;
if (aScrollbar->GetScrollbarDirection() == Layer::VERTICAL) {
float scale = metrics.CalculateCompositedSizeInCssPixels().height / metrics.mScrollableRect.height;
scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f, 1.f / transientTransform.GetYScale(), 1.f);
scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f, 1.f / transientTransform._22, 1.f);
scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(0, -transientTransform._42 * scale, 0);
}
if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) {
float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.mScrollableRect.width;
scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f / transientTransform.GetXScale(), 1.f, 1.f);
scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f / transientTransform._11, 1.f, 1.f);
scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(-transientTransform._41 * scale, 0, 0);
}
@ -712,7 +714,8 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer
// the content. This is needed because otherwise that transient async transform is
// part of the effective transform of this scrollbar, and the scrollbar will jitter
// as the content scrolls.
transform = transform * ToMatrix4x4(transientTransform.Inverse());
transientTransform.Invert();
transform = transform * transientTransform;
}
// GetTransform already takes the pre- and post-scale into account. Since we
@ -780,11 +783,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
const FrameMetrics& metrics = container->GetFrameMetrics();
// We must apply the resolution scale before a pan/zoom transform, so we call
// GetTransform here.
gfx3DMatrix currentTransform = To3DMatrix(aLayer->GetTransform());
Matrix4x4 oldTransform = aLayer->GetTransform();
gfx3DMatrix treeTransform;
CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel();
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.GetScrollOffset() * geckoZoom);
@ -842,22 +842,22 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
}
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
treeTransform = gfx3DMatrix(ViewTransform(-translation,
Matrix4x4 treeTransform = ViewTransform(-translation,
userZoom
/ metrics.mDevPixelsPerCSSPixel
/ metrics.GetParentResolution()));
/ metrics.GetParentResolution());
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
gfx3DMatrix computedTransform = treeTransform * currentTransform;
Matrix4x4 computedTransform = treeTransform * oldTransform;
computedTransform.Scale(1.0f/container->GetPreXScale(),
1.0f/container->GetPreYScale(),
1);
computedTransform.ScalePost(1.0f/container->GetPostXScale(),
1.0f/container->GetPostYScale(),
1);
layerComposite->SetShadowTransform(ToMatrix4x4(computedTransform));
layerComposite->SetShadowTransform(computedTransform);
NS_ASSERTION(!layerComposite->GetShadowTransformSetByAnimation(),
"overwriting animated transform!");

View File

@ -8,12 +8,12 @@
#include "Units.h" // for LayerPoint, etc
#include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_FINAL, etc
#include "mozilla/RefPtr.h" // for RefCounted
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
@ -34,17 +34,17 @@ struct ViewTransform {
, mScale(aScale)
{}
operator gfx3DMatrix() const
operator gfx::Matrix4x4() const
{
return
gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) *
gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1);
gfx::Matrix4x4().Translate(mTranslation.x, mTranslation.y, 0) *
gfx::Matrix4x4().Scale(mScale.scale, mScale.scale, 1);
}
// For convenience, to avoid writing the cumbersome
// "gfx3dMatrix(a) * gfx3DMatrix(b)".
friend gfx3DMatrix operator*(const ViewTransform& a, const ViewTransform& b) {
return gfx3DMatrix(a) * gfx3DMatrix(b);
// "gfx::Matrix4x4(a) * gfx::Matrix4x4(b)".
friend gfx::Matrix4x4 operator*(const ViewTransform& a, const ViewTransform& b) {
return gfx::Matrix4x4(a) * gfx::Matrix4x4(b);
}
bool operator==(const ViewTransform& rhs) const {

View File

@ -8,7 +8,6 @@
#include "FrameMetrics.h" // for FrameMetrics
#include "Units.h" // for LayerRect, LayerPixel, etc
#include "gfx2DGlue.h" // for ToMatrix4x4
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxUtils.h" // for gfxUtils, etc
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc

View File

@ -22,7 +22,6 @@
#include "TiledLayerBuffer.h" // for TiledLayerComposer
#include "Units.h" // for ScreenIntRect
#include "gfx2DGlue.h" // for ToMatrix4x4
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxPrefs.h" // for gfxPrefs
#ifdef XP_MACOSX
#include "gfxPlatformMac.h"
@ -564,7 +563,7 @@ LayerManagerComposite::WorldTransformRect(nsIntRect& aRect)
static void
SubtractTransformedRegion(nsIntRegion& aRegion,
const nsIntRegion& aRegionToSubtract,
const gfx3DMatrix& aTransform)
const Matrix4x4& aTransform)
{
if (aRegionToSubtract.IsEmpty()) {
return;
@ -574,7 +573,7 @@ SubtractTransformedRegion(nsIntRegion& aRegion,
// subtract it from the screen region.
nsIntRegionRectIterator it(aRegionToSubtract);
while (const nsIntRect* rect = it.Next()) {
gfxRect incompleteRect = aTransform.TransformBounds(gfxRect(*rect));
Rect incompleteRect = aTransform.TransformBounds(ToRect(*rect));
aRegion.Sub(aRegion, nsIntRect(incompleteRect.x,
incompleteRect.y,
incompleteRect.width,
@ -586,7 +585,7 @@ SubtractTransformedRegion(nsIntRegion& aRegion,
LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
nsIntRegion& aScreenRegion,
nsIntRegion& aLowPrecisionScreenRegion,
const gfx3DMatrix& aTransform)
const Matrix4x4& aTransform)
{
if (aLayer->GetOpacity() <= 0.f ||
(aScreenRegion.IsEmpty() && aLowPrecisionScreenRegion.IsEmpty())) {
@ -597,10 +596,10 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
ContainerLayer* container = aLayer->AsContainerLayer();
if (container) {
// Accumulate the transform of intermediate surfaces
gfx3DMatrix transform = aTransform;
Matrix4x4 transform = aTransform;
if (container->UseIntermediateSurface()) {
transform = gfx::To3DMatrix(aLayer->GetEffectiveTransform());
transform.PreMultiply(aTransform);
transform = aLayer->GetEffectiveTransform();
transform = aTransform * transform;
}
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
@ -621,8 +620,8 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
if (!incompleteRegion.IsEmpty()) {
// Calculate the transform to get between screen and layer space
gfx3DMatrix transformToScreen = To3DMatrix(aLayer->GetEffectiveTransform());
transformToScreen.PreMultiply(aTransform);
Matrix4x4 transformToScreen = aLayer->GetEffectiveTransform();
transformToScreen = aTransform * transformToScreen;
SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
@ -650,14 +649,12 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
#ifdef MOZ_ANDROID_OMTC
static float
GetDisplayportCoverage(const CSSRect& aDisplayPort,
const gfx3DMatrix& aTransformToScreen,
const Matrix4x4& aTransformToScreen,
const nsIntRect& aScreenRect)
{
gfxRect transformedDisplayport =
aTransformToScreen.TransformBounds(gfxRect(aDisplayPort.x,
aDisplayPort.y,
aDisplayPort.width,
aDisplayPort.height));
Rect transformedDisplayport =
aTransformToScreen.TransformBounds(aDisplayPort.ToUnknownRect());
transformedDisplayport.RoundOut();
nsIntRect displayport = nsIntRect(transformedDisplayport.x,
transformedDisplayport.y,
@ -700,15 +697,15 @@ LayerManagerComposite::ComputeRenderIntegrity()
// This is derived from the code in
// AsyncCompositionManager::TransformScrollableLayer
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
gfx3DMatrix transform = gfx::To3DMatrix(primaryScrollable->GetEffectiveTransform());
Matrix4x4 transform = primaryScrollable->GetEffectiveTransform();
transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);
// Clip the screen rect to the document bounds
gfxRect documentBounds =
transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x,
metrics.mScrollableRect.y - metrics.GetScrollOffset().y,
metrics.mScrollableRect.width,
metrics.mScrollableRect.height));
Rect documentBounds =
transform.TransformBounds(Rect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x,
metrics.mScrollableRect.y - metrics.GetScrollOffset().y,
metrics.mScrollableRect.width,
metrics.mScrollableRect.height));
documentBounds.RoundOut();
screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
documentBounds.width, documentBounds.height));
@ -747,7 +744,7 @@ LayerManagerComposite::ComputeRenderIntegrity()
nsIntRegion screenRegion(screenRect);
nsIntRegion lowPrecisionScreenRegion(screenRect);
gfx3DMatrix transform;
Matrix4x4 transform;
ComputeRenderIntegrityInternal(root, screenRegion,
lowPrecisionScreenRegion, transform);

View File

@ -252,7 +252,7 @@ private:
static void ComputeRenderIntegrityInternal(Layer* aLayer,
nsIntRegion& aScreenRegion,
nsIntRegion& aLowPrecisionScreenRegion,
const gfx3DMatrix& aTransform);
const gfx::Matrix4x4& aTransform);
/**
* Render the current layer tree to the active target.

View File

@ -11,7 +11,6 @@
#include "ImageLayers.h" // for ImageLayer
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "ShadowLayerParent.h" // for ShadowLayerParent
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxPoint3D.h" // for gfxPoint3D
#include "CompositableTransactionParent.h" // for EditReplyVector
#include "ShadowLayersManager.h" // for ShadowLayersManager
@ -631,7 +630,7 @@ LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent,
// from the shadow transform by undoing the translations in
// AsyncCompositionManager::SampleValue.
gfx3DMatrix transform = gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform());
Matrix4x4 transform = layer->AsLayerComposite()->GetShadowTransform();
if (ContainerLayer* c = layer->AsContainerLayer()) {
// Undo the scale transform applied by AsyncCompositionManager::SampleValue
transform.ScalePost(1.0f/c->GetInheritedXScale(),
@ -658,11 +657,12 @@ LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent,
// Undo the translation to the origin of the reference frame applied by
// AsyncCompositionManager::SampleValue
transform.Translate(-scaledOrigin);
transform.Translate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z);
// Undo the rebasing applied by
// nsDisplayTransform::GetResultingTransformMatrixInternal
transform.ChangeBasis(-scaledOrigin - transformOrigin);
gfxPoint3D basis = -scaledOrigin - transformOrigin;
transform.ChangeBasis(basis.x, basis.y, basis.z);
// Convert to CSS pixels (this undoes the operations performed by
// nsStyleTransformMatrix::ProcessTranslatePart which is called from

View File

@ -17,8 +17,6 @@
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
class gfx3DMatrix;
namespace mozilla {
namespace ipc {

View File

@ -20,7 +20,6 @@ using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h";
using struct gfxRGBA from "gfxColor.h";
using struct gfxPoint3D from "gfxPoint3D.h";
using class mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using class gfx3DMatrix from "gfx3DMatrix.h";
using nscoord from "nsCoord.h";
using struct nsIntPoint from "nsPoint.h";
using struct nsRect from "nsRect.h";
@ -151,7 +150,7 @@ struct AnimationSegment {
};
// Transforms need extra information to correctly convert the list of transform
// functions to a gfx3DMatrix that can be applied directly to the layer.
// functions to a Matrix4x4 that can be applied directly to the layer.
struct TransformData {
// the origin of the frame being transformed in app units
nsPoint origin;

View File

@ -32,7 +32,7 @@ namespace mozilla {
namespace layers {
union MaybeTransform {
gfx3DMatrix;
Matrix4x4;
void_t;
};

View File

@ -13,7 +13,6 @@
#include "Layers.h" // for WriteSnapshotToDumpFile
#include "LayerScope.h" // for LayerScope
#include "gfx2DGlue.h" // for ThebesFilter
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPlatform.h" // for gfxPlatform

View File

@ -35,7 +35,6 @@
#include <ui/GraphicBuffer.h>
#endif
class gfx3DMatrix;
class nsIWidget;
namespace mozilla {

View File

@ -7,7 +7,6 @@
#define GFX_OGLSHADERPROGRAM_H
#include "GLContext.h" // for fast inlines of glUniform*
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxTypes.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for RefPtr
@ -471,10 +470,6 @@ protected:
}
}
void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx3DMatrix& aMatrix) {
SetMatrixUniform(aKnownUniform, &aMatrix._11);
}
void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(aKnownUniform, &aMatrix._11);
}

View File

@ -711,9 +711,9 @@ TEST_F(APZCBasicTester, ComplexTransform) {
nsIntRegion(nsIntRect(0, 0, 300, 300)),
nsIntRegion(nsIntRect(0, 0, 150, 300)),
};
gfx3DMatrix transforms[] = {
gfx3DMatrix(),
gfx3DMatrix(),
Matrix4x4 transforms[] = {
Matrix4x4(),
Matrix4x4(),
};
transforms[0].ScalePost(0.5f, 0.5f, 1.0f); // this results from the 2.0 resolution on the root layer
transforms[1].ScalePost(2.0f, 1.0f, 1.0f); // this is the 2.0 x-axis CSS transform on the child layer
@ -1451,12 +1451,12 @@ CreateTestLayerTree1(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<La
nsIntRegion(nsIntRect(10,10,20,20)),
nsIntRegion(nsIntRect(5,5,20,20)),
};
gfx3DMatrix transforms[] = {
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
Matrix4x4 transforms[] = {
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
};
return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers);
}
@ -1472,11 +1472,11 @@ CreateTestLayerTree2(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<La
nsIntRegion(nsIntRect(10,60,40,40)),
nsIntRegion(nsIntRect(10,60,40,40)),
};
gfx3DMatrix transforms[] = {
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
Matrix4x4 transforms[] = {
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
};
return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers);
}
@ -1500,7 +1500,7 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
static already_AddRefed<AsyncPanZoomController>
GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint,
gfx3DMatrix& aTransformToApzcOut, gfx3DMatrix& aTransformToGeckoOut)
Matrix4x4& aTransformToApzcOut, Matrix4x4& aTransformToGeckoOut)
{
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(aPoint, nullptr);
if (hit) {
@ -1521,15 +1521,15 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
ScopedLayerTreeRegistration controller(0, root, mcc);
nsRefPtr<APZCTreeManager> manager = new TestAPZCTreeManager();
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
// No APZC attached so hit testing will return no APZC at (20,20)
nsRefPtr<AsyncPanZoomController> hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToGecko);
AsyncPanZoomController* nullAPZC = nullptr;
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
uint32_t paintSequenceNumber = 0;
@ -1539,8 +1539,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(15, 15)
EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15)));
EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15)));
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
// Now we have a sub APZC with a better fit
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
@ -1549,8 +1549,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(25, 25)
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
// At this point, layers[4] obscures layers[3] at the point (15, 15) so
// hitting there should hit the root APZC
@ -1563,25 +1563,25 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(15, 15)
EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15)));
EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15)));
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
// Hit test ouside the reach of layer[3,4] but inside root
hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko);
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(90, 90)
EXPECT_EQ(gfxPoint(90, 90), transformToApzc.Transform(gfxPoint(90, 90)));
EXPECT_EQ(gfxPoint(90, 90), transformToGecko.Transform(gfxPoint(90, 90)));
EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90));
EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90));
// Hit test ouside the reach of any layer
hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToGecko);
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToGecko);
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
manager->ClearTree();
}
@ -1599,8 +1599,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
nsRefPtr<TestAPZCTreeManager> manager = new TestAPZCTreeManager();
nsRefPtr<AsyncPanZoomController> hit;
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
// Set a CSS transform on one of the layers.
Matrix4x4 transform;
@ -1627,8 +1627,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
// Hit an area that's clearly on the root layer but not any of the child layers.
hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25)));
EXPECT_EQ(gfxPoint(75, 25), transformToGecko.Transform(gfxPoint(75, 25)));
EXPECT_EQ(Point(75, 25), transformToApzc * Point(75, 25));
EXPECT_EQ(Point(75, 25), transformToGecko * Point(75, 25));
// Hit an area on the root that would be on layers[3] if layers[2]
// weren't transformed.
@ -1639,31 +1639,31 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
// start at x=10 but its content at x=20).
hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75)));
EXPECT_EQ(gfxPoint(15, 75), transformToGecko.Transform(gfxPoint(15, 75)));
EXPECT_EQ(Point(15, 75), transformToApzc * Point(15, 75));
EXPECT_EQ(Point(15, 75), transformToGecko * Point(15, 75));
// Hit an area on layers[1].
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzc1, hit.get());
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
// Hit an area on layers[3].
hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc should unapply layers[2]'s transform
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75)));
EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 75));
// and transformToGecko should reapply it
EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(12.5, 75)));
EXPECT_EQ(Point(25, 75), transformToGecko * Point(12.5, 75));
// Hit an area on layers[3] that would be on the root if layers[2]
// weren't transformed.
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc should unapply layers[2]'s transform
EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(37.5, 75), transformToApzc * Point(75, 75));
// and transformToGecko should reapply it
EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(37.5, 75)));
EXPECT_EQ(Point(75, 75), transformToGecko * Point(37.5, 75));
// Pan the root layer upward by 50 pixels.
// This causes layers[1] to scroll out of view, and an async transform
@ -1685,21 +1685,21 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
// transformToApzc doesn't unapply the root's own async transform
EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
// and transformToGecko unapplies it and then reapplies it, because by the
// time the event being transformed reaches Gecko the new paint request will
// have been handled.
EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 75), transformToGecko * Point(75, 75));
// Hit where layers[1] used to be and where layers[3] should now be.
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc unapplies both layers[2]'s css transform and the root's
// async transform
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 25));
// transformToGecko reapplies both the css transform and the async transform
// because we have already issued a paint request with it.
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(12.5, 75)));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(12.5, 75));
// This second pan will move the APZC by another 50 pixels but since the paint
// request dispatched above has not "completed", we will not dispatch another
@ -1713,19 +1713,19 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
// transformToApzc doesn't unapply the root's own async transform
EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
// transformToGecko unapplies the full async transform of -100 pixels, and then
// reapplies the "D" transform of -50 leading to an overall adjustment of +50
EXPECT_EQ(gfxPoint(75, 125), transformToGecko.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 125), transformToGecko * Point(75, 75));
// Hit where layers[1] used to be. It should now hit the root.
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
// transformToApzc doesn't unapply the root's own async transform
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
// transformToGecko unapplies the full async transform of -100 pixels, and then
// reapplies the "D" transform of -50 leading to an overall adjustment of +50
EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 75), transformToGecko * Point(25, 25));
manager->ClearTree();
}

View File

@ -162,7 +162,7 @@ already_AddRefed<Layer> CreateLayer(char aLayerType, LayerManager* aManager) {
already_AddRefed<Layer> CreateLayerTree(
const char* aLayerTreeDescription,
nsIntRegion* aVisibleRegions,
const gfx3DMatrix* aTransforms,
const Matrix4x4* aTransforms,
nsRefPtr<LayerManager>& manager,
nsTArray<nsRefPtr<Layer> >& aLayersOut) {
@ -194,7 +194,7 @@ already_AddRefed<Layer> CreateLayerTree(
layer->SetVisibleRegion(aVisibleRegions[layerNumber]);
}
if (aTransforms) {
layer->SetBaseTransform(ToMatrix4x4(aTransforms[layerNumber]));
layer->SetBaseTransform(aTransforms[layerNumber]);
}
aLayersOut.AppendElement(layer);
layerNumber++;
@ -225,11 +225,11 @@ TEST(Layers, LayerTree) {
nsIntRegion(nsIntRect(0,0,100,100)),
nsIntRegion(nsIntRect(10,10,20,20)),
};
gfx3DMatrix transforms[] = {
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
gfx3DMatrix(),
Matrix4x4 transforms[] = {
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
Matrix4x4(),
};
nsTArray<nsRefPtr<Layer> > layers;

View File

@ -27,7 +27,7 @@
already_AddRefed<mozilla::layers::Layer> CreateLayerTree(
const char* aLayerTreeDescription,
nsIntRegion* aVisibleRegions,
const gfx3DMatrix* aTransforms,
const mozilla::gfx::Matrix4x4* aTransforms,
nsRefPtr<mozilla::layers::LayerManager>& aLayerManager,
nsTArray<nsRefPtr<mozilla::layers::Layer> >& aLayersOut);

View File

@ -2031,15 +2031,16 @@ gfxPlatform::UsesOffMainThreadCompositing()
gfxPrefs::LayersOffMainThreadCompositionEnabled() ||
gfxPrefs::LayersOffMainThreadCompositionForceEnabled() ||
gfxPrefs::LayersOffMainThreadCompositionTestingEnabled();
#if defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD)
#if defined(MOZ_WIDGET_GTK)
// Linux users who chose OpenGL are being grandfathered in to OMTC
result |=
gfxPrefs::LayersAccelerationForceEnabled() ||
PR_GetEnv("MOZ_USE_OMTC") ||
PR_GetEnv("MOZ_OMTC_ENABLED"); // yeah, these two env vars do the same thing.
// I'm told that one of them is enabled on some test slaves config.
// so be slightly careful if you think you can
// remove one of them.
result |= gfxPrefs::LayersAccelerationForceEnabled();
#if !defined(NIGHTLY_BUILD)
// Yeah, these two env vars do the same thing.
// I'm told that one of them is enabled on some test slaves config,
// so be slightly careful if you think you can remove one of them.
result &= PR_GetEnv("MOZ_USE_OMTC") || PR_GetEnv("MOZ_OMTC_ENABLED");
#endif
#endif
firstTime = false;
}

View File

@ -49,6 +49,7 @@ class WindowIdentifier;
extern PRLogModuleInfo *GetHalLog();
#define HAL_LOG(msg) PR_LOG(mozilla::hal::GetHalLog(), PR_LOG_DEBUG, msg)
#define HAL_ERR(msg) PR_LOG(mozilla::hal::GetHalLog(), PR_LOG_ERROR, msg)
typedef Observer<int64_t> SystemClockChangeObserver;
typedef Observer<SystemTimezoneChangeInformation> SystemTimezoneChangeObserver;

View File

@ -68,8 +68,8 @@
#include "UeventPoller.h"
#include "nsIWritablePropertyBag2.h"
#include <algorithm>
#include "PowerWakeLock.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#define NsecPerMsec 1000000LL
#define NsecPerSec 1000000000
@ -667,6 +667,7 @@ void
SetScreenEnabled(bool aEnabled)
{
GetGonkDisplay()->SetEnabled(aEnabled);
gPowerWakelock = nullptr;
sScreenEnabled = aEnabled;
}
@ -1397,15 +1398,15 @@ SetNiceForPid(int aPid, int aNice)
errno = 0;
int origProcPriority = getpriority(PRIO_PROCESS, aPid);
if (errno) {
LOG("Unable to get nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno);
HAL_LOG(("Unable to get nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno));
return;
}
int rv = setpriority(PRIO_PROCESS, aPid, aNice);
if (rv) {
LOG("Unable to set nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno);
HAL_LOG(("Unable to set nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno));
return;
}
@ -1419,7 +1420,7 @@ SetNiceForPid(int aPid, int aNice)
DIR* tasksDir = opendir(nsPrintfCString("/proc/%d/task/", aPid).get());
if (!tasksDir) {
LOG("Unable to open /proc/%d/task. SetNiceForPid bailing.", aPid);
HAL_LOG(("Unable to open /proc/%d/task. SetNiceForPid bailing.", aPid));
return;
}
@ -1452,9 +1453,9 @@ SetNiceForPid(int aPid, int aNice)
// Get and set the task's new priority.
int origtaskpriority = getpriority(PRIO_PROCESS, tid);
if (errno) {
LOG("Unable to get nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno);
HAL_LOG(("Unable to get nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno));
continue;
}
@ -1472,15 +1473,15 @@ SetNiceForPid(int aPid, int aNice)
rv = setpriority(PRIO_PROCESS, tid, newtaskpriority);
if (rv) {
LOG("Unable to set nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno);
HAL_LOG(("Unable to set nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno));
continue;
}
}
LOG("Changed nice for pid %d from %d to %d.",
aPid, origProcPriority, aNice);
HAL_LOG(("Changed nice for pid %d from %d to %d.",
aPid, origProcPriority, aNice));
closedir(tasksDir);
}
@ -1514,11 +1515,11 @@ SetProcessPriority(int aPid,
int clampedOomScoreAdj = clamped<int>(oomScoreAdj, OOM_SCORE_ADJ_MIN,
OOM_SCORE_ADJ_MAX);
if(clampedOomScoreAdj != oomScoreAdj) {
HAL_LOG(("Clamping OOM adjustment for pid %d to %d",
aPid, clampedOomScoreAdj));
HAL_LOG(("Clamping OOM adjustment for pid %d to %d", aPid,
clampedOomScoreAdj));
} else {
HAL_LOG(("Setting OOM adjustment for pid %d to %d",
aPid, clampedOomScoreAdj));
HAL_LOG(("Setting OOM adjustment for pid %d to %d", aPid,
clampedOomScoreAdj));
}
// We try the newer interface first, and fall back to the older interface
@ -1533,9 +1534,8 @@ SetProcessPriority(int aPid,
nsPrintfCString("%d", oomAdj).get());
}
} else {
LOG("Unable to read oom_score_adj pref for priority %s; "
"are the prefs messed up?",
ProcessPriorityToString(aPriority));
HAL_ERR(("Unable to read oom_score_adj pref for priority %s; "
"are the prefs messed up?", ProcessPriorityToString(aPriority)));
MOZ_ASSERT(false);
}
@ -1550,15 +1550,14 @@ SetProcessPriority(int aPid,
rv = Preferences::GetInt("hal.processPriorityManager.gonk.LowCPUNice",
&nice);
} else {
LOG("Unable to read niceness pref for priority %s; "
"are the prefs messed up?",
ProcessPriorityToString(aPriority));
HAL_ERR(("Unable to read niceness pref for priority %s; "
"are the prefs messed up?", ProcessPriorityToString(aPriority)));
MOZ_ASSERT(false);
rv = NS_ERROR_FAILURE;
}
if (NS_SUCCEEDED(rv)) {
LOG("Setting nice for pid %d to %d", aPid, nice);
HAL_LOG(("Setting nice for pid %d to %d", aPid, nice));
SetNiceForPid(aPid, nice);
}
}
@ -1576,13 +1575,13 @@ SetThreadNiceValue(pid_t aTid, ThreadPriority aThreadPriority, int aValue)
MOZ_ASSERT(aThreadPriority < NUM_THREAD_PRIORITY);
MOZ_ASSERT(aThreadPriority >= 0);
LOG("Setting thread %d to priority level %s; nice level %d",
aTid, ThreadPriorityToString(aThreadPriority), aValue);
HAL_LOG(("Setting thread %d to priority level %s; nice level %d",
aTid, ThreadPriorityToString(aThreadPriority), aValue));
int rv = setpriority(PRIO_PROCESS, aTid, aValue);
if (rv) {
LOG("Failed to set thread %d to priority level %s; error %s",
aTid, ThreadPriorityToString(aThreadPriority), strerror(errno));
HAL_LOG(("Failed to set thread %d to priority level %s; error %s", aTid,
ThreadPriorityToString(aThreadPriority), strerror(errno)));
}
}
@ -1598,15 +1597,16 @@ SetRealTimeThreadPriority(pid_t aTid,
MOZ_ASSERT(IsValidRealTimePriority(aValue, policy), "Invalid real time priority");
// Setting real time priorities requires using sched_setscheduler
LOG("Setting thread %d to priority level %s; Real Time priority %d, Schedule FIFO",
aTid, ThreadPriorityToString(aThreadPriority), aValue);
HAL_LOG(("Setting thread %d to priority level %s; Real Time priority %d, "
"Schedule FIFO", aTid, ThreadPriorityToString(aThreadPriority),
aValue));
sched_param schedParam;
schedParam.sched_priority = aValue;
int rv = sched_setscheduler(aTid, policy, &schedParam);
if (rv) {
LOG("Failed to set thread %d to real time priority level %s; error %s",
aTid, ThreadPriorityToString(aThreadPriority), strerror(errno));
HAL_LOG(("Failed to set thread %d to real time priority level %s; error %s",
aTid, ThreadPriorityToString(aThreadPriority), strerror(errno)));
}
}
@ -1624,7 +1624,8 @@ SetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority)
threadPriorityStr = ThreadPriorityToString(aThreadPriority);
break;
default:
LOG("Unrecognized thread priority %d; Doing nothing", aThreadPriority);
HAL_ERR(("Unrecognized thread priority %d; Doing nothing",
aThreadPriority));
return;
}
@ -1686,7 +1687,8 @@ SetCurrentThreadPriority(ThreadPriority aThreadPriority)
break;
}
default:
LOG("Unrecognized thread priority %d; Doing nothing", aThreadPriority);
HAL_LOG(("Unrecognized thread priority %d; Doing nothing",
aThreadPriority));
return;
}
}

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