WebRenderBridgeChild.cpp (20135B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/layers/WebRenderBridgeChild.h" 8 9 #include "gfxPlatform.h" 10 #include "mozilla/StaticPrefs_gfx.h" 11 #include "mozilla/layers/CompositableClient.h" 12 #include "mozilla/layers/CompositorBridgeChild.h" 13 #include "mozilla/layers/CompositorManagerChild.h" 14 #include "mozilla/layers/ImageDataSerializer.h" 15 #include "mozilla/layers/IpcResourceUpdateQueue.h" 16 #include "mozilla/layers/StackingContextHelper.h" 17 #include "mozilla/layers/PTextureChild.h" 18 #include "mozilla/layers/WebRenderLayerManager.h" 19 #include "mozilla/webrender/WebRenderAPI.h" 20 #include "PDMFactory.h" 21 22 namespace mozilla { 23 namespace layers { 24 25 using namespace mozilla::gfx; 26 27 WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId) 28 : mIsInTransaction(false), 29 mIsInClearCachedResources(false), 30 mIdNamespace{0}, 31 mResourceId(0), 32 mPipelineId(aPipelineId), 33 mManager(nullptr), 34 mIPCOpen(false), 35 mDestroyed(false), 36 mSentDisplayList(false), 37 mFontKeysDeleted(0), 38 mFontInstanceKeysDeleted(0) {} 39 40 WebRenderBridgeChild::~WebRenderBridgeChild() { 41 MOZ_ASSERT(NS_IsMainThread()); 42 MOZ_ASSERT(mDestroyed); 43 } 44 45 void WebRenderBridgeChild::Destroy(bool aIsSync) { 46 if (!IPCOpen()) { 47 return; 48 } 49 50 DoDestroy(); 51 52 if (aIsSync) { 53 SendShutdownSync(); 54 } else { 55 SendShutdown(); 56 } 57 } 58 59 void WebRenderBridgeChild::ActorDestroy(ActorDestroyReason why) { DoDestroy(); } 60 61 void WebRenderBridgeChild::DoDestroy() { 62 if (RefCountedShm::IsValid(mResourceShm) && 63 RefCountedShm::Release(mResourceShm) == 0) { 64 RefCountedShm::Dealloc(this, mResourceShm); 65 mResourceShm = RefCountedShmem(); 66 } 67 68 // mDestroyed is used to prevent calling Send__delete__() twice. 69 // When this function is called from CompositorBridgeChild::Destroy(). 70 mDestroyed = true; 71 mManager = nullptr; 72 } 73 74 void WebRenderBridgeChild::AddWebRenderParentCommand( 75 const WebRenderParentCommand& aCmd) { 76 mParentCommands.AppendElement(aCmd); 77 } 78 79 void WebRenderBridgeChild::AddWebRenderParentDestroyCommand( 80 const WebRenderParentCommand& aCmd) { 81 mParentDestroyCommands.AppendElement(aCmd); 82 } 83 84 void WebRenderBridgeChild::MergeWebRenderParentCommands() { 85 mParentCommands.AppendElements(std::move(mParentDestroyCommands)); 86 mParentDestroyCommands.Clear(); 87 } 88 89 void WebRenderBridgeChild::BeginTransaction() { 90 MOZ_ASSERT(!mDestroyed); 91 92 UpdateFwdTransactionId(); 93 mIsInTransaction = true; 94 } 95 96 void WebRenderBridgeChild::UpdateResources( 97 wr::IpcResourceUpdateQueue& aResources) { 98 if (!IPCOpen()) { 99 aResources.Clear(); 100 return; 101 } 102 103 if (aResources.IsEmpty()) { 104 return; 105 } 106 107 nsTArray<OpUpdateResource> resourceUpdates; 108 nsTArray<RefCountedShmem> smallShmems; 109 nsTArray<ipc::Shmem> largeShmems; 110 aResources.Flush(resourceUpdates, smallShmems, largeShmems); 111 112 this->SendUpdateResources(mIdNamespace, resourceUpdates, smallShmems, 113 std::move(largeShmems)); 114 } 115 116 bool WebRenderBridgeChild::EndTransaction( 117 DisplayListData&& aDisplayListData, TransactionId aTransactionId, 118 bool aContainsSVGGroup, const mozilla::VsyncId& aVsyncId, 119 bool aRenderOffscreen, const mozilla::TimeStamp& aVsyncStartTime, 120 const mozilla::TimeStamp& aRefreshStartTime, 121 const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxnURL) { 122 MOZ_ASSERT(!mDestroyed); 123 MOZ_ASSERT(mIsInTransaction); 124 125 TimeStamp fwdTime = TimeStamp::Now(); 126 127 if (!aRenderOffscreen) { 128 MergeWebRenderParentCommands(); 129 } 130 aDisplayListData.mCommands = std::move(mParentCommands); 131 aDisplayListData.mIdNamespace = mIdNamespace; 132 133 nsTArray<CompositionPayload> payloads; 134 if (mManager) { 135 mManager->TakeCompositionPayloads(payloads); 136 } 137 138 mSentDisplayList = true; 139 bool ret = this->SendSetDisplayList( 140 std::move(aDisplayListData), mDestroyedActors, GetFwdTransactionId(), 141 aTransactionId, aContainsSVGGroup, aVsyncId, aVsyncStartTime, 142 aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads, 143 aRenderOffscreen); 144 145 // With multiple render roots, we may not have sent all of our 146 // mParentCommands, so go ahead and go through our mParentCommands and ensure 147 // they get sent. 148 ProcessWebRenderParentCommands(); 149 mDestroyedActors.Clear(); 150 mIsInTransaction = false; 151 152 return ret; 153 } 154 155 void WebRenderBridgeChild::EndEmptyTransaction( 156 const FocusTarget& aFocusTarget, Maybe<TransactionData>&& aTransactionData, 157 TransactionId aTransactionId, const mozilla::VsyncId& aVsyncId, 158 const mozilla::TimeStamp& aVsyncStartTime, 159 const mozilla::TimeStamp& aRefreshStartTime, 160 const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxnURL) { 161 MOZ_ASSERT(!mDestroyed); 162 MOZ_ASSERT(mIsInTransaction); 163 164 TimeStamp fwdTime = TimeStamp::Now(); 165 166 if (aTransactionData) { 167 MergeWebRenderParentCommands(); 168 aTransactionData->mCommands = std::move(mParentCommands); 169 } 170 171 nsTArray<CompositionPayload> payloads; 172 if (mManager) { 173 mManager->TakeCompositionPayloads(payloads); 174 } 175 176 this->SendEmptyTransaction( 177 aFocusTarget, std::move(aTransactionData), mDestroyedActors, 178 GetFwdTransactionId(), aTransactionId, aVsyncId, aVsyncStartTime, 179 aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads); 180 181 // With multiple render roots, we may not have sent all of our 182 // mParentCommands, so go ahead and go through our mParentCommands and ensure 183 // they get sent. 184 ProcessWebRenderParentCommands(); 185 mDestroyedActors.Clear(); 186 mIsInTransaction = false; 187 } 188 189 void WebRenderBridgeChild::ProcessWebRenderParentCommands() { 190 MOZ_ASSERT(!mDestroyed); 191 192 if (HasWebRenderParentCommands()) { 193 MergeWebRenderParentCommands(); 194 this->SendParentCommands(mIdNamespace, mParentCommands); 195 mParentCommands.Clear(); 196 } 197 } 198 199 void WebRenderBridgeChild::AddPipelineIdForCompositable( 200 const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle, 201 CompositableHandleOwner aOwner) { 202 AddWebRenderParentCommand( 203 OpAddPipelineIdForCompositable(aPipelineId, aHandle, aOwner)); 204 } 205 206 void WebRenderBridgeChild::RemovePipelineIdForCompositable( 207 const wr::PipelineId& aPipelineId) { 208 AddWebRenderParentDestroyCommand( 209 OpRemovePipelineIdForCompositable(aPipelineId)); 210 } 211 212 wr::ExternalImageId WebRenderBridgeChild::GetNextExternalImageId() { 213 wr::MaybeExternalImageId id = 214 GetCompositorBridgeChild()->GetNextExternalImageId(); 215 MOZ_RELEASE_ASSERT(id.isSome()); 216 return id.value(); 217 } 218 219 void WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey) { 220 AddWebRenderParentDestroyCommand(OpReleaseTextureOfImage(aKey)); 221 } 222 223 struct FontFileDataSink { 224 wr::FontKey* mFontKey; 225 WebRenderBridgeChild* mWrBridge; 226 wr::IpcResourceUpdateQueue* mResources; 227 }; 228 229 static void WriteFontFileData(const uint8_t* aData, uint32_t aLength, 230 uint32_t aIndex, void* aBaton) { 231 FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton); 232 233 *sink->mFontKey = sink->mWrBridge->GetNextFontKey(); 234 235 sink->mResources->AddRawFont( 236 *sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), 237 aIndex); 238 } 239 240 static void WriteFontDescriptor(const uint8_t* aData, uint32_t aLength, 241 uint32_t aIndex, void* aBaton) { 242 FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton); 243 244 *sink->mFontKey = sink->mWrBridge->GetNextFontKey(); 245 246 sink->mResources->AddFontDescriptor( 247 *sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), 248 aIndex); 249 } 250 251 void WebRenderBridgeChild::PushGlyphs( 252 wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources, 253 Range<const wr::GlyphInstance> aGlyphs, gfx::ScaledFont* aFont, 254 const wr::ColorF& aColor, const StackingContextHelper& aSc, 255 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 256 bool aBackfaceVisible, const wr::GlyphOptions* aGlyphOptions) { 257 MOZ_ASSERT(aFont); 258 259 Maybe<wr::WrFontInstanceKey> key = GetFontKeyForScaledFont(aFont, aResources); 260 MOZ_ASSERT(key.isSome()); 261 262 if (key.isSome()) { 263 aBuilder.PushText(aBounds, aClip, aBackfaceVisible, aColor, key.value(), 264 aGlyphs, aGlyphOptions); 265 } 266 } 267 268 Maybe<wr::FontInstanceKey> WebRenderBridgeChild::GetFontKeyForScaledFont( 269 gfx::ScaledFont* aScaledFont, wr::IpcResourceUpdateQueue& aResources) { 270 MOZ_ASSERT(!mDestroyed); 271 MOZ_ASSERT(aScaledFont); 272 MOZ_ASSERT(aScaledFont->CanSerialize()); 273 274 return mFontInstanceKeys.WithEntryHandle( 275 aScaledFont, [&](auto&& entry) -> Maybe<wr::FontInstanceKey> { 276 if (!entry) { 277 Maybe<wr::FontKey> fontKey = GetFontKeyForUnscaledFont( 278 aScaledFont->GetUnscaledFont(), aResources); 279 if (fontKey.isNothing()) { 280 return Nothing(); 281 } 282 283 wr::FontInstanceKey instanceKey = GetNextFontInstanceKey(); 284 285 Maybe<wr::FontInstanceOptions> options; 286 Maybe<wr::FontInstancePlatformOptions> platformOptions; 287 std::vector<FontVariation> variations; 288 aScaledFont->GetWRFontInstanceOptions(&options, &platformOptions, 289 &variations); 290 291 aResources.AddFontInstance( 292 instanceKey, fontKey.value(), aScaledFont->GetSize(), 293 options.ptrOr(nullptr), platformOptions.ptrOr(nullptr), 294 Range<const FontVariation>(variations.data(), variations.size())); 295 296 entry.Insert(instanceKey); 297 } 298 299 return Some(*entry); 300 }); 301 } 302 303 Maybe<wr::FontKey> WebRenderBridgeChild::GetFontKeyForUnscaledFont( 304 gfx::UnscaledFont* aUnscaled, wr::IpcResourceUpdateQueue& aResources) { 305 MOZ_ASSERT(!mDestroyed); 306 307 return mFontKeys.WithEntryHandle( 308 aUnscaled, [&](auto&& entry) -> Maybe<wr::FontKey> { 309 if (!entry) { 310 wr::FontKey fontKey = {wr::IdNamespace{0}, 0}; 311 FontFileDataSink sink = {&fontKey, this, &aResources}; 312 // First try to retrieve a descriptor for the font, as this is much 313 // cheaper to send over IPC than the full raw font data. If this is 314 // not possible, then and only then fall back to getting the raw font 315 // file data. If that fails, then the only thing left to do is signal 316 // failure by returning a null font key. 317 if (!aUnscaled->GetFontDescriptor(WriteFontDescriptor, &sink) && 318 !aUnscaled->GetFontFileData(WriteFontFileData, &sink)) { 319 return Nothing(); 320 } 321 322 entry.Insert(fontKey); 323 } 324 325 return Some(*entry); 326 }); 327 } 328 329 void WebRenderBridgeChild::RemoveExpiredFontKeys( 330 wr::IpcResourceUpdateQueue& aResourceUpdates) { 331 uint32_t counter = gfx::ScaledFont::DeletionCounter(); 332 if (mFontInstanceKeysDeleted != counter) { 333 mFontInstanceKeysDeleted = counter; 334 for (auto iter = mFontInstanceKeys.Iter(); !iter.Done(); iter.Next()) { 335 if (!iter.Key()) { 336 aResourceUpdates.DeleteFontInstance(iter.Data()); 337 iter.Remove(); 338 } 339 } 340 } 341 counter = gfx::UnscaledFont::DeletionCounter(); 342 if (mFontKeysDeleted != counter) { 343 mFontKeysDeleted = counter; 344 for (auto iter = mFontKeys.Iter(); !iter.Done(); iter.Next()) { 345 if (!iter.Key()) { 346 aResourceUpdates.DeleteFont(iter.Data()); 347 iter.Remove(); 348 } 349 } 350 } 351 } 352 353 CompositorBridgeChild* WebRenderBridgeChild::GetCompositorBridgeChild() { 354 if (!IPCOpen()) { 355 return nullptr; 356 } 357 return static_cast<CompositorBridgeChild*>(Manager()); 358 } 359 360 TextureForwarder* WebRenderBridgeChild::GetTextureForwarder() { 361 return static_cast<TextureForwarder*>(GetCompositorBridgeChild()); 362 } 363 364 LayersIPCActor* WebRenderBridgeChild::GetLayersIPCActor() { 365 return static_cast<LayersIPCActor*>(GetCompositorBridgeChild()); 366 } 367 368 void WebRenderBridgeChild::SyncWithCompositor( 369 const Maybe<uint64_t>& aWindowID) { 370 if (!IPCOpen()) { 371 return; 372 } 373 SendSyncWithCompositor(); 374 } 375 376 void WebRenderBridgeChild::Connect(CompositableClient* aCompositable, 377 ImageContainer* aImageContainer) { 378 MOZ_ASSERT(!mDestroyed); 379 MOZ_ASSERT(aCompositable); 380 381 CompositableHandle handle = CompositableHandle::GetNext(); 382 mCompositables.InsertOrUpdate(uint64_t(handle), aCompositable); 383 384 aCompositable->InitIPDL(handle); 385 SendNewCompositable(handle, aCompositable->GetTextureInfo()); 386 } 387 388 bool WebRenderBridgeChild::AddOpDestroy(const OpDestroy& aOp) { 389 if (!mIsInTransaction) { 390 return false; 391 } 392 393 mDestroyedActors.AppendElement(aOp); 394 return true; 395 } 396 397 void WebRenderBridgeChild::ReleaseCompositable( 398 const CompositableHandle& aHandle) { 399 if (!IPCOpen()) { 400 // This can happen if the IPC connection was torn down, because, e.g. 401 // the GPU process died. 402 return; 403 } 404 if (!DestroyInTransaction(aHandle)) { 405 SendReleaseCompositable(aHandle); 406 } 407 mCompositables.Remove(aHandle.Value()); 408 } 409 410 bool WebRenderBridgeChild::DestroyInTransaction(PTextureChild* aTexture) { 411 return AddOpDestroy(OpDestroy(WrapNotNull(aTexture))); 412 } 413 414 bool WebRenderBridgeChild::DestroyInTransaction( 415 const CompositableHandle& aHandle) { 416 return AddOpDestroy(OpDestroy(aHandle)); 417 } 418 419 void WebRenderBridgeChild::RemoveTextureFromCompositable( 420 CompositableClient* aCompositable, TextureClient* aTexture) { 421 MOZ_ASSERT(aCompositable); 422 MOZ_ASSERT(aTexture); 423 MOZ_ASSERT(aTexture->GetIPDLActor()); 424 MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == 425 GetIPCChannel()); 426 if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) { 427 // We don't have an actor anymore, don't try to use it! 428 return; 429 } 430 431 AddWebRenderParentDestroyCommand(CompositableOperation( 432 aCompositable->GetIPCHandle(), 433 OpRemoveTexture(WrapNotNull(aTexture->GetIPDLActor())))); 434 } 435 436 void WebRenderBridgeChild::UseTextures( 437 CompositableClient* aCompositable, 438 const nsTArray<TimedTextureClient>& aTextures) { 439 MOZ_ASSERT(aCompositable); 440 441 if (!aCompositable->IsConnected()) { 442 return; 443 } 444 445 AutoTArray<TimedTexture, 4> textures; 446 447 for (auto& t : aTextures) { 448 MOZ_ASSERT(t.mTextureClient); 449 MOZ_ASSERT(t.mTextureClient->GetIPDLActor()); 450 MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == 451 GetIPCChannel()); 452 bool readLocked = t.mTextureClient->OnForwardedToHost(); 453 454 textures.AppendElement(TimedTexture( 455 WrapNotNull(t.mTextureClient->GetIPDLActor()), t.mTimeStamp, 456 t.mPictureRect, t.mFrameID, t.mProducerID, readLocked)); 457 GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary( 458 t.mTextureClient); 459 } 460 AddWebRenderParentCommand(CompositableOperation(aCompositable->GetIPCHandle(), 461 OpUseTexture(textures))); 462 } 463 464 void WebRenderBridgeChild::UseRemoteTexture( 465 CompositableClient* aCompositable, const RemoteTextureId aTextureId, 466 const RemoteTextureOwnerId aOwnerId, const gfx::IntSize aSize, 467 const TextureFlags aFlags, const RefPtr<FwdTransactionTracker>& aTracker) { 468 AddWebRenderParentCommand(CompositableOperation( 469 aCompositable->GetIPCHandle(), 470 OpUseRemoteTexture(aTextureId, aOwnerId, aSize, aFlags))); 471 TrackFwdTransaction(aTracker); 472 } 473 474 FwdTransactionCounter& WebRenderBridgeChild::GetFwdTransactionCounter() { 475 return GetCompositorBridgeChild()->GetFwdTransactionCounter(); 476 } 477 478 bool WebRenderBridgeChild::InForwarderThread() { return NS_IsMainThread(); } 479 480 mozilla::ipc::IPCResult WebRenderBridgeChild::RecvWrUpdated( 481 const wr::IdNamespace& aNewIdNamespace, 482 const TextureFactoryIdentifier& textureFactoryIdentifier) { 483 if (mManager) { 484 mManager->WrUpdated(); 485 } 486 IdentifyTextureHost(textureFactoryIdentifier); 487 // Update mIdNamespace to identify obsolete keys and messages by 488 // WebRenderBridgeParent. Since usage of invalid keys could cause crash in 489 // webrender. 490 mIdNamespace = aNewIdNamespace; 491 // Just clear FontInstaceKeys/FontKeys, they are removed during WebRenderAPI 492 // destruction. 493 mFontInstanceKeys.Clear(); 494 mFontKeys.Clear(); 495 return IPC_OK(); 496 } 497 498 mozilla::ipc::IPCResult WebRenderBridgeChild::RecvWrReleasedImages( 499 nsTArray<wr::ExternalImageKeyPair>&& aPairs) { 500 if (mManager) { 501 mManager->WrReleasedImages(aPairs); 502 } 503 return IPC_OK(); 504 } 505 506 void WebRenderBridgeChild::BeginClearCachedResources() { 507 mSentDisplayList = false; 508 mIsInClearCachedResources = true; 509 // Clear display list and animations at parent side before clearing cached 510 // resources on client side. It prevents to clear resources before clearing 511 // display list at parent side. 512 SendClearCachedResources(); 513 } 514 515 void WebRenderBridgeChild::EndClearCachedResources() { 516 if (!IPCOpen()) { 517 mIsInClearCachedResources = false; 518 return; 519 } 520 ProcessWebRenderParentCommands(); 521 mIsInClearCachedResources = false; 522 } 523 524 void WebRenderBridgeChild::SetWebRenderLayerManager( 525 WebRenderLayerManager* aManager) { 526 MOZ_ASSERT(aManager && !mManager); 527 MOZ_ASSERT(NS_IsMainThread() || !XRE_IsContentProcess()); 528 mManager = aManager; 529 } 530 531 ipc::IShmemAllocator* WebRenderBridgeChild::GetShmemAllocator() { 532 if (!IPCOpen()) { 533 return nullptr; 534 } 535 return static_cast<CompositorBridgeChild*>(Manager()); 536 } 537 538 RefPtr<KnowsCompositor> WebRenderBridgeChild::GetForMedia() { 539 MOZ_ASSERT(NS_IsMainThread()); 540 541 // Ensure device initialization for video playback unless they are all remote. 542 // The devices are lazily initialized with WebRender to reduce memory usage. 543 if (!PDMFactory::AllDecodersAreRemote()) { 544 gfxPlatform::GetPlatform()->EnsureDevicesInitialized(); 545 } 546 547 return MakeAndAddRef<KnowsCompositorMediaProxy>( 548 GetTextureFactoryIdentifier()); 549 } 550 551 bool WebRenderBridgeChild::AllocResourceShmem(size_t aSize, 552 RefCountedShmem& aShm) { 553 // We keep a single shmem around to reuse later if it is reference count has 554 // dropped back to 1 (the reference held by the WebRenderBridgeChild). 555 556 // If the cached shmem exists, has the correct size and isn't held by anything 557 // other than us, recycle it. 558 bool alreadyAllocated = RefCountedShm::IsValid(mResourceShm); 559 if (alreadyAllocated) { 560 if (RefCountedShm::GetSize(mResourceShm) == aSize && 561 RefCountedShm::GetReferenceCount(mResourceShm) <= 1) { 562 MOZ_ASSERT(RefCountedShm::GetReferenceCount(mResourceShm) == 1); 563 aShm = mResourceShm; 564 return true; 565 } 566 } 567 568 // If there was no cached shmem or we couldn't recycle it, alloc a new one. 569 if (!RefCountedShm::Alloc(this, aSize, aShm)) { 570 return false; 571 } 572 573 // Now that we have a valid shmem, put it in the cache if we don't have one 574 // yet. 575 if (!alreadyAllocated) { 576 mResourceShm = aShm; 577 RefCountedShm::AddRef(aShm); 578 } 579 580 return true; 581 } 582 583 void WebRenderBridgeChild::DeallocResourceShmem(RefCountedShmem& aShm) { 584 if (!RefCountedShm::IsValid(aShm)) { 585 return; 586 } 587 MOZ_ASSERT(RefCountedShm::GetReferenceCount(aShm) == 0); 588 589 RefCountedShm::Dealloc(this, aShm); 590 } 591 592 void WebRenderBridgeChild::Capture() { this->SendCapture(); } 593 594 void WebRenderBridgeChild::StartCaptureSequence(const nsCString& aPath, 595 uint32_t aFlags) { 596 this->SendStartCaptureSequence(aPath, aFlags); 597 } 598 599 void WebRenderBridgeChild::StopCaptureSequence() { 600 this->SendStopCaptureSequence(); 601 } 602 603 bool WebRenderBridgeChild::SendEnsureConnected( 604 TextureFactoryIdentifier* textureFactoryIdentifier, 605 MaybeIdNamespace* maybeIdNamespace, nsCString* error) { 606 auto* manager = CompositorManagerChild::GetInstance(); 607 if (XRE_IsParentProcess()) { 608 manager->SetSyncIPCStartTimeStamp(); 609 } 610 auto ret = PWebRenderBridgeChild::SendEnsureConnected( 611 textureFactoryIdentifier, maybeIdNamespace, error); 612 if (XRE_IsParentProcess()) { 613 manager->ClearSyncIPCStartTimeStamp(); 614 } 615 return ret; 616 } 617 618 } // namespace layers 619 } // namespace mozilla