mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team. a=merge
This commit is contained in:
commit
35cd2b1e5e
2
CLOBBER
2
CLOBBER
@ -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.
|
||||
|
@ -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 \
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
248
b2g/app/B2GLoader.cpp
Normal 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);
|
||||
}
|
@ -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',
|
||||
]
|
||||
|
@ -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;
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "3842156466e71f41748f86777a1b8fbd379441c0",
|
||||
"revision": "92b742f333b1f695de3de7c10316bc5ee652d084",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
@ -42,3 +42,5 @@ LOCAL_INCLUDES += [
|
||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
DEFINES['NOMINMAX'] = True
|
||||
|
@ -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
|
@ -131,6 +131,7 @@ AppleATDecoder::Drain()
|
||||
{
|
||||
LOG("Draining AudioToolbox AAC decoder");
|
||||
mTaskQueue->AwaitIdle();
|
||||
mCallback->DrainComplete();
|
||||
return Flush();
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -61,3 +61,6 @@ if CONFIG['MOZ_APPLEMEDIA']:
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
DEFINES['NOMINMAX'] = True
|
||||
|
@ -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
|
@ -27,3 +27,6 @@ SOURCES += [
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
DEFINES['NOMINMAX'] = True
|
||||
|
@ -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))) &&
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
]},
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
21
dom/events/crashtests/1035654-1.html
Normal file
21
dom/events/crashtests/1035654-1.html
Normal 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>
|
20
dom/events/crashtests/1035654-2.html
Normal file
20
dom/events/crashtests/1035654-2.html
Normal 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>
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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*.
|
||||
*
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
36
gfx/2d/2D.h
36
gfx/2d/2D.h
@ -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
504
gfx/2d/DrawCommand.h
Normal 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
39
gfx/2d/DrawTarget.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
197
gfx/2d/DrawTargetCapture.cpp
Normal file
197
gfx/2d/DrawTargetCapture.cpp
Normal 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
163
gfx/2d/DrawTargetCapture.h
Normal 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_ */
|
100
gfx/2d/Matrix.h
100
gfx/2d/Matrix.h
@ -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();
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
SurfaceFormat aFormat,
|
||||
bool aOwnData);
|
||||
|
||||
virtual void GuaranteePersistance();
|
||||
|
||||
private:
|
||||
uint8_t *mRawData;
|
||||
int32_t mStride;
|
||||
|
@ -97,7 +97,9 @@ UNIFIED_SOURCES += [
|
||||
'DataSourceSurface.cpp',
|
||||
'DataSurfaceHelpers.cpp',
|
||||
'DrawEventRecorder.cpp',
|
||||
'DrawTarget.cpp',
|
||||
'DrawTargetCairo.cpp',
|
||||
'DrawTargetCapture.cpp',
|
||||
'DrawTargetDual.cpp',
|
||||
'DrawTargetRecording.cpp',
|
||||
'DrawTargetTiled.cpp',
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "GLTypes.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsTArray.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "GLLibraryLoader.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "plstr.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
@ -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<
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 &&
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
||||
/* ===================================================================
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
|
||||
|
||||
class gfx3DMatrix;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
|
@ -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;
|
||||
|
@ -32,7 +32,7 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
union MaybeTransform {
|
||||
gfx3DMatrix;
|
||||
Matrix4x4;
|
||||
void_t;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#endif
|
||||
|
||||
class gfx3DMatrix;
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user