Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/wr/WebRenderBridgeChild.cpp
Line
Count
Source (jump to first uncovered line)
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/dom/TabGroup.h"
11
#include "mozilla/layers/CompositableClient.h"
12
#include "mozilla/layers/CompositorBridgeChild.h"
13
#include "mozilla/layers/ImageDataSerializer.h"
14
#include "mozilla/layers/IpcResourceUpdateQueue.h"
15
#include "mozilla/layers/StackingContextHelper.h"
16
#include "mozilla/layers/PTextureChild.h"
17
#include "mozilla/layers/WebRenderLayerManager.h"
18
#include "mozilla/webrender/WebRenderAPI.h"
19
20
namespace mozilla {
21
namespace layers {
22
23
using namespace mozilla::gfx;
24
25
WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId)
26
  : mIsInTransaction(false)
27
  , mIsInClearCachedResources(false)
28
  , mIdNamespace{0}
29
  , mResourceId(0)
30
  , mPipelineId(aPipelineId)
31
  , mManager(nullptr)
32
  , mIPCOpen(false)
33
  , mDestroyed(false)
34
  , mFontKeysDeleted(0)
35
  , mFontInstanceKeysDeleted(0)
36
0
{
37
0
}
38
39
WebRenderBridgeChild::~WebRenderBridgeChild()
40
0
{
41
0
  MOZ_ASSERT(NS_IsMainThread());
42
0
  MOZ_ASSERT(mDestroyed);
43
0
}
44
45
void
46
WebRenderBridgeChild::Destroy(bool aIsSync)
47
0
{
48
0
  if (!IPCOpen()) {
49
0
    return;
50
0
  }
51
0
52
0
  DoDestroy();
53
0
54
0
  if (aIsSync) {
55
0
    SendShutdownSync();
56
0
  } else {
57
0
    SendShutdown();
58
0
  }
59
0
}
60
61
void
62
WebRenderBridgeChild::ActorDestroy(ActorDestroyReason why)
63
0
{
64
0
  DoDestroy();
65
0
}
66
67
void
68
WebRenderBridgeChild::DoDestroy()
69
0
{
70
0
  if (RefCountedShm::IsValid(mResourceShm) && RefCountedShm::Release(mResourceShm) == 0) {
71
0
    RefCountedShm::Dealloc(this, mResourceShm);
72
0
    mResourceShm = RefCountedShmem();
73
0
  }
74
0
75
0
  // mDestroyed is used to prevent calling Send__delete__() twice.
76
0
  // When this function is called from CompositorBridgeChild::Destroy().
77
0
  // mActiveResourceTracker is not cleared here, since it is
78
0
  // used by PersistentBufferProviderShared.
79
0
  mDestroyed = true;
80
0
  mManager = nullptr;
81
0
}
82
83
void
84
WebRenderBridgeChild::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd)
85
0
{
86
0
  mParentCommands.AppendElement(aCmd);
87
0
}
88
89
void
90
WebRenderBridgeChild::BeginTransaction()
91
0
{
92
0
  MOZ_ASSERT(!mDestroyed);
93
0
94
0
  UpdateFwdTransactionId();
95
0
  mIsInTransaction = true;
96
0
}
97
98
void
99
WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
100
0
{
101
0
  if (!IPCOpen()) {
102
0
    aResources.Clear();
103
0
    return;
104
0
  }
105
0
106
0
  if (aResources.IsEmpty()) {
107
0
    return;
108
0
  }
109
0
110
0
  nsTArray<OpUpdateResource> resourceUpdates;
111
0
  nsTArray<RefCountedShmem> smallShmems;
112
0
  nsTArray<ipc::Shmem> largeShmems;
113
0
  aResources.Flush(resourceUpdates, smallShmems, largeShmems);
114
0
115
0
  this->SendUpdateResources(resourceUpdates, std::move(smallShmems), largeShmems);
116
0
}
117
118
void
119
WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
120
                                     wr::BuiltDisplayList& aDL,
121
                                     wr::IpcResourceUpdateQueue& aResources,
122
                                     const gfx::IntSize& aSize,
123
                                     TransactionId aTransactionId,
124
                                     const WebRenderScrollData& aScrollData,
125
                                     bool aContainsSVGGroup,
126
                                     const mozilla::TimeStamp& aRefreshStartTime,
127
                                     const mozilla::TimeStamp& aTxnStartTime)
