Bug 1569258 - Ensure we have a CompositionRecorder before attempting to write frames r=kvark,mstange

Instead of blindly attempting to write frames to disk, we now ensure that the
`CompositionRecorder` exists. In the case where we have not allocated one,
calling `windowUtils.setCompositionRecording(false)` will instead print an
error message to the browser console.

In addition, attempting to call `windowUtils.setCompositionRecording(true)`
while a `CompositionRecorder` exists will also result in an error message.

Differential Revision: https://phabricator.services.mozilla.com/D39584

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Barret Rennie 2019-07-31 20:21:03 +00:00
parent 7bc070b022
commit 0ea4a2cbed
6 changed files with 86 additions and 12 deletions

View File

@ -115,6 +115,7 @@
#include "mozilla/PreloadedStyleSheet.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/ResultExtensions.h"
#ifdef XP_WIN
# undef GetClassName
@ -4103,14 +4104,60 @@ NS_IMETHODIMP
nsDOMWindowUtils::SetCompositionRecording(bool aValue) {
if (CompositorBridgeChild* cbc = GetCompositorBridge()) {
if (aValue) {
cbc->SendBeginRecording(TimeStamp::Now());
RefPtr<nsDOMWindowUtils> self = this;
cbc->SendBeginRecording(TimeStamp::Now())
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[self](const bool& aSuccess) {
if (!aSuccess) {
self->ReportErrorMessageForWindow(
NS_LITERAL_STRING(
"The composition recorder is already running."),
"DOM", true);
}
},
[self](const mozilla::ipc::ResponseRejectReason&) {
self->ReportErrorMessageForWindow(
NS_LITERAL_STRING(
"Could not start the composition recorder."),
"DOM", true);
});
} else {
cbc->SendEndRecording();
bool success = false;
if (!cbc->SendEndRecording(&success)) {
ReportErrorMessageForWindow(
NS_LITERAL_STRING("Could not stop the composition recorder."),
"DOM", true);
} else if (!success) {
ReportErrorMessageForWindow(
NS_LITERAL_STRING("The composition recorder is not running."),
"DOM", true);
}
}
}
return NS_OK;
}
void nsDOMWindowUtils::ReportErrorMessageForWindow(
const nsAString& aErrorMessage, const char* aClassification,
bool aFromChrome) {
bool isPrivateWindow = false;
if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow)) {
if (nsIPrincipal* principal =
nsGlobalWindowOuter::Cast(window)->GetPrincipal()) {
uint32_t privateBrowsingId = 0;
if (NS_SUCCEEDED(principal->GetPrivateBrowsingId(&privateBrowsingId))) {
isPrivateWindow = !!privateBrowsingId;
}
}
}
nsContentUtils::LogSimpleConsoleError(aErrorMessage, aClassification,
isPrivateWindow, aFromChrome);
}
NS_IMETHODIMP
nsDOMWindowUtils::SetSystemFont(const nsACString& aFontName) {
nsIWidget* widget = GetWidget();

View File

@ -101,6 +101,10 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils,
const nsTArray<float>& aRotationAngles, const nsTArray<float>& aForces,
int32_t aModifiers, bool aIgnoreRootScrollFrame, bool aToWindow,
bool* aPreventDefault);
void ReportErrorMessageForWindow(const nsAString& aErrorMessage,
const char* aClassification,
bool aFromChrome);
};
#endif

View File

@ -2612,7 +2612,12 @@ int32_t RecordContentFrameTime(
}
mozilla::ipc::IPCResult CompositorBridgeParent::RecvBeginRecording(
const TimeStamp& aRecordingStart) {
const TimeStamp& aRecordingStart, BeginRecordingResolver&& aResolve) {
if (mCompositionRecorder) {
aResolve(false);
return IPC_OK();
}
if (mLayerManager) {
mCompositionRecorder = new CompositionRecorder(aRecordingStart);
mLayerManager->SetCompositionRecorder(do_AddRef(mCompositionRecorder));
@ -2624,10 +2629,17 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvBeginRecording(
mWrBridge->SetCompositionRecorder(std::move(recorder));
}
aResolve(true);
return IPC_OK();
}
mozilla::ipc::IPCResult CompositorBridgeParent::RecvEndRecording() {
mozilla::ipc::IPCResult CompositorBridgeParent::RecvEndRecording(
bool* aOutSuccess) {
if (!mCompositionRecorder) {
*aOutSuccess = false;
return IPC_OK();
}
if (mLayerManager) {
mLayerManager->SetCompositionRecorder(nullptr);
}
@ -2638,6 +2650,7 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvEndRecording() {
mCompositionRecorder->WriteCollectedFrames();
mCompositionRecorder = nullptr;
*aOutSuccess = true;
return IPC_OK();
}

View File

@ -245,8 +245,8 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
virtual mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() = 0;
virtual mozilla::ipc::IPCResult RecvAllPluginsCaptured() = 0;
virtual mozilla::ipc::IPCResult RecvBeginRecording(
const TimeStamp& aRecordingStart) = 0;
virtual mozilla::ipc::IPCResult RecvEndRecording() = 0;
const TimeStamp& aRecordingStart, BeginRecordingResolver&& aResolve) = 0;
virtual mozilla::ipc::IPCResult RecvEndRecording(bool* aOutSuccess) = 0;
virtual mozilla::ipc::IPCResult RecvInitialize(
const LayersId& rootLayerTreeId) = 0;
virtual mozilla::ipc::IPCResult RecvGetFrameUniformity(
@ -357,8 +357,9 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
mozilla::ipc::IPCResult RecvAllPluginsCaptured() override;
mozilla::ipc::IPCResult RecvBeginRecording(
const TimeStamp& aRecordingStart) override;
mozilla::ipc::IPCResult RecvEndRecording() override;
const TimeStamp& aRecordingStart,
BeginRecordingResolver&& aResolve) override;
mozilla::ipc::IPCResult RecvEndRecording(bool* aOutSuccess) override;
void NotifyMemoryPressure() override;
void AccumulateMemoryReport(wr::MemoryReport*) override;

View File

@ -87,10 +87,16 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
mozilla::ipc::IPCResult RecvAllPluginsCaptured() override { return IPC_OK(); }
mozilla::ipc::IPCResult RecvBeginRecording(
const TimeStamp& aRecordingStart) override {
const TimeStamp& aRecordingStart,
BeginRecordingResolver&& aResolve) override {
aResolve(false);
return IPC_OK();
}
mozilla::ipc::IPCResult RecvEndRecording(bool* aOutSuccess) override {
*aOutSuccess = false;
return IPC_OK();
}
mozilla::ipc::IPCResult RecvEndRecording() override { return IPC_OK(); }
mozilla::ipc::IPCResult RecvGetFrameUniformity(
FrameUniformityData* aOutData) override {

View File

@ -267,8 +267,11 @@ parent:
sync CheckContentOnlyTDR(uint32_t sequenceNum)
returns (bool isContentOnlyTDR);
async BeginRecording(TimeStamp aRecordingStart);
sync EndRecording();
async BeginRecording(TimeStamp aRecordingStart)
returns (bool success);
sync EndRecording()
returns (bool success);
child:
// Send back Compositor Frame Metrics from APZCs so tiled layers can