mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from rmottola/Arctic-Fox:
- Revert Bug 1125848 - Consolidate PCompositor's creation-destruction logic because of 10.7 MacOS bustage (ceda5a133) - adapt assertion to be as introduced in Bug 1125848 (877071282) - Bug 1160190 followup. Make ServiceWorker actually disabled on mulet so we can reopen the CLOSED TREE. r=bkelly (1a03ee7c2) - Bug 1123846 - Restrict some activities to be provided by the system app r=ferjm (c7ca76805) - fix header include order (01b1289df) - Bug 1151644 - Don't disallow the basic compositor backend. r=jrmuizel (b70633afd) - Bug 1155823 - Properly shutdown the CompositorVsyncDispatcher. r=kats (a3dee13e8) - add gfxCrashReporterUtils as of 1180688 2015-07-13 (433fa6bdb) - Bug 1029673 - Correctly report OMTC compositing in crash reports - r=Bas (87fc22936) - Bug 1180688 - Detect whether the widget will be able to present frames with BasicCompositor on Mac. r=mstange (842ed309f)
This commit is contained in:
@@ -1062,3 +1062,11 @@ pref("gfx.vsync.hw-vsync.enabled", false);
|
||||
pref("gfx.vsync.compositor", false);
|
||||
pref("gfx.touch.resample", false);
|
||||
#endif
|
||||
|
||||
// Comma separated list of activity names that can only be provided by
|
||||
// the system app in dev mode.
|
||||
pref("dom.activities.developer_mode_only", "import-app");
|
||||
|
||||
// mulet apparently loads firefox.js as well as b2g.js, so we have to explicitly
|
||||
// disable serviceworkers here to get them disabled in mulet.
|
||||
pref("dom.serviceWorkers.enabled", false);
|
||||
|
||||
@@ -355,6 +355,23 @@ let Activities = {
|
||||
calleeApp.appStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the activity is in the developer mode activity list, only let the
|
||||
// system app be a provider.
|
||||
let isSystemApp = false;
|
||||
let isDevModeActivity = false;
|
||||
try {
|
||||
isSystemApp =
|
||||
aResult.manifest == Services.prefs.getCharPref("b2g.system_manifest_url");
|
||||
isDevModeActivity =
|
||||
Services.prefs.getCharPref("dom.activities.developer_mode_only")
|
||||
.split(",").indexOf(aMsg.options.name) !== -1;
|
||||
} catch(e) {}
|
||||
|
||||
if (isDevModeActivity && !isSystemApp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ActivitiesServiceFilter.match(aMsg.options.data,
|
||||
aResult.description.filters);
|
||||
};
|
||||
|
||||
@@ -69,6 +69,22 @@ ActivityProxy.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the activities that are restricted to be used in dev mode.
|
||||
let devMode = false;
|
||||
let isDevModeActivity = false;
|
||||
try {
|
||||
devMode = Services.prefs.getBoolPref("dom.apps.developer_mode");
|
||||
isDevModeActivity =
|
||||
Services.prefs.getCharPref("dom.activities.developer_mode_only")
|
||||
.split(",").indexOf(aOptions.name) !== -1;
|
||||
|
||||
} catch(e) {}
|
||||
if (isDevModeActivity && !devMode) {
|
||||
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
|
||||
Services.obs.notifyObservers(null, "Activity:Error", null);
|
||||
return;
|
||||
}
|
||||
|
||||
cpmm.addMessageListener("Activity:FireSuccess", this);
|
||||
cpmm.addMessageListener("Activity:FireError", this);
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ DIRS += ['interfaces']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/mochi/mochitest.ini']
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'Activity.h',
|
||||
]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Random app",
|
||||
"activities": {
|
||||
"import-app": { "blob": { "required": true } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Content-Type: application/manifest+json
|
||||
@@ -0,0 +1,9 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
support-files =
|
||||
system.webapp
|
||||
system.webapp^headers^
|
||||
manifest.webapp
|
||||
manifest.webapp^headers^
|
||||
|
||||
[test_dev_mode_activity.html]
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "System app",
|
||||
"activities": {
|
||||
"import-app": { "blob": { "required": true } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Content-Type: application/manifest+json
|
||||
@@ -0,0 +1,290 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id={1123846}
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug {1123846}</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1123846}">Mozilla Bug {1123846}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
|
||||
/**
|
||||
* Tests the developer mode activities that can only be provided by the
|
||||
* system app.
|
||||
*
|
||||
* We test the following:
|
||||
* 1) No dev mode, no system app installed (failure).
|
||||
* 2) No dev mode, system app installed (failure).
|
||||
* 3) No dev mode, system app and other app installed (failure).
|
||||
* 4) Dev mode, system app and other app installed (success, only system app returned).
|
||||
*/
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
var gRootUrl = "http://test/chrome/dom/activities/tests/mochi/";
|
||||
var gGenerator = runTest();
|
||||
|
||||
function go() {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document },
|
||||
{ "type": "browser", "allow": 1, "context": document },
|
||||
{ "type": "embed-apps", "allow": 1, "context": document }],
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.sysmsg.enabled", true],
|
||||
["dom.apps.developer_mode", false],
|
||||
["dom.activities.developer_mode_only", "import-app"]]},
|
||||
continueTest) });
|
||||
}
|
||||
|
||||
function cbError(aEvent) {
|
||||
ok(false, "Error callback invoked " +
|
||||
aEvent.target.error.name + " " + aEvent.target.error.message);
|
||||
finish();
|
||||
}
|
||||
|
||||
function unexpectedSuccess(aMsg) {
|
||||
return function() {
|
||||
ok(false, "Should not have succeeded: " + aMsg);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var systemAppUrl = gRootUrl + "system.webapp";
|
||||
var otherAppUrl = gRootUrl + "manifest.webapp";
|
||||
|
||||
function installApp(aUrl) {
|
||||
var request = navigator.mozApps.install(aUrl, { });
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
return request;
|
||||
}
|
||||
|
||||
function installSystemApp() {
|
||||
return installApp(systemAppUrl);
|
||||
}
|
||||
|
||||
function installOtherApp() {
|
||||
return installApp(otherAppUrl);
|
||||
}
|
||||
|
||||
function uninstall(aApp) {
|
||||
info("Uninstalling " + (aApp ? aApp.manifestURL : "NO APP!!"));
|
||||
var request = navigator.mozApps.mgmt.uninstall(aApp);
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
}
|
||||
|
||||
function registerComponent(aObject, aDescription, aContract) {
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
info("Registering " + cid);
|
||||
|
||||
var componentManager =
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, aDescription, aContract, aObject);
|
||||
|
||||
// Keep the id on the object so we can unregister later.
|
||||
aObject.cid = cid;
|
||||
}
|
||||
|
||||
function unregisterComponent(aObject) {
|
||||
info("Unregistering " + aObject.cid);
|
||||
var componentManager =
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aObject.cid, aObject);
|
||||
}
|
||||
|
||||
var ActivityGlue = {
|
||||
// nsISupports implementation.
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIActivityUIGlue)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation.
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIActivityUIGlue implementation.
|
||||
chooseActivity: function(aOptions, aActivities, aCallback) {
|
||||
aCallback.handleEvent(Ci.nsIActivityUIGlueCallback.WEBAPPS_ACTIVITY,
|
||||
aActivities.length == 1 ? 0 : -1);
|
||||
}
|
||||
};
|
||||
|
||||
var SystemMessageGlue = {
|
||||
// nsISupports implementation.
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsISystemMessageGlue)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation.
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsISystemMessageGlue implementation.
|
||||
openApp(pageURL, manifestURL, type, target, showApp, onlyShowApp, extra) {
|
||||
// We should only try to open a page in the sytem app.
|
||||
is(manifestURL, systemAppUrl, "Opening a page in the system app.");
|
||||
}
|
||||
};
|
||||
|
||||
registerComponent(ActivityGlue,
|
||||
"Activity Glue",
|
||||
"@mozilla.org/dom/activities/ui-glue;1");
|
||||
|
||||
registerComponent(SystemMessageGlue,
|
||||
"System Message Glue",
|
||||
"@mozilla.org/dom/messages/system-message-glue;1");
|
||||
|
||||
function finish() {
|
||||
unregisterComponent(ActivityGlue);
|
||||
unregisterComponent(SystemMessageGlue);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
gGenerator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exporting and importing hosted and packaged apps.
|
||||
*/
|
||||
function runTest() {
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
// Check how many apps we are starting with.
|
||||
var request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
var initialAppsCount = request.result.length;
|
||||
info("Starting with " + initialAppsCount + " apps installed.");
|
||||
|
||||
// 1) No dev mode, no system app installed (failure).
|
||||
var activity = new MozActivity({ name: "import-app" });
|
||||
activity.onerror = function() {
|
||||
ok(true, "1) No dev mode, no system app installed");
|
||||
continueTest();
|
||||
}
|
||||
activity.onsuccess = unexpectedSuccess("1) No dev mode, no system app installed");
|
||||
yield undefined;
|
||||
|
||||
|
||||
// 2) No dev mode, system app installed (failure).
|
||||
// Configure the system app manifest url.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["b2g.system_manifest_url", systemAppUrl]]},
|
||||
continueTest);
|
||||
yield undefined;
|
||||
|
||||
// Install the system app.
|
||||
request = installSystemApp();
|
||||
yield undefined;
|
||||
var systemApp = request.result;
|
||||
ok(systemApp, "systemApp is non-null");
|
||||
|
||||
activity = new MozActivity({ name: "import-app" });
|
||||
activity.onerror = function() {
|
||||
ok(true, "2) No dev mode, system app installed");
|
||||
continueTest();
|
||||
}
|
||||
activity.onsuccess = unexpectedSuccess("2) No dev mode, system app installed");
|
||||
yield undefined;
|
||||
|
||||
// 3) No dev mode, system app and other app installed (failure).
|
||||
request = installOtherApp();
|
||||
yield undefined;
|
||||
var otherApp = request.result;
|
||||
ok(otherApp, "otherApp is non-null");
|
||||
|
||||
activity = new MozActivity({ name: "import-app" });
|
||||
activity.onerror = function() {
|
||||
ok(true, "3) No dev mode, system app and other app installed");
|
||||
continueTest();
|
||||
}
|
||||
activity.onsuccess = unexpectedSuccess("3) No dev mode, system app and other app installed");
|
||||
yield undefined;
|
||||
|
||||
// 4) Dev mode, no system app installed.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["dom.apps.developer_mode", true]]},
|
||||
continueTest);
|
||||
yield undefined;
|
||||
|
||||
activity = new MozActivity({ name: "import-app" });
|
||||
activity.onsuccess = function() {
|
||||
ok(true, "4) Dev mode, system app and other app installed");
|
||||
continueTest();
|
||||
}
|
||||
activity.onerror = function(aError) {
|
||||
ok(false, "Got error: " + aError.name);
|
||||
finish();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
// Cleanup
|
||||
uninstall(systemApp);
|
||||
yield undefined;
|
||||
|
||||
uninstall(otherApp);
|
||||
yield undefined;
|
||||
|
||||
// Check that we restored the app registry.
|
||||
request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
|
||||
is(request.result.length, initialAppsCount, "All apps are uninstalled.");
|
||||
}
|
||||
|
||||
addLoadEvent(go);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -82,6 +82,12 @@ BasicCompositor::~BasicCompositor()
|
||||
MOZ_COUNT_DTOR(BasicCompositor);
|
||||
}
|
||||
|
||||
bool
|
||||
BasicCompositor::Initialize()
|
||||
{
|
||||
return mWidget ? mWidget->InitCompositor(this) : false;
|
||||
};
|
||||
|
||||
int32_t
|
||||
BasicCompositor::GetMaxTextureSize() const
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ protected:
|
||||
virtual ~BasicCompositor();
|
||||
|
||||
public:
|
||||
virtual bool Initialize() override { return true; };
|
||||
virtual bool Initialize() override;
|
||||
|
||||
virtual void Destroy() override;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mozilla/layers/Effects.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include "gfxVR.h"
|
||||
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
@@ -130,6 +131,8 @@ CompositorD3D11::Initialize()
|
||||
{
|
||||
bool force = gfxPrefs::LayersAccelerationForceEnabled();
|
||||
|
||||
ScopedGfxFeatureReporter reporter("D3D11 Layers", force);
|
||||
|
||||
if (!gfxPlatform::CanUseDirect3D11()) {
|
||||
NS_WARNING("Direct3D 11-accelerated layers are not supported on this system.");
|
||||
return false;
|
||||
@@ -381,6 +384,11 @@ CompositorD3D11::Initialize()
|
||||
DXGI_MWA_NO_WINDOW_CHANGES);
|
||||
}
|
||||
|
||||
if (!mWidget->InitCompositor(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
reporter.SetSuccessful();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mozilla/layers/PCompositorParent.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@@ -41,6 +42,8 @@ CompositorD3D9::Initialize()
|
||||
{
|
||||
bool force = gfxPrefs::LayersAccelerationForceEnabled();
|
||||
|
||||
ScopedGfxFeatureReporter reporter("D3D9 Layers", force);
|
||||
|
||||
if (!gfxPlatform::CanUseDirect3D9()) {
|
||||
NS_WARNING("Direct3D 9-accelerated layers are not supported on this system.");
|
||||
return false;
|
||||
@@ -58,6 +61,11 @@ CompositorD3D9::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mWidget->InitCompositor(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
reporter.SetSuccessful();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/layers/CompositorChild.h"
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
#include <stddef.h> // for size_t
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
@@ -40,58 +39,19 @@ Atomic<int32_t> CompositableForwarder::sSerialCounter(0);
|
||||
|
||||
CompositorChild::CompositorChild(ClientLayerManager *aLayerManager)
|
||||
: mLayerManager(aLayerManager)
|
||||
, mCanSend(false)
|
||||
, mCanSend(true)
|
||||
{
|
||||
}
|
||||
|
||||
CompositorChild::~CompositorChild()
|
||||
{
|
||||
if (mCanSend) {
|
||||
gfxCriticalError() << "CompositorChild was not deinitialized";
|
||||
}
|
||||
}
|
||||
|
||||
static void DeferredDestroyCompositor(nsRefPtr<CompositorParent> aCompositorParent,
|
||||
nsRefPtr<CompositorChild> aCompositorChild)
|
||||
{
|
||||
// Bug 848949 needs to be fixed before
|
||||
// we can close the channel properly
|
||||
//aCompositorChild->Close();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorChild::Destroy()
|
||||
{
|
||||
// This must not be called from the destructor!
|
||||
MOZ_ASSERT(mRefCnt != 0);
|
||||
|
||||
if (!mCanSend) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanSend = false;
|
||||
|
||||
// Destroying the layer manager may cause all sorts of things to happen, so
|
||||
// let's make sure there is still a reference to keep this alive whatever
|
||||
// happens.
|
||||
nsRefPtr<CompositorChild> selfRef = this;
|
||||
|
||||
SendWillStop();
|
||||
// The call just made to SendWillStop can result in IPC from the
|
||||
// CompositorParent to the CompositorChild (e.g. caused by the destruction
|
||||
// of shared memory). We need to ensure this gets processed by the
|
||||
// CompositorChild before it gets destroyed. It suffices to ensure that
|
||||
// events already in the MessageLoop get processed before the
|
||||
// CompositorChild is destroyed, so we add a task to the MessageLoop to
|
||||
// handle compositor desctruction.
|
||||
|
||||
// From now on the only message we can send is Stop.
|
||||
|
||||
if (mLayerManager) {
|
||||
mLayerManager->Destroy();
|
||||
mLayerManager = nullptr;
|
||||
}
|
||||
|
||||
mLayerManager->Destroy();
|
||||
mLayerManager = nullptr;
|
||||
// start from the end of the array because Destroy() can cause the
|
||||
// LayerTransactionChild to be removed from the array.
|
||||
for (int i = ManagedPLayerTransactionChild().Length() - 1; i >= 0; --i) {
|
||||
@@ -99,13 +59,8 @@ CompositorChild::Destroy()
|
||||
static_cast<LayerTransactionChild*>(ManagedPLayerTransactionChild()[i]);
|
||||
layers->Destroy();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mCanSend);
|
||||
SendStop();
|
||||
|
||||
// The DeferredDestroyCompositor task takes ownership of compositorParent and
|
||||
// will release them when it runs.
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(DeferredDestroyCompositor, mCompositorParent, selfRef));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -132,8 +87,6 @@ CompositorChild::Create(Transport* aTransport, ProcessId aOtherPid)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
child->mCanSend = true;
|
||||
|
||||
// We release this ref in ActorDestroy().
|
||||
sCompositor = child.forget().take();
|
||||
|
||||
@@ -146,18 +99,6 @@ CompositorChild::Create(Transport* aTransport, ProcessId aOtherPid)
|
||||
return sCompositor;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorChild::OpenSameProcess(CompositorParent* aParent)
|
||||
{
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
mCompositorParent = aParent;
|
||||
mCanSend = Open(mCompositorParent->GetIPCChannel(),
|
||||
CompositorParent::CompositorLoop(),
|
||||
ipc::ChildSide);
|
||||
return mCanSend;
|
||||
}
|
||||
|
||||
/*static*/ CompositorChild*
|
||||
CompositorChild::Get()
|
||||
{
|
||||
@@ -388,7 +329,14 @@ CompositorChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at CompositorChild");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sCompositor) {
|
||||
sCompositor->Release();
|
||||
sCompositor = nullptr;
|
||||
}
|
||||
// We don't want to release the ref to sCompositor here, during
|
||||
// cleanup, because that will cause it to be deleted while it's
|
||||
// still being used. So defer the deletion to after it's not in
|
||||
// use.
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &CompositorChild::Release));
|
||||
@@ -527,6 +475,9 @@ CompositorChild::CancelNotifyAfterRemotePaint(TabChild* aTabChild)
|
||||
bool
|
||||
CompositorChild::SendWillStop()
|
||||
{
|
||||
MOZ_ASSERT(mCanSend);
|
||||
// From now on the only two messages we can send are WillStop and Stop.
|
||||
mCanSend = false;
|
||||
return PCompositorChild::SendWillStop();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,12 +60,6 @@ public:
|
||||
static PCompositorChild*
|
||||
Create(Transport* aTransport, ProcessId aOtherProcess);
|
||||
|
||||
/**
|
||||
* Initialize the CompositorChild and open the connection in the non-multi-process
|
||||
* case.
|
||||
*/
|
||||
bool OpenSameProcess(CompositorParent* aParent);
|
||||
|
||||
static CompositorChild* Get();
|
||||
|
||||
static bool ChildProcessHasCompositor() { return sCompositor != nullptr; }
|
||||
@@ -174,9 +168,6 @@ private:
|
||||
void* aLayerTransactionChild);
|
||||
|
||||
nsRefPtr<ClientLayerManager> mLayerManager;
|
||||
// When not multi-process, hold a reference to the CompositorParent to keep it
|
||||
// alive. This reference should be null in multi-process.
|
||||
nsRefPtr<CompositorParent> mCompositorParent;
|
||||
|
||||
// The ViewID of the FrameMetrics is used as the key for this hash table.
|
||||
// While this should be safe to use since the ViewID is unique
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Layers.h" // for WriteSnapshotToDumpFile
|
||||
#include "LayerScope.h" // for LayerScope
|
||||
#include "gfx2DGlue.h" // for ThebesFilter
|
||||
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
|
||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
@@ -208,6 +209,8 @@ CompositorOGL::Initialize()
|
||||
{
|
||||
bool force = gfxPrefs::LayersAccelerationForceEnabled();
|
||||
|
||||
ScopedGfxFeatureReporter reporter("GL Layers", force);
|
||||
|
||||
// Do not allow double initialization
|
||||
MOZ_ASSERT(mGLContext == nullptr, "Don't reinitialize CompositorOGL");
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
#define MOZ_GFXFEATUREREPORTER 1
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GFXFEATUREREPORTER
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include <string.h> // for strcmp
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
|
||||
#include "mozilla/Services.h" // for GetObserverService
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsCOMPtr.h" // for nsCOMPtr
|
||||
#include "nsError.h" // for NS_OK, NS_FAILED, nsresult
|
||||
#include "nsExceptionHandler.h" // for AppendAppNotesToCrashReport
|
||||
#include "nsID.h"
|
||||
#include "nsIEventTarget.h" // for NS_DISPATCH_NORMAL
|
||||
#include "nsIObserver.h" // for nsIObserver, etc
|
||||
#include "nsIObserverService.h" // for nsIObserverService
|
||||
#include "nsIRunnable.h" // for nsIRunnable
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h" // for nsAutoCString, nsCString, etc
|
||||
#include "nsTArray.h" // for nsTArray
|
||||
#include "nsThreadUtils.h" // for NS_DispatchToMainThread, etc
|
||||
#include "nscore.h" // for NS_IMETHOD, NS_IMETHODIMP, etc
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static nsTArray<nsCString> *gFeaturesAlreadyReported = nullptr;
|
||||
static StaticMutex gFeaturesAlreadyReportedMutex;
|
||||
|
||||
class ObserverToDestroyFeaturesAlreadyReported final : public nsIObserver
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
ObserverToDestroyFeaturesAlreadyReported() {}
|
||||
private:
|
||||
virtual ~ObserverToDestroyFeaturesAlreadyReported() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(ObserverToDestroyFeaturesAlreadyReported,
|
||||
nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ObserverToDestroyFeaturesAlreadyReported::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "xpcom-shutdown")) {
|
||||
StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex);
|
||||
if (gFeaturesAlreadyReported) {
|
||||
delete gFeaturesAlreadyReported;
|
||||
gFeaturesAlreadyReported = nullptr;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class RegisterObserverRunnable : public nsRunnable {
|
||||
public:
|
||||
NS_IMETHOD Run() override {
|
||||
// LeakLog made me do this. Basically, I just wanted gFeaturesAlreadyReported to be a static nsTArray<nsCString>,
|
||||
// and LeakLog was complaining about leaks like this:
|
||||
// leaked 1 instance of nsTArray_base with size 8 bytes
|
||||
// leaked 7 instances of nsStringBuffer with size 8 bytes each (56 bytes total)
|
||||
// So this is a work-around using a pointer, and using a nsIObserver to deallocate on xpcom shutdown.
|
||||
// Yay for fighting bloat.
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (!observerService)
|
||||
return NS_OK;
|
||||
nsRefPtr<ObserverToDestroyFeaturesAlreadyReported> observer = new ObserverToDestroyFeaturesAlreadyReported;
|
||||
observerService->AddObserver(observer, "xpcom-shutdown", false);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ScopedGfxFeatureReporter::WriteAppNote(char statusChar)
|
||||
{
|
||||
StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex);
|
||||
|
||||
if (!gFeaturesAlreadyReported) {
|
||||
gFeaturesAlreadyReported = new nsTArray<nsCString>;
|
||||
nsCOMPtr<nsIRunnable> r = new RegisterObserverRunnable();
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
nsAutoCString featureString;
|
||||
featureString.AppendPrintf("%s%c ",
|
||||
mFeature,
|
||||
mStatusChar);
|
||||
|
||||
if (!gFeaturesAlreadyReported->Contains(featureString)) {
|
||||
gFeaturesAlreadyReported->AppendElement(featureString);
|
||||
CrashReporter::AppendAppNotesToCrashReport(featureString);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#else
|
||||
|
||||
namespace mozilla {
|
||||
void ScopedGfxFeatureReporter::WriteAppNote(char) {}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/* -*- 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 gfxCrashReporterUtils_h__
|
||||
#define gfxCrashReporterUtils_h__
|
||||
|
||||
#include "gfxCore.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/** \class ScopedGfxFeatureReporter
|
||||
*
|
||||
* On creation, adds "FeatureName?" to AppNotes
|
||||
* On destruction, adds "FeatureName-", or "FeatureName+" if you called SetSuccessful().
|
||||
*
|
||||
* Any such string is added at most once to AppNotes, and is subsequently skipped.
|
||||
*
|
||||
* This ScopedGfxFeatureReporter class is designed to be fool-proof to use in functions that
|
||||
* have many exit points. We don't want to encourage having function with many exit points.
|
||||
* It just happens that our graphics features initialization functions are like that.
|
||||
*/
|
||||
class NS_GFX ScopedGfxFeatureReporter
|
||||
{
|
||||
public:
|
||||
explicit ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
|
||||
: mFeature(aFeature), mStatusChar('-')
|
||||
{
|
||||
WriteAppNote(force ? '!' : '?');
|
||||
}
|
||||
~ScopedGfxFeatureReporter() {
|
||||
WriteAppNote(mStatusChar);
|
||||
}
|
||||
void SetSuccessful() { mStatusChar = '+'; }
|
||||
|
||||
class AppNoteWritingRunnable;
|
||||
|
||||
protected:
|
||||
const char *mFeature;
|
||||
char mStatusChar;
|
||||
|
||||
private:
|
||||
void WriteAppNote(char statusChar);
|
||||
};
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#endif // gfxCrashReporterUtils_h__
|
||||
@@ -14,6 +14,7 @@ XPIDL_MODULE = 'gfx'
|
||||
EXPORTS += [
|
||||
'FilterSupport.h',
|
||||
'gfxCore.h',
|
||||
'gfxCrashReporterUtils.h',
|
||||
'nsBoundingMetrics.h',
|
||||
'nsColor.h',
|
||||
'nsColorNameList.h',
|
||||
@@ -46,6 +47,7 @@ if CONFIG['MOZ_X11']:
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'FilterSupport.cpp',
|
||||
'gfxCrashReporterUtils.cpp',
|
||||
'nsColor.cpp',
|
||||
'nsFont.cpp',
|
||||
'nsFontMetrics.cpp',
|
||||
|
||||
@@ -131,8 +131,8 @@ using namespace mozilla::system;
|
||||
#include "nsDocument.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "CameraPreferences.h"
|
||||
#include "MediaDecoder.h"
|
||||
#include "TouchManager.h"
|
||||
#include "MediaDecoder.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
||||
@@ -529,6 +529,7 @@ public:
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawing() override;
|
||||
void EndRemoteDrawing() override;
|
||||
void CleanupRemoteDrawing() override;
|
||||
bool InitCompositor(mozilla::layers::Compositor* aCompositor) override;
|
||||
|
||||
APZCTreeManager* APZCTM() { return mAPZC ; }
|
||||
|
||||
|
||||
@@ -2493,6 +2493,8 @@ nsChildView::EnsureVibrancyManager()
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
nsChildView::StartRemoteDrawing()
|
||||
{
|
||||
// should have created the GLPresenter in InitCompositor.
|
||||
MOZ_ASSERT(mGLPresenter);
|
||||
if (!mGLPresenter) {
|
||||
mGLPresenter = GLPresenter::CreateForWindow(this);
|
||||
|
||||
@@ -2537,6 +2539,19 @@ nsChildView::CleanupRemoteDrawing()
|
||||
mGLPresenter = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsChildView::InitCompositor(Compositor* aCompositor)
|
||||
{
|
||||
if (aCompositor->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
if (!mGLPresenter) {
|
||||
mGLPresenter = GLPresenter::CreateForWindow(this);
|
||||
}
|
||||
|
||||
return !!mGLPresenter;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::DoRemoteComposition(const nsIntRect& aRenderRect)
|
||||
{
|
||||
|
||||
+61
-47
@@ -181,24 +181,45 @@ nsBaseWidget::Shutdown()
|
||||
mShutdownObserver = nullptr;
|
||||
}
|
||||
|
||||
static void DeferredDestroyCompositor(nsRefPtr<CompositorParent> aCompositorParent,
|
||||
nsRefPtr<CompositorChild> aCompositorChild)
|
||||
{
|
||||
// Bug 848949 needs to be fixed before
|
||||
// we can close the channel properly
|
||||
//aCompositorChild->Close();
|
||||
}
|
||||
|
||||
void nsBaseWidget::DestroyCompositor()
|
||||
{
|
||||
if (mCompositorChild) {
|
||||
// XXX CompositorChild and CompositorParent might be re-created in
|
||||
// ClientLayerManager destructor. See bug 1133426.
|
||||
nsRefPtr<CompositorChild> compositorChild = mCompositorChild;
|
||||
nsRefPtr<CompositorParent> compositorParent = mCompositorParent;
|
||||
mCompositorChild->Destroy();
|
||||
}
|
||||
}
|
||||
nsRefPtr<CompositorChild> compositorChild = mCompositorChild.forget();
|
||||
nsRefPtr<CompositorParent> compositorParent = mCompositorParent.forget();
|
||||
|
||||
void nsBaseWidget::DestroyLayerManager()
|
||||
{
|
||||
if (mLayerManager) {
|
||||
mLayerManager->Destroy();
|
||||
mLayerManager = nullptr;
|
||||
compositorChild->SendWillStop();
|
||||
// New LayerManager, CompositorParent and CompositorChild might be created
|
||||
// as a result of internal GetLayerManager() call.
|
||||
compositorChild->Destroy();
|
||||
|
||||
// The call just made to SendWillStop can result in IPC from the
|
||||
// CompositorParent to the CompositorChild (e.g. caused by the destruction
|
||||
// of shared memory). We need to ensure this gets processed by the
|
||||
// CompositorChild before it gets destroyed. It suffices to ensure that
|
||||
// events already in the MessageLoop get processed before the
|
||||
// CompositorChild is destroyed, so we add a task to the MessageLoop to
|
||||
// handle compositor desctruction.
|
||||
|
||||
// The DefferedDestroyCompositor task takes ownership of compositorParent and
|
||||
// will release them when it runs.
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(DeferredDestroyCompositor, compositorParent,
|
||||
compositorChild));
|
||||
}
|
||||
|
||||
// Can have base widgets that are things like tooltips
|
||||
// which don't have CompositorVsyncDispatchers
|
||||
if (mCompositorVsyncDispatcher) {
|
||||
mCompositorVsyncDispatcher->Shutdown();
|
||||
}
|
||||
DestroyCompositor();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -213,6 +234,11 @@ nsBaseWidget::~nsBaseWidget()
|
||||
static_cast<BasicLayerManager*>(mLayerManager.get())->ClearRetainerWidget();
|
||||
}
|
||||
|
||||
if (mLayerManager) {
|
||||
mLayerManager->Destroy();
|
||||
mLayerManager = nullptr;
|
||||
}
|
||||
|
||||
if (mShutdownObserver) {
|
||||
// If the shutdown observer is currently processing observers,
|
||||
// then UnregisterShutdownObserver won't stop our Observer
|
||||
@@ -222,7 +248,7 @@ nsBaseWidget::~nsBaseWidget()
|
||||
nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
|
||||
}
|
||||
|
||||
DestroyLayerManager();
|
||||
DestroyCompositor();
|
||||
|
||||
#ifdef NOISY_WIDGET_LEAKS
|
||||
gNumWidgets--;
|
||||
@@ -230,11 +256,6 @@ nsBaseWidget::~nsBaseWidget()
|
||||
#endif
|
||||
|
||||
delete mOriginalBounds;
|
||||
|
||||
// Can have base widgets that are things like tooltips which don't have CompositorVsyncDispatchers
|
||||
if (mCompositorVsyncDispatcher) {
|
||||
mCompositorVsyncDispatcher->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -1061,12 +1082,8 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
MOZ_ASSERT(gfxPlatform::UsesOffMainThreadCompositing(),
|
||||
"This function assumes OMTC");
|
||||
|
||||
MOZ_ASSERT(!mCompositorParent && !mCompositorChild,
|
||||
"Should have properly cleaned up the previous PCompositor pair beforehand");
|
||||
|
||||
if (mCompositorChild) {
|
||||
mCompositorChild->Destroy();
|
||||
}
|
||||
MOZ_ASSERT(!mCompositorParent,
|
||||
"Should have properly cleaned up the previous CompositorParent beforehand");
|
||||
|
||||
// Recreating this is tricky, as we may still have an old and we need
|
||||
// to make sure it's properly destroyed by calling DestroyCompositor!
|
||||
@@ -1079,9 +1096,11 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
|
||||
CreateCompositorVsyncDispatcher();
|
||||
mCompositorParent = NewCompositorParent(aWidth, aHeight);
|
||||
MessageChannel *parentChannel = mCompositorParent->GetIPCChannel();
|
||||
nsRefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
|
||||
MessageLoop *childMessageLoop = CompositorParent::CompositorLoop();
|
||||
mCompositorChild = new CompositorChild(lm);
|
||||
mCompositorChild->OpenSameProcess(mCompositorParent);
|
||||
mCompositorChild->Open(parentChannel, childMessageLoop, ipc::ChildSide);
|
||||
|
||||
// Make sure the parent knows it is same process.
|
||||
mCompositorParent->SetOtherProcessId(kCurrentProcessId);
|
||||
@@ -1096,37 +1115,32 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
nsTArray<LayersBackend> backendHints;
|
||||
GetPreferredCompositorBackends(backendHints);
|
||||
|
||||
#if !defined(MOZ_X11) && !defined(XP_WIN)
|
||||
if (!mRequireOffMainThreadCompositing &&
|
||||
!Preferences::GetBool("layers.offmainthreadcomposition.force-basic", false)) {
|
||||
for (size_t i = 0; i < backendHints.Length(); ++i) {
|
||||
if (backendHints[i] == LayersBackend::LAYERS_BASIC) {
|
||||
backendHints[i] = LayersBackend::LAYERS_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
if (!backendHints.IsEmpty()) {
|
||||
shadowManager = mCompositorChild->SendPLayerTransactionConstructor(
|
||||
backendHints, 0, &textureFactoryIdentifier, &success);
|
||||
}
|
||||
|
||||
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
|
||||
if (success) {
|
||||
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
|
||||
if (!lf) {
|
||||
lm = nullptr;
|
||||
mCompositorChild = nullptr;
|
||||
return;
|
||||
}
|
||||
lf->SetShadowManager(shadowManager);
|
||||
lf->IdentifyTextureHost(textureFactoryIdentifier);
|
||||
ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
|
||||
WindowUsesOMTC();
|
||||
|
||||
if (!success || !lf) {
|
||||
NS_WARNING("Failed to create an OMT compositor.");
|
||||
DestroyCompositor();
|
||||
mLayerManager = lm.forget();
|
||||
return;
|
||||
}
|
||||
|
||||
lf->SetShadowManager(shadowManager);
|
||||
lf->IdentifyTextureHost(textureFactoryIdentifier);
|
||||
ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
|
||||
WindowUsesOMTC();
|
||||
|
||||
mLayerManager = lm.forget();
|
||||
NS_WARNING("Failed to create an OMT compositor.");
|
||||
DestroyCompositor();
|
||||
// Compositor child had the only reference to LayerManager and will have
|
||||
// deallocated it when being freed.
|
||||
}
|
||||
|
||||
bool nsBaseWidget::ShouldUseOffMainThreadCompositing()
|
||||
|
||||
@@ -441,7 +441,6 @@ protected:
|
||||
* reached (This is the case with gtk2 for instance).
|
||||
*/
|
||||
void DestroyCompositor();
|
||||
void DestroyLayerManager();
|
||||
|
||||
nsIWidgetListener* mWidgetListener;
|
||||
nsIWidgetListener* mAttachedWidgetListener;
|
||||
|
||||
@@ -46,6 +46,7 @@ class PluginWidgetChild;
|
||||
}
|
||||
namespace layers {
|
||||
class Composer2D;
|
||||
class Compositor;
|
||||
class CompositorChild;
|
||||
class LayerManager;
|
||||
class LayerManagerComposite;
|
||||
@@ -1861,6 +1862,16 @@ class nsIWidget : public nsISupports {
|
||||
uint32_t aNativeMessage,
|
||||
uint32_t aModifierFlags) = 0;
|
||||
|
||||
/**
|
||||
* A hook for the widget to prepare a Compositor, during the latter's initialization.
|
||||
*
|
||||
* If this method returns true, it means that the widget will be able to
|
||||
* present frames from the compoositor.
|
||||
* Returning false will cause the compositor's initialization to fail, and
|
||||
* a different compositor backend will be used (if any).
|
||||
*/
|
||||
virtual bool InitCompositor(mozilla::layers::Compositor*) { return true; }
|
||||
|
||||
/**
|
||||
* A shortcut to SynthesizeNativeMouseEvent, abstracting away the native message.
|
||||
* aPoint is location in device pixels to which the mouse pointer moves to.
|
||||
|
||||
@@ -674,7 +674,11 @@ NS_METHOD nsWindow::Destroy()
|
||||
* On windows the LayerManagerOGL destructor wants the widget to be around for
|
||||
* cleanup. It also would like to have the HWND intact, so we nullptr it here.
|
||||
*/
|
||||
DestroyLayerManager();
|
||||
if (mLayerManager) {
|
||||
mLayerManager->Destroy();
|
||||
}
|
||||
mLayerManager = nullptr;
|
||||
DestroyCompositor();
|
||||
|
||||
/* We should clear our cached resources now and not wait for the GC to
|
||||
* delete the nsWindow. */
|
||||
@@ -3325,13 +3329,10 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
}
|
||||
|
||||
if (!mLayerManager) {
|
||||
MOZ_ASSERT(!mCompositorParent && !mCompositorChild);
|
||||
mLayerManager = CreateBasicLayerManager();
|
||||
}
|
||||
|
||||
// If we don't have a layer manager at this point we shouldn't have a
|
||||
// PCompositor actor pair either.
|
||||
MOZ_ASSERT(mLayerManager || (!mCompositorParent && !mCompositorChild));
|
||||
|
||||
NS_ASSERTION(mLayerManager, "Couldn't provide a valid layer manager.");
|
||||
|
||||
return mLayerManager;
|
||||
@@ -6597,7 +6598,10 @@ nsWindow::IsPopup()
|
||||
void
|
||||
nsWindow::ClearCompositor(nsWindow* aWindow)
|
||||
{
|
||||
aWindow->DestroyLayerManager();
|
||||
if (aWindow->mLayerManager) {
|
||||
aWindow->mLayerManager = nullptr;
|
||||
aWindow->DestroyCompositor();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user