128
0
{
129
0
  MOZ_ASSERT(!mDestroyed);
130
0
  MOZ_ASSERT(mIsInTransaction);
131
0
132
0
  ByteBuf dlData(aDL.dl.inner.data, aDL.dl.inner.length, aDL.dl.inner.capacity);
133
0
  aDL.dl.inner.capacity = 0;
134
0
  aDL.dl.inner.data = nullptr;
135
0
136
0
  TimeStamp fwdTime;
137
#if defined(ENABLE_FRAME_LATENCY_LOG)
138
  fwdTime = TimeStamp::Now();
139
#endif
140
141
0
  nsTArray<OpUpdateResource> resourceUpdates;
142
0
  nsTArray<RefCountedShmem> smallShmems;
143
0
  nsTArray<ipc::Shmem> largeShmems;
144
0
  aResources.Flush(resourceUpdates, smallShmems, largeShmems);
145
0
146
0
  this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
147
0
                           GetFwdTransactionId(), aTransactionId,
148
0
                           aContentSize, dlData, aDL.dl_desc, aScrollData,
149
0
                           std::move(resourceUpdates), std::move(smallShmems), largeShmems,
150
0
                           mIdNamespace, aContainsSVGGroup, aRefreshStartTime, aTxnStartTime, fwdTime);
151
0
152
0
  mParentCommands.Clear();
153
0
  mDestroyedActors.Clear();
154
0
  mIsInTransaction = false;
155
0
}
156
157
void
158
WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
159
                                          const ScrollUpdatesMap& aUpdates,
160
                                          uint32_t aPaintSequenceNumber,
161
                                          TransactionId aTransactionId,
162
                                          const mozilla::TimeStamp& aRefreshStartTime,
163
                                          const mozilla::TimeStamp& aTxnStartTime)
164
0
{
165
0
  MOZ_ASSERT(!mDestroyed);
166
0
  MOZ_ASSERT(mIsInTransaction);
167
0
168
0
  TimeStamp fwdTime;
169
#if defined(ENABLE_FRAME_LATENCY_LOG)
170
  fwdTime = TimeStamp::Now();
171
#endif
172
173
0
  this->SendEmptyTransaction(aFocusTarget, aUpdates, aPaintSequenceNumber,
174
0
                             mParentCommands, mDestroyedActors,
175
0
                             GetFwdTransactionId(), aTransactionId,
176
0
                             mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
177
0
  mParentCommands.Clear();
178
0
  mDestroyedActors.Clear();
179
0
  mIsInTransaction = false;
180
0
}
181
182
void
183
WebRenderBridgeChild::ProcessWebRenderParentCommands()
184
0
{
185
0
  MOZ_ASSERT(!mDestroyed);
186
0
187
0
  if (mParentCommands.IsEmpty()) {
188
0
    return;
189
0
  }
190
0
  this->SendParentCommands(mParentCommands);
191
0
  mParentCommands.Clear();
192
0
}
193
194
void
195
WebRenderBridgeChild::AddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId,
196
                                                        const CompositableHandle& aHandle)
197
0
{
198
0
  AddWebRenderParentCommand(
199
0
    OpAddPipelineIdForCompositable(aPipelineId, aHandle, /* isAsync */ true));
200
0
}
201
202
void
203
WebRenderBridgeChild::AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId,
204
                                                   const CompositableHandle& aHandle)
205
0
{
206
0
  AddWebRenderParentCommand(
207
0
    OpAddPipelineIdForCompositable(aPipelineId, aHandle, /* isAsync */ false));
208
0
}
209
210
void
211
WebRenderBridgeChild::RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId)
212
0
{
213
0
  AddWebRenderParentCommand(
214
0
    OpRemovePipelineIdForCompositable(aPipelineId));
215
0
}
216
217
wr::ExternalImageId
218
WebRenderBridgeChild::GetNextExternalImageId()
219
0
{
220
0
  wr::MaybeExternalImageId id = GetCompositorBridgeChild()->GetNextExternalImageId();
221
0
  MOZ_RELEASE_ASSERT(id.isSome());
222
0
  return id.value();
223
0
}
224
225
void
226
WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId)
227
0
{
228
0
  AddWebRenderParentCommand(
229
0
    OpRemoveExternalImageId(aImageId));
230
0
}
231
232
void
233
WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey)
234
0
{
235
0
  AddWebRenderParentCommand(
236
0
    OpReleaseTextureOfImage(aKey));
237
0
}
238
239
struct FontFileDataSink
240
{
241
  wr::FontKey* mFontKey;
242
  WebRenderBridgeChild* mWrBridge;
243
  wr::IpcResourceUpdateQueue* mResources;
244
};
245
246
static void
247
WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
248
                  void* aBaton)
