mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
apz
This commit is contained in:
13 files changed
+485
-15
No files matched your search
@@ -741,6 +741,15 @@ std::vector<LayersId> APZCTreeManager::UpdateHitTestingTree(
|
||||
// APZC instances
|
||||
MutexAutoLock lock(mMapLock);
|
||||
mApzcMap = std::move(state.mApzcMap);
|
||||
{
|
||||
static int s_apzcLog = 0;
|
||||
if (s_apzcLog < 6) {
|
||||
s_apzcLog++;
|
||||
printf("APZ-DIAG UpdateHitTestingTree: APZC count=%zu\n",
|
||||
mApzcMap.size());
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& mapping : mApzcMap) {
|
||||
AsyncPanZoomController* parent = mapping.second.apzc->GetParent();
|
||||
@@ -1711,6 +1720,19 @@ APZEventResult APZCTreeManager::ReceiveInputEvent(
|
||||
state.mHit = GetTargetAPZC(wheelInput.mOrigin);
|
||||
|
||||
wheelInput.mHandledByAPZ = WillHandleInput(wheelInput);
|
||||
{
|
||||
static int s_wlog = 0;
|
||||
if (s_wlog < 8) {
|
||||
s_wlog++;
|
||||
printf(
|
||||
"APZ-DIAG wheel hit: origin=(%.1f,%.1f) handledByAPZ=%d "
|
||||
"targetApzc=%p\n",
|
||||
(double)wheelInput.mOrigin.x, (double)wheelInput.mOrigin.y,
|
||||
(int)wheelInput.mHandledByAPZ,
|
||||
(void*)state.mHit.mTargetApzc.get());
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
if (!wheelInput.mHandledByAPZ) {
|
||||
return state.Finish(*this, std::move(aCallback));
|
||||
}
|
||||
|
||||
@@ -326,6 +326,20 @@ APZEventResult APZInputBridge::ReceiveInputEvent(
|
||||
}
|
||||
case eWheelEventClass: {
|
||||
WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent();
|
||||
{
|
||||
Maybe<APZWheelAction> a = ActionForWheelEvent(&wheelEvent);
|
||||
static int s_wa = 0;
|
||||
if (s_wa < 8) {
|
||||
s_wa++;
|
||||
printf(
|
||||
"APZ-DIAG InputBridge wheel: msg=%d deltaMode=%d dY=%.1f "
|
||||
"action=%d\n",
|
||||
(int)wheelEvent.mMessage, (int)wheelEvent.mDeltaMode,
|
||||
(double)wheelEvent.mDeltaY,
|
||||
a.isSome() ? (int)a.value() : -1);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (Maybe<APZWheelAction> action = ActionForWheelEvent(&wheelEvent)) {
|
||||
ScrollWheelInput::ScrollMode scrollMode =
|
||||
|
||||
@@ -64,7 +64,15 @@ void APZSampler::SetSamplerThread(const wr::WrWindowId& aWindowId) {
|
||||
void APZSampler::SampleForWebRender(const wr::WrWindowId& aWindowId,
|
||||
const uint64_t* aGeneratedFrameId,
|
||||
wr::Transaction* aTransaction) {
|
||||
if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
|
||||
RefPtr<APZSampler> sampler = GetSampler(aWindowId);
|
||||
static int s_smpLog = 0;
|
||||
if (s_smpLog < 3) {
|
||||
s_smpLog++;
|
||||
printf("APZ-DIAG SampleForWebRender called, sampler=%p\n",
|
||||
(void*)sampler.get());
|
||||
fflush(stdout);
|
||||
}
|
||||
if (sampler) {
|
||||
wr::TransactionWrapper txn(aTransaction);
|
||||
Maybe<VsyncId> vsyncId =
|
||||
aGeneratedFrameId ? Some(VsyncId{*aGeneratedFrameId}) : Nothing();
|
||||
|
||||
@@ -683,6 +683,19 @@ static bool PrepareForSetTargetAPZCNotification(
|
||||
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(relativeTo, point);
|
||||
ScrollContainerFrame* scrollAncestor =
|
||||
GetScrollContainerFor(target, aRootFrame);
|
||||
{
|
||||
static int s_prep = 0;
|
||||
if (s_prep < 20) {
|
||||
s_prep++;
|
||||
printf("APZ-TGT prepare: target=%p scrollAncestor=%p isRoot=%d\n",
|
||||
(void*)target, (void*)scrollAncestor,
|
||||
scrollAncestor ? (int)(scrollAncestor ==
|
||||
aRootFrame->PresShell()
|
||||
->GetRootScrollContainerFrame())
|
||||
: -1);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// Assuming that if there's no scrollAncestor, there's already a displayPort.
|
||||
nsCOMPtr<dom::Element> dpElement =
|
||||
@@ -816,6 +829,20 @@ APZCCallbackHelper::SendSetTargetAPZCNotification(nsIWidget* aWidget,
|
||||
const WidgetGUIEvent& aEvent,
|
||||
const LayersId& aLayersId,
|
||||
uint64_t aInputBlockId) {
|
||||
{
|
||||
static int s_sstg = 0;
|
||||
if (s_sstg < 20) {
|
||||
s_sstg++;
|
||||
PresShell* ps = aDocument ? aDocument->GetPresShell() : nullptr;
|
||||
printf(
|
||||
"APZ-TGT send: widget=%d doc=%d presShell=%d inputBlock=%llu "
|
||||
"sLast=%llu\n",
|
||||
(int)!!aWidget, (int)!!aDocument, (int)!!ps,
|
||||
(unsigned long long)aInputBlockId,
|
||||
(unsigned long long)sLastTargetAPZCNotificationInputBlock);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
if (!aWidget || !aDocument) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -271,6 +271,9 @@ void CompositorBridgeParent::Initialize() {
|
||||
mApzcTreeManager = APZCTreeManager::Create(mRootLayerTreeID);
|
||||
mApzSampler = new APZSampler(mApzcTreeManager, true);
|
||||
mApzUpdater = new APZUpdater(mApzcTreeManager, true);
|
||||
printf("APZ-INIT: CompositorBridgeParent created APZCTreeManager (UseAPZ=1)\n");
|
||||
} else {
|
||||
printf("APZ-INIT: UseAPZ=0 (no APZCTreeManager)\n");
|
||||
}
|
||||
|
||||
CompositorAnimationStorage* animationStorage = GetAnimationStorage();
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "PDMFactory.h"
|
||||
|
||||
namespace mozilla {
|
||||
@@ -106,8 +109,20 @@ void WebRenderBridgeChild::UpdateResources(
|
||||
nsTArray<ipc::Shmem> largeShmems;
|
||||
aResources.Flush(resourceUpdates, smallShmems, largeShmems);
|
||||
|
||||
this->SendUpdateResources(mIdNamespace, resourceUpdates, smallShmems,
|
||||
std::move(largeShmems));
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessUpdateResources",
|
||||
[p, ns = mIdNamespace, u = std::move(resourceUpdates),
|
||||
s = std::move(smallShmems), l = std::move(largeShmems)]() mutable {
|
||||
p->InProcessUpdateResources(ns, std::move(u), std::move(s),
|
||||
std::move(l));
|
||||
}));
|
||||
} else {
|
||||
this->SendUpdateResources(mIdNamespace, resourceUpdates, smallShmems,
|
||||
std::move(largeShmems));
|
||||
}
|
||||
}
|
||||
|
||||
bool WebRenderBridgeChild::EndTransaction(
|
||||
@@ -120,6 +135,21 @@ bool WebRenderBridgeChild::EndTransaction(
|
||||
MOZ_ASSERT(mIsInTransaction);
|
||||
|
||||
TimeStamp fwdTime = TimeStamp::Now();
|
||||
{
|
||||
static TimeStamp s_lastEnd;
|
||||
static int s_etDiag = 0;
|
||||
if (s_etDiag < 40) {
|
||||
s_etDiag++;
|
||||
double intervalMs =
|
||||
s_lastEnd.IsNull() ? 0.0 : (fwdTime - s_lastEnd).ToMilliseconds();
|
||||
double paintMs = aTxnStartTime.IsNull()
|
||||
? 0.0
|
||||
: (fwdTime - aTxnStartTime).ToMilliseconds();
|
||||
printf("ET-DIAG mainPaintMs=%.1f intervalMs=%.1f\n", paintMs, intervalMs);
|
||||
fflush(stdout);
|
||||
}
|
||||
s_lastEnd = fwdTime;
|
||||
}
|
||||
|
||||
if (!aRenderOffscreen) {
|
||||
MergeWebRenderParentCommands();
|
||||
@@ -133,11 +163,31 @@ bool WebRenderBridgeChild::EndTransaction(
|
||||
}
|
||||
|
||||
mSentDisplayList = true;
|
||||
bool ret = this->SendSetDisplayList(
|
||||
std::move(aDisplayListData), mDestroyedActors, GetFwdTransactionId(),
|
||||
aTransactionId, aContainsSVGGroup, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads,
|
||||
aRenderOffscreen);
|
||||
bool ret = true;
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessSetDisplayList",
|
||||
[p, dl = std::move(aDisplayListData),
|
||||
destroy = std::move(mDestroyedActors), fwdTxn = GetFwdTransactionId(),
|
||||
txnId = aTransactionId, svg = aContainsSVGGroup, vsyncId = aVsyncId,
|
||||
vsyncStart = aVsyncStartTime, refreshStart = aRefreshStartTime,
|
||||
txnStart = aTxnStartTime, url = nsCString(aTxnURL), fwdTime,
|
||||
pl = std::move(payloads),
|
||||
offscreen = aRenderOffscreen]() mutable {
|
||||
p->InProcessSetDisplayList(
|
||||
std::move(dl), std::move(destroy), fwdTxn, txnId, svg, vsyncId,
|
||||
vsyncStart, refreshStart, txnStart, url, fwdTime, std::move(pl),
|
||||
offscreen);
|
||||
}));
|
||||
} else {
|
||||
ret = this->SendSetDisplayList(
|
||||
std::move(aDisplayListData), mDestroyedActors, GetFwdTransactionId(),
|
||||
aTransactionId, aContainsSVGGroup, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads,
|
||||
aRenderOffscreen);
|
||||
}
|
||||
|
||||
// With multiple render roots, we may not have sent all of our
|
||||
// mParentCommands, so go ahead and go through our mParentCommands and ensure
|
||||
@@ -170,10 +220,28 @@ void WebRenderBridgeChild::EndEmptyTransaction(
|
||||
mManager->TakeCompositionPayloads(payloads);
|
||||
}
|
||||
|
||||
this->SendEmptyTransaction(
|
||||
aFocusTarget, std::move(aTransactionData), mDestroyedActors,
|
||||
GetFwdTransactionId(), aTransactionId, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads);
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessEmptyTransaction",
|
||||
[p, focus = aFocusTarget, txnData = std::move(aTransactionData),
|
||||
destroy = std::move(mDestroyedActors), fwdTxn = GetFwdTransactionId(),
|
||||
txnId = aTransactionId, vsyncId = aVsyncId,
|
||||
vsyncStart = aVsyncStartTime, refreshStart = aRefreshStartTime,
|
||||
txnStart = aTxnStartTime, url = nsCString(aTxnURL), fwdTime,
|
||||
pl = std::move(payloads)]() mutable {
|
||||
p->InProcessEmptyTransaction(
|
||||
focus, std::move(txnData), std::move(destroy), fwdTxn, txnId,
|
||||
vsyncId, vsyncStart, refreshStart, txnStart, url, fwdTime,
|
||||
std::move(pl));
|
||||
}));
|
||||
} else {
|
||||
this->SendEmptyTransaction(
|
||||
aFocusTarget, std::move(aTransactionData), mDestroyedActors,
|
||||
GetFwdTransactionId(), aTransactionId, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads);
|
||||
}
|
||||
|
||||
// With multiple render roots, we may not have sent all of our
|
||||
// mParentCommands, so go ahead and go through our mParentCommands and ensure
|
||||
@@ -188,7 +256,17 @@ void WebRenderBridgeChild::ProcessWebRenderParentCommands() {
|
||||
|
||||
if (HasWebRenderParentCommands()) {
|
||||
MergeWebRenderParentCommands();
|
||||
this->SendParentCommands(mIdNamespace, mParentCommands);
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessParentCommands",
|
||||
[p, ns = mIdNamespace, cmds = std::move(mParentCommands)]() mutable {
|
||||
p->InProcessParentCommands(ns, std::move(cmds));
|
||||
}));
|
||||
} else {
|
||||
this->SendParentCommands(mIdNamespace, mParentCommands);
|
||||
}
|
||||
mParentCommands.Clear();
|
||||
}
|
||||
}
|
||||
@@ -379,7 +457,17 @@ void WebRenderBridgeChild::Connect(CompositableClient* aCompositable,
|
||||
mCompositables.InsertOrUpdate(uint64_t(handle), aCompositable);
|
||||
|
||||
aCompositable->InitIPDL(handle);
|
||||
SendNewCompositable(handle, aCompositable->GetTextureInfo());
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessNewCompositable",
|
||||
[p, handle, info = aCompositable->GetTextureInfo()]() mutable {
|
||||
p->InProcessNewCompositable(handle, info);
|
||||
}));
|
||||
} else {
|
||||
SendNewCompositable(handle, aCompositable->GetTextureInfo());
|
||||
}
|
||||
}
|
||||
|
||||
bool WebRenderBridgeChild::AddOpDestroy(const OpDestroy& aOp) {
|
||||
@@ -399,7 +487,15 @@ void WebRenderBridgeChild::ReleaseCompositable(
|
||||
return;
|
||||
}
|
||||
if (!DestroyInTransaction(aHandle)) {
|
||||
SendReleaseCompositable(aHandle);
|
||||
if (RefPtr<WebRenderBridgeParent> p =
|
||||
WebRenderBridgeParent::GetInProcess(wr::AsUint64(mPipelineId));
|
||||
p && CompositorThread()) {
|
||||
CompositorThread()->Dispatch(NS_NewRunnableFunction(
|
||||
"WRBridgeInProcessReleaseCompositable",
|
||||
[p, h = aHandle]() mutable { p->InProcessReleaseCompositable(h); }));
|
||||
} else {
|
||||
SendReleaseCompositable(aHandle);
|
||||
}
|
||||
}
|
||||
mCompositables.Remove(aHandle.Value());
|
||||
}
|
||||
|
||||
@@ -17,8 +17,14 @@
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/Range.h"
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/StaticPrefs_webgl.h"
|
||||
#include "mozilla/layers/PTextureParent.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "mozilla/ipc/SideVariant.h"
|
||||
#include "nsTHashMap.h"
|
||||
#include "prenv.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/GPUParent.h"
|
||||
@@ -349,6 +355,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(
|
||||
|
||||
mRemoteTextureTxnScheduler =
|
||||
RemoteTextureTxnScheduler::Create(aCompositorBridge);
|
||||
RegisterInProcess();
|
||||
}
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(
|
||||
@@ -376,6 +383,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(
|
||||
mLateInit->mAsyncImageManager->AddPipeline(mPipelineId, this);
|
||||
mRemoteTextureTxnScheduler =
|
||||
RemoteTextureTxnScheduler::Create(aCompositorBridge);
|
||||
RegisterInProcess();
|
||||
}
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(const wr::PipelineId& aPipelineId,
|
||||
@@ -400,6 +408,169 @@ WebRenderBridgeParent::~WebRenderBridgeParent() {
|
||||
wr::AsUint64(mPipelineId));
|
||||
}
|
||||
|
||||
// In-process direct-dispatch registry. The map owns a strong ref so a registered
|
||||
// parent is always alive for a lookup (no cross-thread refcount-revival race);
|
||||
// teardown removes it in Destroy(). Opt-in via GECKO_WR_DIRECT.
|
||||
static StaticMutex sWRBPRegistryMutex;
|
||||
static nsTHashMap<uint64_t, RefPtr<WebRenderBridgeParent>>* sWRBPRegistry =
|
||||
nullptr;
|
||||
|
||||
static bool WRDirectEnabled() {
|
||||
static const bool sEnabled = !!PR_GetEnv("GECKO_WR_DIRECT");
|
||||
return sEnabled;
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::RegisterInProcess() {
|
||||
if (!WRDirectEnabled()) {
|
||||
return;
|
||||
}
|
||||
static bool sLogged = false;
|
||||
if (!sLogged) {
|
||||
sLogged = true;
|
||||
printf("WR-DIRECT: in-process WebRender transaction path enabled\n");
|
||||
}
|
||||
StaticMutexAutoLock lock(sWRBPRegistryMutex);
|
||||
if (!sWRBPRegistry) {
|
||||
sWRBPRegistry = new nsTHashMap<uint64_t, RefPtr<WebRenderBridgeParent>>();
|
||||
}
|
||||
sWRBPRegistry->InsertOrUpdate(wr::AsUint64(mPipelineId), this);
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::UnregisterInProcess() {
|
||||
StaticMutexAutoLock lock(sWRBPRegistryMutex);
|
||||
if (sWRBPRegistry) {
|
||||
sWRBPRegistry->Remove(wr::AsUint64(mPipelineId));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<WebRenderBridgeParent> WebRenderBridgeParent::GetInProcess(
|
||||
uint64_t aPipelineId) {
|
||||
StaticMutexAutoLock lock(sWRBPRegistryMutex);
|
||||
if (!sWRBPRegistry) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<WebRenderBridgeParent> parent;
|
||||
sWRBPRegistry->Get(aPipelineId, &parent);
|
||||
return parent.forget();
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::XlateTexture(
|
||||
NotNull<ipc::SideVariant<PTextureParent*, PTextureChild*>>& aField) {
|
||||
if (aField.IsParent()) {
|
||||
return;
|
||||
}
|
||||
PTextureChild* child = aField.AsChild().get();
|
||||
IProtocol* actor = Lookup(child->Id());
|
||||
MOZ_ASSERT(actor, "in-process PTexture has no parent-side actor");
|
||||
if (!actor) {
|
||||
return;
|
||||
}
|
||||
ipc::SideVariant<PTextureParent*, PTextureChild*> sv;
|
||||
sv = static_cast<PTextureParent*>(actor);
|
||||
aField = WrapNotNull(sv);
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::TranslateActors(nsTArray<OpDestroy>& aOps) {
|
||||
for (auto& op : aOps) {
|
||||
if (op.type() == OpDestroy::TPTexture) {
|
||||
XlateTexture(op.get_PTexture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::TranslateActors(
|
||||
nsTArray<WebRenderParentCommand>& aCommands) {
|
||||
for (auto& cmd : aCommands) {
|
||||
if (cmd.type() != WebRenderParentCommand::TCompositableOperation) {
|
||||
continue;
|
||||
}
|
||||
auto& detail = cmd.get_CompositableOperation().detail();
|
||||
switch (detail.type()) {
|
||||
case CompositableOperationDetail::TOpRemoveTexture:
|
||||
XlateTexture(detail.get_OpRemoveTexture().texture());
|
||||
break;
|
||||
case CompositableOperationDetail::TOpUseTexture:
|
||||
for (auto& tt : detail.get_OpUseTexture().textures()) {
|
||||
XlateTexture(tt.texture());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::TranslateActors(
|
||||
nsTArray<OpUpdateResource>& aUpdates) {
|
||||
for (auto& up : aUpdates) {
|
||||
if (up.type() == OpUpdateResource::TOpPushExternalImageForTexture) {
|
||||
XlateTexture(up.get_OpPushExternalImageForTexture().texture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessUpdateResources(
|
||||
const wr::IdNamespace& aIdNamespace, nsTArray<OpUpdateResource>&& aUpdates,
|
||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||
nsTArray<ipc::Shmem>&& aLargeShmems) {
|
||||
TranslateActors(aUpdates);
|
||||
(void)RecvUpdateResources(aIdNamespace, std::move(aUpdates),
|
||||
std::move(aSmallShmems), std::move(aLargeShmems));
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessParentCommands(
|
||||
const wr::IdNamespace& aIdNamespace,
|
||||
nsTArray<WebRenderParentCommand>&& aCommands) {
|
||||
TranslateActors(aCommands);
|
||||
(void)RecvParentCommands(aIdNamespace, std::move(aCommands));
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessNewCompositable(
|
||||
const CompositableHandle& aHandle, const TextureInfo& aInfo) {
|
||||
(void)RecvNewCompositable(aHandle, aInfo);
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessReleaseCompositable(
|
||||
const CompositableHandle& aHandle) {
|
||||
(void)RecvReleaseCompositable(aHandle);
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessSetDisplayList(
|
||||
DisplayListData&& aDisplayList, nsTArray<OpDestroy>&& aToDestroy,
|
||||
uint64_t aFwdTransactionId, TransactionId aTransactionId,
|
||||
bool aContainsSVGGroup, VsyncId aVsyncId, TimeStamp aVsyncStartTime,
|
||||
TimeStamp aRefreshStartTime, TimeStamp aTxnStartTime, nsCString aTxnURL,
|
||||
TimeStamp aFwdTime, nsTArray<CompositionPayload>&& aPayloads,
|
||||
bool aRenderOffscreen) {
|
||||
TranslateActors(aToDestroy);
|
||||
TranslateActors(aDisplayList.mCommands);
|
||||
TranslateActors(aDisplayList.mResourceUpdates);
|
||||
(void)RecvSetDisplayList(
|
||||
std::move(aDisplayList), std::move(aToDestroy), aFwdTransactionId,
|
||||
aTransactionId, aContainsSVGGroup, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, aFwdTime, std::move(aPayloads),
|
||||
aRenderOffscreen);
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::InProcessEmptyTransaction(
|
||||
const FocusTarget& aFocusTarget, Maybe<TransactionData>&& aTransactionData,
|
||||
nsTArray<OpDestroy>&& aToDestroy, uint64_t aFwdTransactionId,
|
||||
TransactionId aTransactionId, VsyncId aVsyncId, TimeStamp aVsyncStartTime,
|
||||
TimeStamp aRefreshStartTime, TimeStamp aTxnStartTime, nsCString aTxnURL,
|
||||
TimeStamp aFwdTime, nsTArray<CompositionPayload>&& aPayloads) {
|
||||
TranslateActors(aToDestroy);
|
||||
if (aTransactionData) {
|
||||
TranslateActors(aTransactionData->mCommands);
|
||||
TranslateActors(aTransactionData->mResourceUpdates);
|
||||
}
|
||||
(void)RecvEmptyTransaction(aFocusTarget, std::move(aTransactionData),
|
||||
std::move(aToDestroy), aFwdTransactionId,
|
||||
aTransactionId, aVsyncId, aVsyncStartTime,
|
||||
aRefreshStartTime, aTxnStartTime, aTxnURL, aFwdTime,
|
||||
std::move(aPayloads));
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<WebRenderBridgeParent> WebRenderBridgeParent::CreateDestroyed(
|
||||
const wr::PipelineId& aPipelineId, nsCString&& aError) {
|
||||
@@ -534,6 +705,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::HandleShutdown() {
|
||||
}
|
||||
|
||||
void WebRenderBridgeParent::Destroy() {
|
||||
UnregisterInProcess();
|
||||
if (!EnsureInitialized()) {
|
||||
return;
|
||||
}
|
||||
@@ -1353,6 +1525,15 @@ bool WebRenderBridgeParent::ProcessDisplayListData(
|
||||
// Note that this needs to happen before the display list transaction is
|
||||
// sent to WebRender, so that the UpdateHitTestingTree call is guaranteed to
|
||||
// be in the updater queue at the time that the scene swap completes.
|
||||
{
|
||||
static int s_sdLog = 0;
|
||||
if (s_sdLog < 5) {
|
||||
s_sdLog++;
|
||||
printf("APZ-DIAG WRBP::SetDisplayList scrollData=%d\n",
|
||||
(int)(bool)aDisplayList.mScrollData);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
if (aDisplayList.mScrollData) {
|
||||
UpdateAPZScrollData(aWrEpoch, std::move(aDisplayList.mScrollData.ref()));
|
||||
}
|
||||
|
||||
@@ -199,6 +199,38 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
||||
|
||||
void Destroy();
|
||||
|
||||
// In-process direct dispatch: when the compositor is in this process, a
|
||||
// WebRenderBridgeChild hands the transaction's moved C++ payload straight to
|
||||
// the compositor thread instead of through IPDL (skipping Pickle
|
||||
// serialization). GetInProcess() finds the parent for a pipeline id; the
|
||||
// InProcess* methods run on the compositor thread, translate child-side actor
|
||||
// references (PTexture) to this side via Lookup(), then invoke the Recv path.
|
||||
// Opt-in: only populated when GECKO_WR_DIRECT is set in the environment.
|
||||
static already_AddRefed<WebRenderBridgeParent> GetInProcess(
|
||||
uint64_t aPipelineId);
|
||||
void InProcessUpdateResources(const wr::IdNamespace& aIdNamespace,
|
||||
nsTArray<OpUpdateResource>&& aUpdates,
|
||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||
nsTArray<ipc::Shmem>&& aLargeShmems);
|
||||
void InProcessParentCommands(const wr::IdNamespace& aIdNamespace,
|
||||
nsTArray<WebRenderParentCommand>&& aCommands);
|
||||
void InProcessNewCompositable(const CompositableHandle& aHandle,
|
||||
const TextureInfo& aInfo);
|
||||
void InProcessReleaseCompositable(const CompositableHandle& aHandle);
|
||||
void InProcessSetDisplayList(
|
||||
DisplayListData&& aDisplayList, nsTArray<OpDestroy>&& aToDestroy,
|
||||
uint64_t aFwdTransactionId, TransactionId aTransactionId,
|
||||
bool aContainsSVGGroup, VsyncId aVsyncId, TimeStamp aVsyncStartTime,
|
||||
TimeStamp aRefreshStartTime, TimeStamp aTxnStartTime, nsCString aTxnURL,
|
||||
TimeStamp aFwdTime, nsTArray<CompositionPayload>&& aPayloads,
|
||||
bool aRenderOffscreen);
|
||||
void InProcessEmptyTransaction(
|
||||
const FocusTarget& aFocusTarget, Maybe<TransactionData>&& aTransactionData,
|
||||
nsTArray<OpDestroy>&& aToDestroy, uint64_t aFwdTransactionId,
|
||||
TransactionId aTransactionId, VsyncId aVsyncId, TimeStamp aVsyncStartTime,
|
||||
TimeStamp aRefreshStartTime, TimeStamp aTxnStartTime, nsCString aTxnURL,
|
||||
TimeStamp aFwdTime, nsTArray<CompositionPayload>&& aPayloads);
|
||||
|
||||
// CompositorVsyncSchedulerOwner
|
||||
bool IsPendingComposite() override { return false; }
|
||||
void FinishPendingComposite() override {}
|
||||
@@ -400,6 +432,14 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
||||
void DeleteImage(const wr::ImageKey& aKey, wr::TransactionBuilder& aUpdates);
|
||||
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
|
||||
|
||||
void RegisterInProcess();
|
||||
void UnregisterInProcess();
|
||||
void XlateTexture(
|
||||
NotNull<ipc::SideVariant<PTextureParent*, PTextureChild*>>& aField);
|
||||
void TranslateActors(nsTArray<OpDestroy>& aOps);
|
||||
void TranslateActors(nsTArray<WebRenderParentCommand>& aCommands);
|
||||
void TranslateActors(nsTArray<OpUpdateResource>& aUpdates);
|
||||
|
||||
bool ProcessWebRenderParentCommands(
|
||||
const nsTArray<WebRenderParentCommand>& aCommands,
|
||||
wr::TransactionBuilder& aTxn);
|
||||
|
||||
@@ -3988,6 +3988,16 @@ bool gfxPlatform::UseDesktopZoomingScrollbars() {
|
||||
|
||||
/*static*/
|
||||
bool gfxPlatform::AsyncPanZoomEnabled() {
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// The wasm embedding is single-process (no e10s) but runs an in-process
|
||||
// WebRender compositor. The layers.async-pan-zoom.enabled pref defaults to true
|
||||
// (and is mirror:once, so a late runtime SetBool can't reliably disable it), and
|
||||
// the e10s/Fission gates below would also force it on -- so gate APZ directly on
|
||||
// the GECKO_APZ env var instead. Cleanly opt-in: default OFF -> the correct
|
||||
// layout-hit-test scroll path (APZ-on currently mis-targets nested scroll
|
||||
// containers because subframe displayports aren't activated -- see embed-input).
|
||||
return getenv("GECKO_APZ") != nullptr;
|
||||
#endif
|
||||
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_UIKIT)
|
||||
// For XUL applications (everything but Firefox on Android)
|
||||
// we only want to use APZ when E10S is enabled. If
|
||||
|
||||
@@ -892,8 +892,17 @@ void RenderThread::UpdateAndRender(
|
||||
// and for avoiding GPU queue is filled with too much tasks.
|
||||
// WaitForGPU's implementation is different for each platform.
|
||||
auto timerId = glean::wr::gpu_wait_time.Start();
|
||||
TimeStamp gpuS = TimeStamp::Now();
|
||||
renderer->WaitForGPU();
|
||||
double gpuWaitMs = (TimeStamp::Now() - gpuS).ToMilliseconds();
|
||||
glean::wr::gpu_wait_time.StopAndAccumulate(std::move(timerId));
|
||||
static int s_renderDiag = 0;
|
||||
if (s_renderDiag < 40) {
|
||||
s_renderDiag++;
|
||||
printf("RENDER-DIAG renderCPU=%.1fms gpuWait=%.1fms\n",
|
||||
(end - start).ToMilliseconds(), gpuWaitMs);
|
||||
fflush(stdout);
|
||||
}
|
||||
} else {
|
||||
// Update frame id for NotifyPipelinesUpdated() when rendering does not
|
||||
// happen, either because rendering was not requested or the frame was
|
||||
|
||||
@@ -3048,6 +3048,18 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
||||
(void)rootScrollContainerFrame->DecideScrollableLayer(
|
||||
builder, &displayPortBase, &temp,
|
||||
/* aSetBase = */ true);
|
||||
static int s_dpRoot = 0;
|
||||
if (s_dpRoot < 6) {
|
||||
s_dpRoot++;
|
||||
printf(
|
||||
"APZ-DIAG root paint: paintingToWindow=%d apzEnabled=%d "
|
||||
"rootHasDisplayPort=%d\n",
|
||||
(int)builder->IsPaintingToWindow(),
|
||||
(int)nsLayoutUtils::AsyncPanZoomEnabled(aFrame),
|
||||
(int)DisplayPortUtils::HasDisplayPort(
|
||||
rootScrollContainerFrame->GetContent()));
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// In the case where we use APZ for the given popup frame, we need to set the
|
||||
|
||||
@@ -296,6 +296,17 @@ nsIWidget::ContentAndAPZEventStatus PuppetWidget::DispatchInputEvent(
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// Single-process wasm: APZ is wired LOCALLY on this widget (mAPZC, via the
|
||||
// in-process compositor) and there is no mBrowserChild to forward input to.
|
||||
// Use the base-class APZ routing (mAPZC->InputBridge()->ReceiveInputEvent +
|
||||
// ProcessUntransformedAPZEvent) instead of the remote SendDispatch* path below,
|
||||
// which would otherwise drop the event here (mBrowserChild is null).
|
||||
if (mAPZC && !mBrowserChild) {
|
||||
return nsIWidget::DispatchInputEvent(aEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mBrowserChild) {
|
||||
return status;
|
||||
}
|
||||
@@ -493,6 +504,17 @@ void PuppetWidget::UpdateZoomConstraints(
|
||||
}
|
||||
|
||||
bool PuppetWidget::AsyncPanZoomEnabled() const {
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// Single-process wasm: the in-process compositor (GetWindowRenderer ->
|
||||
// CreateCompositor) wires an APZCTreeManager directly on this widget (mAPZC),
|
||||
// so report APZ enabled when it is present. mBrowserChild is null here, so the
|
||||
// default IPC-based check below would otherwise always return false -- which
|
||||
// also suppresses WebRenderLayerManager sending scroll data (no hit-testing
|
||||
// tree for APZ) and routes wheel input around APZ.
|
||||
if (mAPZC) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return mBrowserChild && mBrowserChild->AsyncPanZoomEnabled();
|
||||
}
|
||||
|
||||
|
||||
@@ -1108,6 +1108,20 @@ nsEventStatus nsIWidget::ProcessUntransformedAPZEvent(
|
||||
UniquePtr<WidgetEvent> original(aEvent->Duplicate());
|
||||
nsEventStatus status = DispatchEvent(aEvent);
|
||||
|
||||
if (aEvent->AsWheelEvent()) {
|
||||
static int s_tgt = 0;
|
||||
if (s_tgt < 20) {
|
||||
s_tgt++;
|
||||
printf(
|
||||
"APZ-TGT: mAPZC=%d routed=%d dropped=%d inputBlockId=%llu "
|
||||
"apzEventState=%d\n",
|
||||
(int)!!mAPZC, (int)InputAPZContext::WasRoutedToChildProcess(),
|
||||
(int)InputAPZContext::WasDropped(),
|
||||
(unsigned long long)inputBlockId, (int)!!mAPZEventState);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (mAPZC && !InputAPZContext::WasRoutedToChildProcess() &&
|
||||
!InputAPZContext::WasDropped() && inputBlockId) {
|
||||
// EventStateManager did not route the event into the child process and
|
||||
@@ -1417,6 +1431,18 @@ Document* nsIWidget::GetDocument() const {
|
||||
return presShell->GetDocument();
|
||||
}
|
||||
}
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// Windowless content (PuppetWidget) attaches its PresShell via the ATTACHED
|
||||
// widget listener, not mWidgetListener, so the base lookup returns null. Fall
|
||||
// back to it -- otherwise APZ's SetTargetAPZC subframe-activation no-ops (no
|
||||
// document), nested overflow:scroll containers never get an APZC, and APZ
|
||||
// mis-targets the root. See gfxPlatform::AsyncPanZoomEnabled / embed-input.
|
||||
if (mAttachedWidgetListener) {
|
||||
if (PresShell* presShell = mAttachedWidgetListener->GetPresShell()) {
|
||||
return presShell->GetDocument();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user