2017-10-28 02:10:06 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2016-11-10 21:05:06 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
#include "mozilla/layers/ContentCompositorBridgeParent.h"
|
2018-03-06 18:25:39 +03:00
|
|
|
|
2016-11-10 21:05:06 +03:00
|
|
|
#include <stdint.h> // for uint64_t
|
2018-03-06 18:25:39 +03:00
|
|
|
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "LayerTransactionParent.h" // for LayerTransactionParent
|
2018-03-06 18:25:39 +03:00
|
|
|
#include "apz/src/APZCTreeManager.h" // for APZCTreeManager
|
2018-12-02 17:02:27 +03:00
|
|
|
#include "gfxUtils.h"
|
2017-07-19 06:09:00 +03:00
|
|
|
#ifdef XP_WIN
|
2017-11-13 12:54:18 +03:00
|
|
|
# include "mozilla/gfx/DeviceManagerDx.h" // for DeviceManagerDx
|
2019-11-21 00:33:55 +03:00
|
|
|
# include "mozilla/layers/ImageDataSerializer.h"
|
2017-07-19 06:09:00 +03:00
|
|
|
#endif
|
2020-04-02 05:16:18 +03:00
|
|
|
#include "mozilla/D3DMessageUtils.h" // for DxgiAdapterDesc
|
2020-01-09 01:19:14 +03:00
|
|
|
#include "mozilla/dom/WebGLParent.h"
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "mozilla/ipc/Transport.h" // for Transport
|
2017-02-10 01:30:11 +03:00
|
|
|
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
|
2018-03-29 01:36:42 +03:00
|
|
|
#include "mozilla/layers/APZUpdater.h" // for APZUpdater
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "mozilla/layers/AsyncCompositionManager.h"
|
2017-01-13 01:29:41 +03:00
|
|
|
#include "mozilla/layers/CompositorOptions.h"
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
|
|
|
#include "mozilla/layers/LayerManagerComposite.h"
|
|
|
|
#include "mozilla/layers/LayerTreeOwnerTracker.h"
|
|
|
|
#include "mozilla/layers/PLayerTransactionParent.h"
|
|
|
|
#include "mozilla/layers/RemoteContentController.h"
|
2016-11-16 16:54:51 +03:00
|
|
|
#include "mozilla/layers/WebRenderBridgeParent.h"
|
2017-07-25 11:54:36 +03:00
|
|
|
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
2019-11-14 07:59:56 +03:00
|
|
|
#include "mozilla/webgpu/WebGPUParent.h"
|
2016-11-10 21:05:06 +03:00
|
|
|
#include "mozilla/mozalloc.h" // for operator new, etc
|
|
|
|
#include "nsDebug.h" // for NS_ASSERTION, etc
|
|
|
|
#include "nsTArray.h" // for nsTArray
|
|
|
|
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop
|
|
|
|
#include "mozilla/Unused.h"
|
|
|
|
#include "mozilla/StaticPtr.h"
|
2018-12-02 17:02:27 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
# include "ProfilerMarkerPayload.h"
|
|
|
|
#endif
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
namespace layers {
|
|
|
|
|
|
|
|
// defined in CompositorBridgeParent.cpp
|
2019-09-02 20:38:31 +03:00
|
|
|
typedef std::map<LayersId, CompositorBridgeParent::LayerTreeState> LayerTreeMap;
|
2016-11-10 21:05:06 +03:00
|
|
|
extern LayerTreeMap sIndirectLayerTrees;
|
|
|
|
extern StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
|
2018-03-25 02:06:01 +03:00
|
|
|
void UpdateIndirectTree(LayersId aId, Layer* aRoot,
|
|
|
|
const TargetConfig& aTargetConfig);
|
|
|
|
void EraseLayerState(LayersId aId);
|
2016-11-10 21:05:06 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint() {
|
2016-11-10 21:05:06 +03:00
|
|
|
mNotifyAfterRemotePaint = true;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
|
2017-06-14 18:40:00 +03:00
|
|
|
mCanSend = false;
|
|
|
|
|
2016-11-10 21:05:06 +03:00
|
|
|
// We must keep this object alive untill the code handling message
|
|
|
|
// reception is finished on this thread.
|
2020-07-03 01:59:24 +03:00
|
|
|
GetCurrentSerialEventTarget()->Dispatch(NewRunnableMethod(
|
2019-03-04 00:02:25 +03:00
|
|
|
"layers::ContentCompositorBridgeParent::DeferredDestroy", this,
|
|
|
|
&ContentCompositorBridgeParent::DeferredDestroy));
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
PLayerTransactionParent*
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::AllocPLayerTransactionParent(
|
2016-11-10 21:05:06 +03:00
|
|
|
const nsTArray<LayersBackend>&, const LayersId& aId) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aId.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
// Check to see if this child process has access to this layer tree.
|
|
|
|
if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) {
|
|
|
|
NS_ERROR(
|
|
|
|
"Unexpected layers id in AllocPLayerTransactionParent; dropping "
|
|
|
|
"message...");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state = nullptr;
|
|
|
|
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
|
|
|
|
if (sIndirectLayerTrees.end() != itr) {
|
|
|
|
state = &itr->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state && state->mLayerManager) {
|
2019-03-05 04:37:37 +03:00
|
|
|
state->mContentCompositorBridgeParent = this;
|
2016-11-24 08:11:27 +03:00
|
|
|
HostLayerManager* lm = state->mLayerManager;
|
2017-07-10 04:03:12 +03:00
|
|
|
CompositorAnimationStorage* animStorage =
|
|
|
|
state->mParent ? state->mParent->GetAnimationStorage() : nullptr;
|
2018-06-26 21:40:10 +03:00
|
|
|
TimeDuration vsyncRate =
|
|
|
|
state->mParent ? state->mParent->GetVsyncInterval() : TimeDuration();
|
|
|
|
LayerTransactionParent* p =
|
|
|
|
new LayerTransactionParent(lm, this, animStorage, aId, vsyncRate);
|
2016-11-10 21:05:06 +03:00
|
|
|
p->AddIPDLReference();
|
|
|
|
sIndirectLayerTrees[aId].mLayerTree = p;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_WARNING("Created child without a matching parent?");
|
2018-06-26 21:40:10 +03:00
|
|
|
LayerTransactionParent* p = new LayerTransactionParent(
|
|
|
|
/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId,
|
|
|
|
TimeDuration());
|
2016-11-10 21:05:06 +03:00
|
|
|
p->AddIPDLReference();
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::DeallocPLayerTransactionParent(
|
2016-11-10 21:05:06 +03:00
|
|
|
PLayerTransactionParent* aLayers) {
|
|
|
|
LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
|
|
|
|
EraseLayerState(slp->GetId());
|
|
|
|
static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
PAPZCTreeManagerParent*
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::AllocPAPZCTreeManagerParent(
|
2018-03-25 02:06:01 +03:00
|
|
|
const LayersId& aLayersId) {
|
2016-11-10 21:05:06 +03:00
|
|
|
// Check to see if this child process has access to this layer tree.
|
|
|
|
if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
|
|
|
|
NS_ERROR(
|
|
|
|
"Unexpected layers id in AllocPAPZCTreeManagerParent; dropping "
|
|
|
|
"message...");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
CompositorBridgeParent::LayerTreeState& state =
|
|
|
|
sIndirectLayerTrees[aLayersId];
|
2017-04-28 21:22:21 +03:00
|
|
|
|
|
|
|
// If the widget has shutdown its compositor, we may not have had a chance yet
|
|
|
|
// to unmap our layers id, and we could get here without a parent compositor.
|
|
|
|
// In this case return an empty APZCTM.
|
|
|
|
if (!state.mParent) {
|
2017-05-04 10:13:38 +03:00
|
|
|
// Note: we immediately call ClearTree since otherwise the APZCTM will
|
|
|
|
// retain a reference to itself, through the checkerboard observer.
|
2018-04-10 19:30:01 +03:00
|
|
|
LayersId dummyId{0};
|
|
|
|
RefPtr<APZCTreeManager> temp = new APZCTreeManager(dummyId);
|
2018-04-19 17:09:59 +03:00
|
|
|
RefPtr<APZUpdater> tempUpdater = new APZUpdater(temp, false);
|
2018-04-10 19:30:01 +03:00
|
|
|
tempUpdater->ClearTree(dummyId);
|
2020-03-27 20:40:40 +03:00
|
|
|
return new APZCTreeManagerParent(aLayersId, temp, tempUpdater);
|
2017-04-28 21:22:21 +03:00
|
|
|
}
|
|
|
|
|
2020-03-27 20:40:40 +03:00
|
|
|
state.mParent->AllocateAPZCTreeManagerParent(lock, aLayersId, state);
|
2016-11-10 21:05:06 +03:00
|
|
|
return state.mApzcTreeManagerParent;
|
|
|
|
}
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::DeallocPAPZCTreeManagerParent(
|
2016-11-10 21:05:06 +03:00
|
|
|
PAPZCTreeManagerParent* aActor) {
|
|
|
|
APZCTreeManagerParent* parent = static_cast<APZCTreeManagerParent*>(aActor);
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2018-03-25 02:06:01 +03:00
|
|
|
auto iter = sIndirectLayerTrees.find(parent->GetLayersId());
|
2016-11-10 21:05:06 +03:00
|
|
|
if (iter != sIndirectLayerTrees.end()) {
|
|
|
|
CompositorBridgeParent::LayerTreeState& state = iter->second;
|
|
|
|
MOZ_ASSERT(state.mApzcTreeManagerParent == parent);
|
|
|
|
state.mApzcTreeManagerParent = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete parent;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
PAPZParent* ContentCompositorBridgeParent::AllocPAPZParent(
|
2018-03-25 02:06:01 +03:00
|
|
|
const LayersId& aLayersId) {
|
2016-11-10 21:05:06 +03:00
|
|
|
// Check to see if this child process has access to this layer tree.
|
|
|
|
if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
|
|
|
|
NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoteContentController* controller = new RemoteContentController();
|
|
|
|
|
|
|
|
// Increment the controller's refcount before we return it. This will keep the
|
|
|
|
// controller alive until it is released by IPDL in DeallocPAPZParent.
|
|
|
|
controller->AddRef();
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
CompositorBridgeParent::LayerTreeState& state =
|
|
|
|
sIndirectLayerTrees[aLayersId];
|
|
|
|
MOZ_ASSERT(!state.mController);
|
|
|
|
state.mController = controller;
|
|
|
|
|
|
|
|
return controller;
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor) {
|
2016-11-10 21:05:06 +03:00
|
|
|
RemoteContentController* controller =
|
|
|
|
static_cast<RemoteContentController*>(aActor);
|
|
|
|
controller->Release();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
PWebRenderBridgeParent*
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::AllocPWebRenderBridgeParent(
|
2018-10-05 10:35:29 +03:00
|
|
|
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId layersId = wr::AsLayersId(aPipelineId);
|
2016-11-16 16:54:51 +03:00
|
|
|
// Check to see if this child process has access to this layer tree.
|
2017-04-19 13:58:10 +03:00
|
|
|
if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) {
|
2018-06-15 18:18:05 +03:00
|
|
|
NS_ERROR(
|
|
|
|
"Unexpected layers id in AllocPWebRenderBridgeParent; dropping "
|
|
|
|
"message...");
|
2016-11-16 16:54:51 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-04-26 22:29:21 +03:00
|
|
|
RefPtr<CompositorBridgeParent> cbp = nullptr;
|
|
|
|
RefPtr<WebRenderBridgeParent> root = nullptr;
|
|
|
|
|
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
MOZ_ASSERT(sIndirectLayerTrees.find(layersId) != sIndirectLayerTrees.end());
|
|
|
|
MOZ_ASSERT(sIndirectLayerTrees[layersId].mWrBridge == nullptr);
|
|
|
|
cbp = sIndirectLayerTrees[layersId].mParent;
|
|
|
|
if (cbp) {
|
|
|
|
root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge;
|
|
|
|
}
|
2017-10-19 05:15:46 +03:00
|
|
|
}
|
2018-03-13 07:53:07 +03:00
|
|
|
|
2020-05-05 21:15:43 +03:00
|
|
|
RefPtr<wr::WebRenderAPI> api;
|
2018-03-13 07:53:07 +03:00
|
|
|
if (root) {
|
2020-05-05 21:15:43 +03:00
|
|
|
api = root->GetWebRenderAPI();
|
2018-03-13 07:53:07 +03:00
|
|
|
}
|
|
|
|
|
2020-05-05 21:15:43 +03:00
|
|
|
if (!root || !api) {
|
2017-06-30 04:06:11 +03:00
|
|
|
// This could happen when this function is called after
|
|
|
|
// CompositorBridgeParent destruction. This was observed during Tab move
|
|
|
|
// between different windows.
|
2018-04-26 22:29:21 +03:00
|
|
|
NS_WARNING(
|
|
|
|
nsPrintfCString("Created child without a matching parent? root %p",
|
|
|
|
root.get())
|
|
|
|
.get());
|
|
|
|
WebRenderBridgeParent* parent =
|
|
|
|
WebRenderBridgeParent::CreateDestroyed(aPipelineId);
|
2017-08-03 12:36:55 +03:00
|
|
|
parent->AddRef(); // IPDL reference
|
2017-06-30 04:06:11 +03:00
|
|
|
return parent;
|
|
|
|
}
|
2016-11-16 16:54:51 +03:00
|
|
|
|
2020-05-05 21:15:43 +03:00
|
|
|
api = api->Clone();
|
2017-07-25 11:54:36 +03:00
|
|
|
RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
|
2018-04-26 22:29:21 +03:00
|
|
|
WebRenderBridgeParent* parent = new WebRenderBridgeParent(
|
2020-05-05 21:15:43 +03:00
|
|
|
this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api),
|
2020-06-18 02:47:20 +03:00
|
|
|
std::move(holder), cbp->GetVsyncInterval());
|
2016-11-16 16:54:51 +03:00
|
|
|
parent->AddRef(); // IPDL reference
|
2017-08-03 12:36:55 +03:00
|
|
|
|
2018-04-26 22:29:21 +03:00
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2019-03-05 04:37:37 +03:00
|
|
|
sIndirectLayerTrees[layersId].mContentCompositorBridgeParent = this;
|
2018-04-26 22:29:21 +03:00
|
|
|
sIndirectLayerTrees[layersId].mWrBridge = parent;
|
|
|
|
}
|
2017-02-27 06:16:11 +03:00
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::DeallocPWebRenderBridgeParent(
|
2016-11-16 16:54:51 +03:00
|
|
|
PWebRenderBridgeParent* aActor) {
|
|
|
|
WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
|
2018-03-25 02:06:01 +03:00
|
|
|
EraseLayerState(wr::AsLayersId(parent->PipelineId()));
|
2016-11-16 16:54:51 +03:00
|
|
|
parent->Release(); // IPDL reference
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-11-14 07:59:56 +03:00
|
|
|
webgpu::PWebGPUParent* ContentCompositorBridgeParent::AllocPWebGPUParent() {
|
|
|
|
webgpu::WebGPUParent* parent = new webgpu::WebGPUParent();
|
|
|
|
parent->AddRef(); // IPDL reference
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentCompositorBridgeParent::DeallocPWebGPUParent(
|
|
|
|
webgpu::PWebGPUParent* aActor) {
|
|
|
|
webgpu::WebGPUParent* parent = static_cast<webgpu::WebGPUParent*>(aActor);
|
|
|
|
parent->Release(); // IPDL reference
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvNotifyChildCreated(
|
2017-04-10 00:30:27 +03:00
|
|
|
const LayersId& child, CompositorOptions* aOptions) {
|
2016-11-10 21:05:06 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
|
|
|
|
it != sIndirectLayerTrees.end(); it++) {
|
|
|
|
CompositorBridgeParent::LayerTreeState* lts = &it->second;
|
2019-03-05 04:37:37 +03:00
|
|
|
if (lts->mParent && lts->mContentCompositorBridgeParent == this) {
|
2016-11-10 21:05:06 +03:00
|
|
|
lts->mParent->NotifyChildCreated(child);
|
2017-04-10 00:30:27 +03:00
|
|
|
*aOptions = lts->mParent->GetOptions();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 01:13:37 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::RecvMapAndNotifyChildCreated(
|
2017-04-10 00:30:27 +03:00
|
|
|
const LayersId& child, const base::ProcessId& pid,
|
|
|
|
CompositorOptions* aOptions) {
|
2017-04-04 01:13:37 +03:00
|
|
|
// This can only be called from the browser process, as the mapping
|
|
|
|
// ensures proper window ownership of layer trees.
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvCheckContentOnlyTDR(
|
2017-07-19 06:09:00 +03:00
|
|
|
const uint32_t& sequenceNum, bool* isContentOnlyTDR) {
|
|
|
|
*isContentOnlyTDR = false;
|
|
|
|
#ifdef XP_WIN
|
2018-12-02 17:02:27 +03:00
|
|
|
gfx::ContentDeviceData compositor;
|
2017-07-19 06:09:00 +03:00
|
|
|
|
2018-12-02 17:02:27 +03:00
|
|
|
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
|
2017-07-19 06:09:00 +03:00
|
|
|
|
|
|
|
// Check that the D3D11 device sequence numbers match.
|
2018-12-02 17:02:27 +03:00
|
|
|
gfx::D3D11DeviceStatus status;
|
2017-07-19 06:09:00 +03:00
|
|
|
dm->ExportDeviceInfo(&status);
|
|
|
|
|
|
|
|
if (sequenceNum == status.sequenceNumber() && !dm->HasDeviceReset()) {
|
|
|
|
*isContentOnlyTDR = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return IPC_OK();
|
|
|
|
};
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::ShadowLayersUpdated(
|
2016-11-10 21:05:06 +03:00
|
|
|
LayerTransactionParent* aLayerTree, const TransactionInfo& aInfo,
|
|
|
|
bool aHitTestUpdate) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
2016-11-10 21:05:06 +03:00
|
|
|
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(id.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(state->mParent);
|
2017-01-04 20:58:58 +03:00
|
|
|
state->mParent->ScheduleRotationOnCompositorThread(aInfo.targetConfig(),
|
|
|
|
aInfo.isFirstPaint());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
Layer* shadowRoot = aLayerTree->GetRoot();
|
|
|
|
if (shadowRoot) {
|
|
|
|
CompositorBridgeParent::SetShadowProperties(shadowRoot);
|
|
|
|
}
|
2017-01-04 20:58:58 +03:00
|
|
|
UpdateIndirectTree(id, shadowRoot, aInfo.targetConfig());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
// Cache the plugin data for this remote layer tree
|
2020-05-05 15:59:26 +03:00
|
|
|
state->mPluginData = aInfo.plugins().Clone();
|
2016-11-10 21:05:06 +03:00
|
|
|
state->mUpdatedPluginDataAvailable = true;
|
|
|
|
|
2017-01-04 20:58:58 +03:00
|
|
|
state->mParent->NotifyShadowTreeTransaction(
|
|
|
|
id, aInfo.isFirstPaint(), aInfo.focusTarget(), aInfo.scheduleComposite(),
|
|
|
|
aInfo.paintSequenceNumber(), aInfo.isRepeatTransaction(), aHitTestUpdate);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-11-10 21:05:06 +03:00
|
|
|
// Send the 'remote paint ready' message to the content thread if it has
|
|
|
|
// already asked.
|
|
|
|
if (mNotifyAfterRemotePaint) {
|
|
|
|
Unused << SendRemotePaintIsReady();
|
|
|
|
mNotifyAfterRemotePaint = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aLayerTree->ShouldParentObserveEpoch()) {
|
|
|
|
// Note that we send this through the window compositor, since this needs
|
|
|
|
// to reach the widget owning the tab.
|
2018-07-30 16:24:50 +03:00
|
|
|
Unused << state->mParent->SendObserveLayersUpdate(
|
|
|
|
id, aLayerTree->GetChildEpoch(), true);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2018-11-16 08:26:10 +03:00
|
|
|
auto endTime = TimeStamp::Now();
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
2019-09-18 04:22:12 +03:00
|
|
|
if (profiler_can_accept_markers()) {
|
2018-11-16 08:26:10 +03:00
|
|
|
class ContentBuildPayload : public ProfilerMarkerPayload {
|
|
|
|
public:
|
|
|
|
ContentBuildPayload(const mozilla::TimeStamp& aStartTime,
|
|
|
|
const mozilla::TimeStamp& aEndTime)
|
|
|
|
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
2020-03-16 23:32:35 +03:00
|
|
|
mozilla::ProfileBufferEntryWriter::Length TagAndSerializationBytes()
|
2019-09-18 04:20:10 +03:00
|
|
|
const override {
|
|
|
|
return CommonPropsTagAndSerializationBytes();
|
|
|
|
}
|
|
|
|
void SerializeTagAndPayload(
|
2020-03-12 00:59:19 +03:00
|
|
|
mozilla::ProfileBufferEntryWriter& aEntryWriter) const override {
|
2019-09-18 04:20:10 +03:00
|
|
|
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
|
|
|
SerializeTagAndCommonProps(tag, aEntryWriter);
|
|
|
|
}
|
2020-08-11 06:50:54 +03:00
|
|
|
void StreamPayload(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
|
2019-09-18 04:20:10 +03:00
|
|
|
const TimeStamp& aProcessStartTime,
|
|
|
|
UniqueStacks& aUniqueStacks) const override {
|
2018-11-16 08:26:10 +03:00
|
|
|
StreamCommonProps("CONTENT_FULL_PAINT_TIME", aWriter, aProcessStartTime,
|
|
|
|
aUniqueStacks);
|
|
|
|
}
|
2019-09-18 04:20:10 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
explicit ContentBuildPayload(CommonProps&& aCommonProps)
|
|
|
|
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
|
|
|
static mozilla::UniquePtr<ProfilerMarkerPayload> Deserialize(
|
2020-03-12 00:59:19 +03:00
|
|
|
mozilla::ProfileBufferEntryReader& aEntryReader) {
|
2019-09-18 04:20:10 +03:00
|
|
|
ProfilerMarkerPayload::CommonProps props =
|
|
|
|
DeserializeCommonProps(aEntryReader);
|
|
|
|
return UniquePtr<ProfilerMarkerPayload>(
|
|
|
|
new ContentBuildPayload(std::move(props)));
|
|
|
|
}
|
2018-11-16 08:26:10 +03:00
|
|
|
};
|
2019-09-04 10:58:21 +03:00
|
|
|
AUTO_PROFILER_STATS(add_marker_with_ContentBuildPayload);
|
2018-11-16 08:26:10 +03:00
|
|
|
profiler_add_marker_for_thread(
|
2019-02-16 20:37:43 +03:00
|
|
|
profiler_current_thread_id(), JS::ProfilingCategoryPair::GRAPHICS,
|
|
|
|
"CONTENT_FULL_PAINT_TIME",
|
2020-05-20 02:07:54 +03:00
|
|
|
ContentBuildPayload(aInfo.transactionStart(), endTime));
|
2018-11-16 08:26:10 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
Telemetry::Accumulate(
|
|
|
|
Telemetry::CONTENT_FULL_PAINT_TIME,
|
|
|
|
static_cast<uint32_t>(
|
|
|
|
(endTime - aInfo.transactionStart()).ToMilliseconds()));
|
|
|
|
|
2019-05-28 16:42:57 +03:00
|
|
|
RegisterPayloads(aLayerTree, aInfo.payload());
|
2019-01-11 00:41:14 +03:00
|
|
|
|
2018-12-08 02:28:03 +03:00
|
|
|
aLayerTree->SetPendingTransactionId(
|
2019-01-03 22:43:04 +03:00
|
|
|
aInfo.id(), aInfo.vsyncId(), aInfo.vsyncStart(), aInfo.refreshStart(),
|
2019-01-15 22:16:48 +03:00
|
|
|
aInfo.transactionStart(), endTime, aInfo.containsSVG(), aInfo.url(),
|
|
|
|
aInfo.fwdTime());
|
2018-12-07 20:38:47 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::DidCompositeLocked(
|
2018-12-08 02:28:41 +03:00
|
|
|
LayersId aId, const VsyncId& aVsyncId, TimeStamp& aCompositeStart,
|
|
|
|
TimeStamp& aCompositeEnd) {
|
2016-11-10 21:05:06 +03:00
|
|
|
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
|
|
|
|
if (LayerTransactionParent* layerTree = sIndirectLayerTrees[aId].mLayerTree) {
|
2018-12-08 02:28:41 +03:00
|
|
|
TransactionId transactionId =
|
|
|
|
layerTree->FlushTransactionId(aVsyncId, aCompositeEnd);
|
2018-04-20 22:13:06 +03:00
|
|
|
if (transactionId.IsValid()) {
|
2017-07-24 14:07:35 +03:00
|
|
|
Unused << SendDidComposite(aId, transactionId, aCompositeStart,
|
|
|
|
aCompositeEnd);
|
|
|
|
}
|
2018-07-27 16:42:30 +03:00
|
|
|
} else if (sIndirectLayerTrees[aId].mWrBridge) {
|
|
|
|
MOZ_ASSERT(false); // this should never get called for a WR compositor
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::ScheduleComposite(
|
2018-02-02 16:57:35 +03:00
|
|
|
LayerTransactionParent* aLayerTree) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
CompositorBridgeParent* parent;
|
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
parent = sIndirectLayerTrees[id].mParent;
|
|
|
|
}
|
|
|
|
if (parent) {
|
2018-02-02 16:57:35 +03:00
|
|
|
parent->ScheduleComposite(aLayerTree);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::NotifyClearCachedResources(
|
2016-11-10 21:05:06 +03:00
|
|
|
LayerTransactionParent* aLayerTree) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (state && state->mParent) {
|
|
|
|
// Note that we send this through the window compositor, since this needs
|
|
|
|
// to reach the widget owning the tab.
|
2018-07-30 16:24:50 +03:00
|
|
|
Unused << state->mParent->SendObserveLayersUpdate(
|
|
|
|
id, aLayerTree->GetChildEpoch(), false);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::SetTestSampleTime(const LayersId& aId,
|
|
|
|
const TimeStamp& aTime) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aId.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2017-06-28 03:29:05 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aId);
|
2016-11-10 21:05:06 +03:00
|
|
|
if (!state) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
2017-06-28 03:29:05 +03:00
|
|
|
return state->mParent->SetTestSampleTime(aId, aTime);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::LeaveTestMode(const LayersId& aId) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aId.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2017-06-28 03:29:05 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aId);
|
2016-11-10 21:05:06 +03:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
2017-06-28 03:29:05 +03:00
|
|
|
state->mParent->LeaveTestMode(aId);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::ApplyAsyncProperties(
|
2018-06-05 03:18:21 +03:00
|
|
|
LayerTransactionParent* aLayerTree, TransformsToSkip aSkip) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
2018-06-05 03:18:21 +03:00
|
|
|
state->mParent->ApplyAsyncProperties(aLayerTree, aSkip);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
2017-02-10 01:30:11 +03:00
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::SetTestAsyncScrollOffset(
|
2020-03-27 20:40:40 +03:00
|
|
|
const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
|
2018-03-06 18:25:37 +03:00
|
|
|
const CSSPoint& aPoint) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2018-03-06 18:25:37 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2020-03-27 20:40:40 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
2018-03-06 18:25:37 +03:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::SetTestAsyncZoom(
|
2020-03-27 20:40:40 +03:00
|
|
|
const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
|
2018-03-06 18:25:37 +03:00
|
|
|
const LayerToParentLayerScale& aZoom) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2018-03-06 18:25:37 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2020-03-27 20:40:40 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
2018-03-06 18:25:37 +03:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->SetTestAsyncZoom(aLayersId, aScrollId, aZoom);
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::FlushApzRepaints(
|
2020-03-27 20:40:40 +03:00
|
|
|
const LayersId& aLayersId) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2020-03-27 20:40:40 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
2018-12-06 22:20:12 +03:00
|
|
|
if (!state || !state->mParent) {
|
2016-11-10 21:05:06 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-28 14:48:29 +03:00
|
|
|
state->mParent->FlushApzRepaints(aLayersId);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2020-03-27 20:40:40 +03:00
|
|
|
void ContentCompositorBridgeParent::GetAPZTestData(const LayersId& aLayersId,
|
2019-03-04 00:02:25 +03:00
|
|
|
APZTestData* aOutData) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2018-03-02 07:00:40 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2020-03-27 20:40:40 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
2018-03-02 07:00:40 +03:00
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
state->mParent->GetAPZTestData(aLayersId, aOutData);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2020-08-06 00:42:06 +03:00
|
|
|
void ContentCompositorBridgeParent::GetFrameUniformity(
|
|
|
|
const LayersId& aLayersId, FrameUniformityData* aOutData) {
|
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
state->mParent->GetFrameUniformity(aLayersId, aOutData);
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::SetConfirmedTargetAPZC(
|
2016-11-10 21:05:06 +03:00
|
|
|
const LayersId& aLayersId, const uint64_t& aInputBlockId,
|
2020-08-25 05:17:06 +03:00
|
|
|
nsTArray<ScrollableLayerGuid>&& aTargets) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
2017-05-28 14:51:48 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
2016-11-10 21:05:06 +03:00
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-25 05:17:06 +03:00
|
|
|
state->mParent->SetConfirmedTargetAPZC(aLayersId, aInputBlockId,
|
|
|
|
std::move(aTargets));
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
AsyncCompositionManager* ContentCompositorBridgeParent::GetCompositionManager(
|
2016-11-10 21:05:06 +03:00
|
|
|
LayerTransactionParent* aLayerTree) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
2016-11-10 21:05:06 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
return state->mParent->GetCompositionManager(aLayerTree);
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::DeferredDestroy() { mSelfRef = nullptr; }
|
2016-11-10 21:05:06 +03:00
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
ContentCompositorBridgeParent::~ContentCompositorBridgeParent() {
|
2016-11-10 21:05:06 +03:00
|
|
|
MOZ_ASSERT(XRE_GetIOMessageLoop());
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
PTextureParent* ContentCompositorBridgeParent::AllocPTextureParent(
|
2018-03-12 16:10:13 +03:00
|
|
|
const SurfaceDescriptor& aSharedData, const ReadLockDescriptor& aReadLock,
|
2016-11-10 21:05:06 +03:00
|
|
|
const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
|
2017-04-20 04:24:13 +03:00
|
|
|
const LayersId& aId, const uint64_t& aSerial,
|
|
|
|
const wr::MaybeExternalImageId& aExternalImageId) {
|
2016-11-10 21:05:06 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState* state = nullptr;
|
|
|
|
|
|
|
|
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
|
|
|
|
if (sIndirectLayerTrees.end() != itr) {
|
|
|
|
state = &itr->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextureFlags flags = aFlags;
|
|
|
|
|
2017-06-20 11:17:19 +03:00
|
|
|
LayersBackend actualBackend = LayersBackend::LAYERS_NONE;
|
|
|
|
if (state && state->mLayerManager) {
|
|
|
|
actualBackend = state->mLayerManager->GetBackendType();
|
|
|
|
}
|
|
|
|
|
2017-05-12 08:44:28 +03:00
|
|
|
if (!state) {
|
2016-11-10 21:05:06 +03:00
|
|
|
// The compositor was recreated, and we're receiving layers updates for a
|
|
|
|
// a layer manager that will soon be discarded or invalidated. We can't
|
|
|
|
// return null because this will mess up deserialization later and we'll
|
|
|
|
// kill the content process. Instead, we signal that the underlying
|
|
|
|
// TextureHost should not attempt to access the compositor.
|
|
|
|
flags |= TextureFlags::INVALID_COMPOSITOR;
|
2017-06-20 11:17:19 +03:00
|
|
|
} else if (actualBackend != LayersBackend::LAYERS_NONE &&
|
|
|
|
aLayersBackend != actualBackend) {
|
2016-11-10 21:05:06 +03:00
|
|
|
gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch)
|
|
|
|
<< "Texture backend is wrong";
|
|
|
|
}
|
|
|
|
|
2018-03-12 16:10:13 +03:00
|
|
|
return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock,
|
|
|
|
aLayersBackend, aFlags, aSerial,
|
|
|
|
aExternalImageId);
|
2016-11-10 21:05:06 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::DeallocPTextureParent(
|
2016-11-10 21:05:06 +03:00
|
|
|
PTextureParent* actor) {
|
|
|
|
return TextureHost::DestroyIPDLActor(actor);
|
|
|
|
}
|
|
|
|
|
2018-12-02 17:19:11 +03:00
|
|
|
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvInitPCanvasParent(
|
|
|
|
Endpoint<PCanvasParent>&& aEndpoint) {
|
2020-02-24 14:15:41 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!mCanvasTranslator,
|
|
|
|
"mCanvasTranslator must be released before recreating.");
|
2018-12-02 17:19:11 +03:00
|
|
|
|
2020-02-24 14:15:41 +03:00
|
|
|
mCanvasTranslator = CanvasTranslator::Create(std::move(aEndpoint));
|
2018-12-02 17:19:11 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-09-17 03:15:59 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentCompositorBridgeParent::RecvReleasePCanvasParent() {
|
2020-02-24 14:15:41 +03:00
|
|
|
MOZ_RELEASE_ASSERT(mCanvasTranslator,
|
|
|
|
"mCanvasTranslator hasn't been created.");
|
2019-09-17 03:15:59 +03:00
|
|
|
|
2020-02-24 14:15:41 +03:00
|
|
|
mCanvasTranslator = nullptr;
|
2019-09-17 03:15:59 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-12-02 17:19:11 +03:00
|
|
|
UniquePtr<SurfaceDescriptor>
|
|
|
|
ContentCompositorBridgeParent::LookupSurfaceDescriptorForClientDrawTarget(
|
|
|
|
const uintptr_t aDrawTarget) {
|
2020-02-24 14:15:41 +03:00
|
|
|
return mCanvasTranslator->WaitForSurfaceDescriptor(
|
|
|
|
reinterpret_cast<void*>(aDrawTarget));
|
2018-12-02 17:19:11 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
bool ContentCompositorBridgeParent::IsSameProcess() const {
|
2016-11-10 21:05:06 +03:00
|
|
|
return OtherPid() == base::GetCurrentProcId();
|
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::UpdatePaintTime(
|
2016-11-10 21:05:06 +03:00
|
|
|
LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) {
|
2018-03-25 02:06:01 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id.IsValid());
|
2016-11-10 21:05:06 +03:00
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
state->mParent->UpdatePaintTime(aLayerTree, aPaintTime);
|
|
|
|
}
|
|
|
|
|
2019-05-28 16:42:57 +03:00
|
|
|
void ContentCompositorBridgeParent::RegisterPayloads(
|
2018-12-13 17:56:51 +03:00
|
|
|
LayerTransactionParent* aLayerTree,
|
2019-05-28 16:42:57 +03:00
|
|
|
const nsTArray<CompositionPayload>& aPayload) {
|
2018-12-13 17:56:51 +03:00
|
|
|
LayersId id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id.IsValid());
|
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-28 16:42:57 +03:00
|
|
|
state->mParent->RegisterPayloads(aLayerTree, aPayload);
|
2018-12-13 17:56:51 +03:00
|
|
|
}
|
|
|
|
|
2019-03-04 00:02:25 +03:00
|
|
|
void ContentCompositorBridgeParent::ObserveLayersUpdate(
|
2018-07-30 16:24:50 +03:00
|
|
|
LayersId aLayersId, LayersObserverEpoch aEpoch, bool aActive) {
|
2018-03-25 02:06:01 +03:00
|
|
|
MOZ_ASSERT(aLayersId.IsValid());
|
2016-11-30 05:59:14 +03:00
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-30 16:24:50 +03:00
|
|
|
Unused << state->mParent->SendObserveLayersUpdate(aLayersId, aEpoch, aActive);
|
2016-11-30 05:59:14 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 00:33:55 +03:00
|
|
|
static inline bool AllowDirectDXGISurfaceDrawing() {
|
|
|
|
if (!StaticPrefs::dom_ipc_plugins_asyncdrawing_enabled()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#if defined(XP_WIN)
|
2020-01-09 01:19:23 +03:00
|
|
|
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
|
2019-11-21 00:33:55 +03:00
|
|
|
MOZ_ASSERT(dm);
|
|
|
|
if (!dm || !dm->GetCompositorDevice() || !dm->TextureSharingWorks()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentCompositorBridgeParent::RecvSupportsAsyncDXGISurface(bool* value) {
|
|
|
|
*value = AllowDirectDXGISurfaceDrawing();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvPreferredDXGIAdapter(
|
|
|
|
DxgiAdapterDesc* aOutDesc) {
|
|
|
|
PodZero(aOutDesc);
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (!AllowDirectDXGISurfaceDrawing()) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
2020-01-09 01:19:23 +03:00
|
|
|
RefPtr<ID3D11Device> device =
|
|
|
|
gfx::DeviceManagerDx::Get()->GetCompositorDevice();
|
2019-11-21 00:33:55 +03:00
|
|
|
if (!device) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<IDXGIDevice> dxgi;
|
|
|
|
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice),
|
|
|
|
getter_AddRefs(dxgi))) ||
|
|
|
|
!dxgi) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
RefPtr<IDXGIAdapter> adapter;
|
|
|
|
if (FAILED(dxgi->GetAdapter(getter_AddRefs(adapter))) || !adapter) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
DXGI_ADAPTER_DESC desc;
|
|
|
|
if (FAILED(adapter->GetDesc(&desc))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOutDesc = DxgiAdapterDesc::From(desc);
|
|
|
|
#endif
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2020-01-09 01:19:16 +03:00
|
|
|
already_AddRefed<dom::PWebGLParent>
|
2020-05-01 01:23:48 +03:00
|
|
|
ContentCompositorBridgeParent::AllocPWebGLParent() {
|
|
|
|
RefPtr<dom::PWebGLParent> parent = new dom::WebGLParent();
|
|
|
|
return parent.forget();
|
2020-01-09 01:19:14 +03:00
|
|
|
}
|
|
|
|
|
2016-11-10 21:05:06 +03:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|