249
0
{
250
0
  FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton);
251
0
252
0
  *sink->mFontKey = sink->mWrBridge->GetNextFontKey();
253
0
254
0
  sink->mResources->AddRawFont(*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), aIndex);
255
0
}
256
257
static void
258
WriteFontDescriptor(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
259
                  void* aBaton)
260
0
{
261
0
  FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton);
262
0
263
0
  *sink->mFontKey = sink->mWrBridge->GetNextFontKey();
264
0
265
0
  sink->mResources->AddFontDescriptor(*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), aIndex);
266
0
}
267
268
void
269
WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, Range<const wr::GlyphInstance> aGlyphs,
270
                                 gfx::ScaledFont* aFont, const wr::ColorF& aColor, const StackingContextHelper& aSc,
271
                                 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, bool aBackfaceVisible,
272
                                 const wr::GlyphOptions* aGlyphOptions)
273
0
{
274
0
  MOZ_ASSERT(aFont);
275
0
276
0
  wr::WrFontInstanceKey key = GetFontKeyForScaledFont(aFont);
277
0
  MOZ_ASSERT(key.mNamespace.mHandle && key.mHandle);
278
0
279
0
  aBuilder.PushText(aBounds,
280
0
                    aClip,
281
0
                    aBackfaceVisible,
282
0
                    aColor,
283
0
                    key,
284
0
                    aGlyphs,
285
0
                    aGlyphOptions);
286
0
}
287
288
wr::FontInstanceKey
289
WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont,
290
                                              wr::IpcResourceUpdateQueue* aResources)
291
0
{
292
0
  MOZ_ASSERT(!mDestroyed);
293
0
  MOZ_ASSERT(aScaledFont);
294
0
  MOZ_ASSERT(aScaledFont->CanSerialize());
295
0
296
0
  wr::FontInstanceKey instanceKey = { wr::IdNamespace { 0 }, 0 };
297
0
  if (mFontInstanceKeys.Get(aScaledFont, &instanceKey)) {
298
0
    return instanceKey;
299
0
  }
300
0
301
0
  Maybe<wr::IpcResourceUpdateQueue> resources =
302
0
    aResources ? Nothing() : Some(wr::IpcResourceUpdateQueue(this));
303
0
  aResources = resources.ptrOr(aResources);
304
0
305
0
  wr::FontKey fontKey = GetFontKeyForUnscaledFont(aScaledFont->GetUnscaledFont(), aResources);
306
0
  wr::FontKey nullKey = { wr::IdNamespace { 0 }, 0};
307
0
  if (fontKey == nullKey) {
308
0
    return instanceKey;
309
0
  }
310
0
311
0
  instanceKey = GetNextFontInstanceKey();
312
0
313
0
  Maybe<wr::FontInstanceOptions> options;
314
0
  Maybe<wr::FontInstancePlatformOptions> platformOptions;
315
0
  std::vector<FontVariation> variations;
316
0
  aScaledFont->GetWRFontInstanceOptions(&options, &platformOptions, &variations);
317
0
318
0
  aResources->AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(),
319
0
                              options.ptrOr(nullptr), platformOptions.ptrOr(nullptr),
320
0
                              Range<const FontVariation>(variations.data(), variations.size()));
321
0
  if (resources.isSome()) {
322
0
    UpdateResources(resources.ref());
323
0
  }
324
0
325
0
  mFontInstanceKeys.Put(aScaledFont, instanceKey);
326
0
327
0
  return instanceKey;
328
0
329
0
}
330
331
wr::FontKey
332
WebRenderBridgeChild::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaled,
333
                                                wr::IpcResourceUpdateQueue* aResources)
334
0
{
335
0
  MOZ_ASSERT(!mDestroyed);
336
0
337
0
  wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
338
0
  if (!mFontKeys.Get(aUnscaled, &fontKey)) {
339
0
    Maybe<wr::IpcResourceUpdateQueue> resources =
340
0
      aResources ? Nothing() : Some(wr::IpcResourceUpdateQueue(this));
341
0
342
0
    FontFileDataSink sink = { &fontKey, this, resources.ptrOr(aResources) };
343
0
    // First try to retrieve a descriptor for the font, as this is much cheaper
344
0
    // to send over IPC than the full raw font data. If this is not possible, then
345
0
    // and only then fall back to getting the raw font file data. If that fails,
346
0
    // then the only thing left to do is signal failure by returning a null font key.
347
0
    if (!aUnscaled->GetWRFontDescriptor(WriteFontDescriptor, &sink) &&
348
0
        !aUnscaled->GetFontFileData(WriteFontFileData, &sink)) {
349
0
      return fontKey;
350
0
    }
351
0
352
0
    if (resources.isSome()) {
353
0
      UpdateResources(resources.ref());
354
0
    }
355
0
356
0
    mFontKeys.Put(aUnscaled, fontKey);
357
0
  }
358
0
359
0
  return fontKey;
360
0
}
361
362
void
363
WebRenderBridgeChild::RemoveExpiredFontKeys(wr::IpcResourceUpdateQueue& aResourceUpdates)
364
0
{
365
0
  uint32_t counter = gfx::ScaledFont::DeletionCounter();
366
0
  if (mFontInstanceKeysDeleted != counter) {
367
0
    mFontInstanceKeysDeleted = counter;
368
0
    for (auto iter = mFontInstanceKeys.Iter(); !iter.Done(); iter.Next()) {
369
0
      if (!iter.Key()) {
370
0
        aResourceUpdates.DeleteFontInstance(iter.Data());
371
0
        iter.Remove();
372
0
      }
373
0
    }
374
0
  }
375
0
  counter = gfx::UnscaledFont::DeletionCounter();
376
0
  if (mFontKeysDeleted != counter) {
377
0
    mFontKeysDeleted = counter;
378
0
    for (auto iter = mFontKeys.Iter(); !iter.Done(); iter.Next()) {
379
0
      if (!iter.Key()) {
380
0
        aResourceUpdates.DeleteFont(iter.Data());
381
0
        iter.Remove();
382
0
      }
383
0
    }
384
0
  }
385
0
}
386
387
CompositorBridgeChild*
388
WebRenderBridgeChild::GetCompositorBridgeChild()
389
0
{
390
0
  return static_cast<CompositorBridgeChild*>(Manager());
391
0
}
392
393
TextureForwarder*
394
WebRenderBridgeChild::GetTextureForwarder()
395
0
{
396
0
  return static_cast<TextureForwarder*>(GetCompositorBridgeChild());
397
0
}
398
399
LayersIPCActor*
400
WebRenderBridgeChild::GetLayersIPCActor()
401
0
{
402
0
  return static_cast<LayersIPCActor*>(GetCompositorBridgeChild());
403
0
}
404
405
void
406
WebRenderBridgeChild::SyncWithCompositor()
407
0
{
408
0
  if (!IPCOpen()) {
409
0
    return;
410
0
  }
411
0
  SendSyncWithCompositor();
412
0
}
413
414
void
415
WebRenderBridgeChild::Connect(CompositableClient* aCompositable,
416
                              ImageContainer* aImageContainer)
417
0
{
418
0
  MOZ_ASSERT(!mDestroyed);
419
0
  MOZ_ASSERT(aCompositable);
420
0
421
0
  static uint64_t sNextID = 1;
422
0
  uint64_t id = sNextID++;
423
0
424
0
  mCompositables.Put(id, aCompositable);
425
0
426
0
  CompositableHandle handle(id);
427
0
  aCompositable->InitIPDL(handle);
428
0
  SendNewCompositable(handle, aCompositable->GetTextureInfo());
429
0
}
430
431
void
432
WebRenderBridgeChild::UseTiledLayerBuffer(CompositableClient* aCompositable,
433
                                          const SurfaceDescriptorTiles& aTiledDescriptor)
434
0
{
435
0
436
0
}
437
438
void
439
WebRenderBridgeChild::UpdateTextureRegion(CompositableClient* aCompositable,
440
                                          const ThebesBufferData& aThebesBufferData,
441
                                          const nsIntRegion& aUpdatedRegion)
442
0
{
443
0
444
0
}
445
446
bool
447
WebRenderBridgeChild::AddOpDestroy(const OpDestroy& aOp)
448
0
{
449
0
  if (!mIsInTransaction) {
450
0
    return false;
451
0
  }
452
0
453
0
  mDestroyedActors.AppendElement(aOp);
454
0
  return true;
455
0
}
456
457
void
458
WebRenderBridgeChild::ReleaseCompositable(const CompositableHandle& aHandle)
459
0
{
460
0
  if (!IPCOpen()) {
461
0
    // This can happen if the IPC connection was torn down, because, e.g.
462
0
    // the GPU process died.
463
0
    return;
464
0
  }
465
0
  if (!DestroyInTransaction(aHandle)) {
466
0
    SendReleaseCompositable(aHandle);
467
0
  }
468
0
  mCompositables.Remove(aHandle.Value());
469
0
}
470
471
bool
472
WebRenderBridgeChild::DestroyInTransaction(PTextureChild* aTexture)
473
0
{
474
0
  return AddOpDestroy(OpDestroy(aTexture));
475
0
}
476
477
bool
478
WebRenderBridgeChild::DestroyInTransaction(const CompositableHandle& aHandle)
479
0
{
480
0
  return AddOpDestroy(OpDestroy(aHandle));
481
0
}
482
483
void
484
WebRenderBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable,
485
                                                    TextureClient* aTexture)
486
0
{
487
0
  MOZ_ASSERT(aCompositable);
488
0
  MOZ_ASSERT(aTexture);
489
0
  MOZ_ASSERT(aTexture->GetIPDLActor());
490
0
  MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == GetIPCChannel());
491
0
  if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
492
0
    // We don't have an actor anymore, don't try to use it!
493
0
    return;
494
0
  }
495
0
496
0
  AddWebRenderParentCommand(
497
0
    CompositableOperation(
498
0
      aCompositable->GetIPCHandle(),
499
0
      OpRemoveTexture(nullptr, aTexture->GetIPDLActor())));
500
0
}
501
502
void
503
WebRenderBridgeChild::UseTextures(CompositableClient* aCompositable,
504
                                  const nsTArray<TimedTextureClient>& aTextures)
505
0
{
506
0
  MOZ_ASSERT(aCompositable);
507
0
508
0
  if (!aCompositable->IsConnected()) {
509
0
    return;
510
0
  }
511
0
512
0
  AutoTArray<TimedTexture,4> textures;
513
0
514
0
  for (auto& t : aTextures) {
515
0
    MOZ_ASSERT(t.mTextureClient);
516
0
    MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
517
0
    MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == GetIPCChannel());
518
0
    bool readLocked = t.mTextureClient->OnForwardedToHost();
519
0
520
0
    textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
521
0
                                        t.mTimeStamp, t.mPictureRect,
522
0
                                        t.mFrameID, t.mProducerID,
523
0
                                        readLocked));
524
0
    GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
525
0
  }
526
0
  AddWebRenderParentCommand(CompositableOperation(aCompositable->GetIPCHandle(),
527
0
                                            OpUseTexture(textures)));
528
0
}
529
530
void
531
WebRenderBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
532
                                                TextureClient* aClientOnBlack,
533
                                                TextureClient* aClientOnWhite)
534
0
{
535
0
536
0
}
537
538
void
539
WebRenderBridgeChild::UpdateFwdTransactionId()
540
0
{
541
0
  GetCompositorBridgeChild()->UpdateFwdTransactionId();
542
0
}
543
544
uint64_t
545
WebRenderBridgeChild::GetFwdTransactionId()
546
0
{
547
0
  return GetCompositorBridgeChild()->GetFwdTransactionId();
548
0
}
549
550
bool
551
WebRenderBridgeChild::InForwarderThread()
552
0
{
553
0
  return NS_IsMainThread();
554
0
}
555
556
mozilla::ipc::IPCResult
557
WebRenderBridgeChild::RecvWrUpdated(const wr::IdNamespace& aNewIdNamespace,
558
                                    const TextureFactoryIdentifier& textureFactoryIdentifier)
559
0
{
560
0
  if (mManager) {
561
0
    mManager->WrUpdated();
562
0
  }
563
0
  IdentifyTextureHost(textureFactoryIdentifier);
564
0
  // Update mIdNamespace to identify obsolete keys and messages by WebRenderBridgeParent.
565
0
  // Since usage of invalid keys could cause crash in webrender.
566
0
  mIdNamespace = aNewIdNamespace;
567
0
  // Just clear FontInstaceKeys/FontKeys, they are removed during WebRenderAPI destruction.
568
0
  mFontInstanceKeys.Clear();
569
0
  mFontKeys.Clear();
570
0
  return IPC_OK();
571
0
}
572
573
void
574
WebRenderBridgeChild::BeginClearCachedResources()
575
0
{
576
0
  mIsInClearCachedResources = true;
577
0
  // Clear display list and animtaions at parent side before clearing cached
578
0
  // resources on client side. It prevents to clear resources before clearing
579
0
  // display list at parent side.
580
0
  SendClearCachedResources();
581
0
}
582
583
void
584
WebRenderBridgeChild::EndClearCachedResources()
585
0
{
586
0
  if (!IPCOpen()) {
587
0
    mIsInClearCachedResources = false;
588
0
    return;
589
0
  }
590
0
  ProcessWebRenderParentCommands();
591
0
  mIsInClearCachedResources = false;
592
0
}
593
594
void
595
WebRenderBridgeChild::SetWebRenderLayerManager(WebRenderLayerManager* aManager)
596
0
{
597
0
  MOZ_ASSERT(aManager && !mManager);
598
0
  mManager = aManager;
599
0
600
0
  nsCOMPtr<nsIEventTarget> eventTarget = nullptr;
601
0
  if (dom::TabGroup* tabGroup = mManager->GetTabGroup()) {
602
0
    eventTarget = tabGroup->EventTargetFor(TaskCategory::Other);
603
0
  }
604
0
  MOZ_ASSERT(eventTarget || !XRE_IsContentProcess());
605
0
  mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
606
0
    1000, "CompositableForwarder", eventTarget);
607
0
}
608
609
ipc::IShmemAllocator*
610
WebRenderBridgeChild::GetShmemAllocator()
611
0
{
612
0
  return static_cast<CompositorBridgeChild*>(Manager());
613
0
}
614
615
616
RefPtr<KnowsCompositor>
617
WebRenderBridgeChild::GetForMedia()
618
0
{
619
0
  MOZ_ASSERT(NS_IsMainThread());
620
0
  return MakeAndAddRef<KnowsCompositorMediaProxy>(GetTextureFactoryIdentifier());
621
0
}
622
623
bool
624
WebRenderBridgeChild::AllocResourceShmem(size_t aSize, RefCountedShmem& aShm)
625
0
{
626
0
  // We keep a single shmem around to reuse later if it is reference count has
627
0
  // dropped back to 1 (the reference held by the WebRenderBridgeChild).
628
0
629
0
  // If the cached shmem exists, has the correct size and isn't held by anything
630
0
  // other than us, recycle it.
631
0
  bool alreadyAllocated = RefCountedShm::IsValid(mResourceShm);
632
0
  if (alreadyAllocated) {
633
0
    if (RefCountedShm::GetSize(mResourceShm) == aSize
634
0
        && RefCountedShm::GetReferenceCount(mResourceShm) <= 1) {
635
0
      MOZ_ASSERT(RefCountedShm::GetReferenceCount(mResourceShm) == 1);
636
0
      aShm = mResourceShm;
637
0
      return true;
638
0
    }
639
0
  }
640
0
641
0
  // If there was no cached shmem or we couldn't recycle it, alloc a new one.
642
0
  if (!RefCountedShm::Alloc(this, aSize, aShm)) {
643
0
    return false;
644
0
  }
645
0
646
0
  // Now that we have a valid shmem, put it in the cache if we don't have one
647
0
  // yet.
648
0
  if (!alreadyAllocated) {
649
0
    mResourceShm = aShm;
650
0
    RefCountedShm::AddRef(aShm);
651
0
  }
652
0
653
0
  return true;
654
0
}
655
656
void
657
WebRenderBridgeChild::DeallocResourceShmem(RefCountedShmem& aShm)
658
0
{
659
0
  if (!RefCountedShm::IsValid(aShm)) {
660
0
    return;
661
0
  }
662
0
  MOZ_ASSERT(RefCountedShm::GetReferenceCount(aShm) == 0);
663
0
664
0
  RefCountedShm::Dealloc(this, aShm);
665
0
}
666
667
void
668
WebRenderBridgeChild::Capture()
669
0
{
670
0
  this->SendCapture();
671
0
}
672
673
} // namespace layers
674
} // namespace mozilla