Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/ShadowLayers.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 "ClientLayerManager.h"         // for ClientLayerManager
8
#include "ShadowLayers.h"
9
#include <set>                          // for _Rb_tree_const_iterator, etc
10
#include <vector>                       // for vector
11
#include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
12
#include "ISurfaceAllocator.h"          // for IsSurfaceDescriptorValid
13
#include "Layers.h"                     // for Layer
14
#include "RenderTrace.h"                // for RenderTraceScope
15
#include "gfx2DGlue.h"                  // for Moz2D transition helpers
16
#include "gfxPlatform.h"                // for gfxImageFormat, gfxPlatform
17
#include "gfxPrefs.h"
18
//#include "gfxSharedImageSurface.h"      // for gfxSharedImageSurface
19
#include "ipc/IPCMessageUtils.h"        // for gfxContentType, null_t
20
#include "IPDLActor.h"
21
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
22
#include "mozilla/dom/TabGroup.h"
23
#include "mozilla/gfx/Point.h"          // for IntSize
24
#include "mozilla/layers/CompositableClient.h"  // for CompositableClient, etc
25
#include "mozilla/layers/CompositorBridgeChild.h"
26
#include "mozilla/layers/ContentClient.h"
27
#include "mozilla/layers/ImageDataSerializer.h"
28
#include "mozilla/layers/ImageBridgeChild.h"
29
#include "mozilla/layers/LayersMessages.h"  // for Edit, etc
30
#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
31
#include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
32
#include "mozilla/layers/LayerTransactionChild.h"
33
#include "mozilla/layers/PTextureChild.h"
34
#include "mozilla/layers/SyncObject.h"
35
#ifdef XP_DARWIN
36
#include "mozilla/layers/TextureSync.h"
37
#endif
38
#include "ShadowLayerUtils.h"
39
#include "mozilla/layers/TextureClient.h"  // for TextureClient
40
#include "mozilla/mozalloc.h"           // for operator new, etc
41
#include "nsTArray.h"                   // for AutoTArray, nsTArray, etc
42
#include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
43
#include "mozilla/ReentrantMonitor.h"
44
45
namespace mozilla {
46
namespace ipc {
47
class Shmem;
48
} // namespace ipc
49
50
namespace layers {
51
52
using namespace mozilla::gfx;
53
using namespace mozilla::gl;
54
using namespace mozilla::ipc;
55
56
class ClientTiledLayerBuffer;
57
58
typedef nsTArray<SurfaceDescriptor> BufferArray;
59
typedef nsTArray<Edit> EditVector;
60
typedef nsTHashtable<nsPtrHashKey<ShadowableLayer>> ShadowableLayerSet;
61
typedef nsTArray<OpDestroy> OpDestroyVector;
62
63
class Transaction
64
{
65
public:
66
  Transaction()
67
    : mTargetRotation(ROTATION_0)
68
    , mTargetOrientation(hal::eScreenOrientation_None)
69
    , mOpen(false)
70
    , mRotationChanged(false)
71
0
  {}
72
73
  void Begin(const gfx::IntRect& aTargetBounds, ScreenRotation aRotation,
74
             hal::ScreenOrientation aOrientation)
75
0
  {
76
0
    mOpen = true;
77
0
    mTargetBounds = aTargetBounds;
78
0
    if (aRotation != mTargetRotation) {
79
0
      // the first time this is called, mRotationChanged will be false if
80
0
      // aRotation is 0, but we should be OK because for the first transaction
81
0
      // we should only compose if it is non-empty. See the caller(s) of
82
0
      // RotationChanged.
83
0
      mRotationChanged = true;
84
0
    }
85
0
    mTargetRotation = aRotation;
86
0
    mTargetOrientation = aOrientation;
87
0
  }
88
  void AddEdit(const Edit& aEdit)
89
0
  {
90
0
    MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
91
0
    mCset.AppendElement(aEdit);
92
0
  }
93
  void AddEdit(const CompositableOperation& aEdit)
94
0
  {
95
0
    AddEdit(Edit(aEdit));
96
0
  }
97
98
  void AddNoSwapPaint(const CompositableOperation& aPaint)
99
0
  {
100
0
    MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
101
0
    mPaints.AppendElement(Edit(aPaint));
102
0
  }
103
  void AddMutant(ShadowableLayer* aLayer)
104
0
  {
105
0
    MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
106
0
    mMutants.PutEntry(aLayer);
107
0
  }
108
  void AddSimpleMutant(ShadowableLayer* aLayer)
109
0
  {
110
0
    MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
111
0
    mSimpleMutants.PutEntry(aLayer);
112
0
  }
113
  void End()
114
0
  {
115
0
    mCset.Clear();
116
0
    mPaints.Clear();
117
0
    mMutants.Clear();
118
0
    mSimpleMutants.Clear();
119
0
    mDestroyedActors.Clear();
120
0
    mOpen = false;
121
0
    mRotationChanged = false;
122
0
  }
123
124
0
  bool Empty() const {
125
0
    return mCset.IsEmpty() &&
126
0
           mPaints.IsEmpty() &&
127
0
           mMutants.IsEmpty() &&
128
0
           mSimpleMutants.IsEmpty() &&
129
0
           mDestroyedActors.IsEmpty();
130
0
  }
131
0
  bool RotationChanged() const {
132
0
    return mRotationChanged;
133
0
  }
134
0
  bool Finished() const { return !mOpen && Empty(); }
135
136
0
  bool Opened() const { return mOpen; }
137
138
  EditVector mCset;
139
  nsTArray<CompositableOperation> mPaints;
140
  OpDestroyVector mDestroyedActors;
141
  ShadowableLayerSet mMutants;
142
  ShadowableLayerSet mSimpleMutants;
143
  gfx::IntRect mTargetBounds;
144
  ScreenRotation mTargetRotation;
145
  hal::ScreenOrientation mTargetOrientation;
146
147
private:
148
  bool mOpen;
149
  bool mRotationChanged;
150
151
  // disabled
152
  Transaction(const Transaction&);
153
  Transaction& operator=(const Transaction&);
154
};
155
struct AutoTxnEnd {
156
0
  explicit AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {}
157
0
  ~AutoTxnEnd() { mTxn->End(); }
158
  Transaction* mTxn;
159
};
160
161
void
162
KnowsCompositor::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
163
0
{
164
0
  mTextureFactoryIdentifier = aIdentifier;
165
0
166
0
  mSyncObject = SyncObjectClient::CreateSyncObjectClient(aIdentifier.mSyncHandle);
167
0
}
168
169
KnowsCompositor::KnowsCompositor()
170
  : mSerial(++sSerialCounter)
171
0
{}
172
173
KnowsCompositor::~KnowsCompositor()
174
0
{}
175
176
KnowsCompositorMediaProxy::KnowsCompositorMediaProxy(const TextureFactoryIdentifier& aIdentifier)
177
0
{
178
0
  mTextureFactoryIdentifier = aIdentifier;
179
0
  // overwrite mSerial's value set by the parent class because we use the same serial
180
0
  // as the KnowsCompositor we are proxying.
181
0
  mThreadSafeAllocator = ImageBridgeChild::GetSingleton();
182
0
  mSyncObject = mThreadSafeAllocator->GetSyncObject();
183
0
}
184
185
KnowsCompositorMediaProxy::~KnowsCompositorMediaProxy()
186
0
{}
187
188
TextureForwarder*
189
KnowsCompositorMediaProxy::GetTextureForwarder()
190
0
{
191
0
  return mThreadSafeAllocator->GetTextureForwarder();
192
0
}
193
194
LayersIPCActor*
195
KnowsCompositorMediaProxy::GetLayersIPCActor()
196
0
{
197
0
  return mThreadSafeAllocator->GetLayersIPCActor();
198
0
}
199
200
ActiveResourceTracker*
201
KnowsCompositorMediaProxy::GetActiveResourceTracker()
202
0
{
203
0
  return mThreadSafeAllocator->GetActiveResourceTracker();
204
0
}
205
206
void
207
KnowsCompositorMediaProxy::SyncWithCompositor()
208
0
{
209
0
  mThreadSafeAllocator->SyncWithCompositor();
210
0
}
211
212
RefPtr<KnowsCompositor>
213
ShadowLayerForwarder::GetForMedia()
214
0
{
215
0
  return MakeAndAddRef<KnowsCompositorMediaProxy>(GetTextureFactoryIdentifier());
216
0
}
217
218
ShadowLayerForwarder::ShadowLayerForwarder(ClientLayerManager* aClientLayerManager)
219
 : mClientLayerManager(aClientLayerManager)
220
 , mMessageLoop(MessageLoop::current())
221
 , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
222
 , mIsFirstPaint(false)
223
 , mWindowOverlayChanged(false)
224
 , mNextLayerHandle(1)
225
0
{
226
0
  mTxn = new Transaction();
227
0
  if (TabGroup* tabGroup = mClientLayerManager->GetTabGroup()) {
228
0
    mEventTarget = tabGroup->EventTargetFor(TaskCategory::Other);
229
0
  }
230
0
  MOZ_ASSERT(mEventTarget || !XRE_IsContentProcess());
231
0
  mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
232
0
    1000, "CompositableForwarder", mEventTarget);
233
0
}
234
235
template<typename T>
236
struct ReleaseOnMainThreadTask : public Runnable
237
{
238
  UniquePtr<T> mObj;
239
240
  explicit ReleaseOnMainThreadTask(UniquePtr<T>& aObj)
241
    : Runnable("layers::ReleaseOnMainThreadTask")
242
    , mObj(std::move(aObj))
243
0
  {}
244
245
0
  NS_IMETHOD Run() override {
246
0
    mObj = nullptr;
247
0
    return NS_OK;
248
0
  }
249
};
250
251
ShadowLayerForwarder::~ShadowLayerForwarder()
252
0
{
253
0
  MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?");
254
0
  delete mTxn;
255
0
  if (mShadowManager) {
256
0
    mShadowManager->SetForwarder(nullptr);
257
0
    if (NS_IsMainThread()) {
258
0
      mShadowManager->Destroy();
259
0
    } else {
260
0
      if (mEventTarget) {
261
0
        mEventTarget->Dispatch(
262
0
          NewRunnableMethod("LayerTransactionChild::Destroy", mShadowManager,
263
0
                            &LayerTransactionChild::Destroy),
264
0
          nsIEventTarget::DISPATCH_NORMAL);
265
0
      } else {
266
0
        NS_DispatchToMainThread(
267
0
          NewRunnableMethod("layers::LayerTransactionChild::Destroy",
268
0
                            mShadowManager,
269
0
                            &LayerTransactionChild::Destroy));
270
0
      }
271
0
    }
272
0
  }
273
0
274
0
  if (!NS_IsMainThread()) {
275
0
    RefPtr<ReleaseOnMainThreadTask<ActiveResourceTracker>> event =
276
0
      new ReleaseOnMainThreadTask<ActiveResourceTracker>(mActiveResourceTracker);
277
0
    if (mEventTarget) {
278
0
      mEventTarget->Dispatch(event.forget(), nsIEventTarget::DISPATCH_NORMAL);
279
0
    } else {
280
0
      NS_DispatchToMainThread(event);
281
0
    }
282
0
  }
283
0
}
284
285
void
286
ShadowLayerForwarder::BeginTransaction(const gfx::IntRect& aTargetBounds,
287
                                       ScreenRotation aRotation,
288
                                       hal::ScreenOrientation aOrientation)
289
0
{
290
0
  MOZ_ASSERT(IPCOpen(), "no manager to forward to");
291
0
  MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
292
0
  UpdateFwdTransactionId();
293
0
  mTxn->Begin(aTargetBounds, aRotation, aOrientation);
294
0
}
295
296
static const LayerHandle&
297
Shadow(ShadowableLayer* aLayer)
298
0
{
299
0
  return aLayer->GetShadow();
300
0
}
301
302
template<typename OpCreateT>
303
static void
304
CreatedLayer(Transaction* aTxn, ShadowableLayer* aLayer)
305
0
{
306
0
  aTxn->AddEdit(OpCreateT(Shadow(aLayer)));
307
0
}
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreatePaintedLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreateContainerLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreateImageLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreateColorLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreateCanvasLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
Unexecuted instantiation: Unified_cpp_gfx_layers8.cpp:void mozilla::layers::CreatedLayer<mozilla::layers::OpCreateRefLayer>(mozilla::layers::Transaction*, mozilla::layers::ShadowableLayer*)
308
309
void
310
ShadowLayerForwarder::CreatedPaintedLayer(ShadowableLayer* aThebes)
311
0
{
312
0
  CreatedLayer<OpCreatePaintedLayer>(mTxn, aThebes);
313
0
}
314
void
315
ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer* aContainer)
316
0
{
317
0
  CreatedLayer<OpCreateContainerLayer>(mTxn, aContainer);
318
0
}
319
void
320
ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer* aImage)
321
0
{
322
0
  CreatedLayer<OpCreateImageLayer>(mTxn, aImage);
323
0
}
324
void
325
ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor)
326
0
{
327
0
  CreatedLayer<OpCreateColorLayer>(mTxn, aColor);
328
0
}
329
void
330
ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas)
331
0
{
332
0
  CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas);
333
0
}
334
void
335
ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef)
336
0
{
337
0
  CreatedLayer<OpCreateRefLayer>(mTxn, aRef);
338
0
}
339
340
void
341
ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant)
342
0
{
343
0
  mTxn->AddMutant(aMutant);
344
0
}
345
346
void
347
ShadowLayerForwarder::MutatedSimple(ShadowableLayer* aMutant)
348
0
{
349
0
  mTxn->AddSimpleMutant(aMutant);
350
0
}
351
352
void
353
ShadowLayerForwarder::SetRoot(ShadowableLayer* aRoot)
354
0
{
355
0
  mTxn->AddEdit(OpSetRoot(Shadow(aRoot)));
356
0
}
357
void
358
ShadowLayerForwarder::InsertAfter(ShadowableLayer* aContainer,
359
                                  ShadowableLayer* aChild,
360
                                  ShadowableLayer* aAfter)
361
0
{
362
0
  if (!aChild->HasShadow()) {
363
0
    return;
364
0
  }
365
0
366
0
  while (aAfter && !aAfter->HasShadow()) {
367
0
    aAfter = aAfter->AsLayer()->GetPrevSibling() ? aAfter->AsLayer()->GetPrevSibling()->AsShadowableLayer() : nullptr;
368
0
  }
369
0
370
0
  if (aAfter) {
371
0
    mTxn->AddEdit(OpInsertAfter(Shadow(aContainer), Shadow(aChild), Shadow(aAfter)));
372
0
  } else {
373
0
    mTxn->AddEdit(OpPrependChild(Shadow(aContainer), Shadow(aChild)));
374
0
  }
375
0
}
376
void
377
ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer,
378
                                  ShadowableLayer* aChild)
379
0
{
380
0
  MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n",
381
0
                  aContainer->AsLayer(), aChild->AsLayer()));
382
0
383
0
  if (!aChild->HasShadow()) {
384
0
    return;
385
0
  }
386
0
387
0
  mTxn->AddEdit(OpRemoveChild(Shadow(aContainer), Shadow(aChild)));
388
0
}
389
void
390
ShadowLayerForwarder::RepositionChild(ShadowableLayer* aContainer,
391
                                      ShadowableLayer* aChild,
392
                                      ShadowableLayer* aAfter)
393
0
{
394
0
  if (!aChild->HasShadow()) {
395
0
    return;
396
0
  }
397
0
398
0
  while (aAfter && !aAfter->HasShadow()) {
399
0
    aAfter = aAfter->AsLayer()->GetPrevSibling() ? aAfter->AsLayer()->GetPrevSibling()->AsShadowableLayer() : nullptr;
400
0
  }
401
0
402
0
  if (aAfter) {
403
0
    MOZ_LAYERS_LOG(("[LayersForwarder] OpRepositionChild container=%p child=%p after=%p",
404
0
                   aContainer->AsLayer(), aChild->AsLayer(), aAfter->AsLayer()));
405
0
    mTxn->AddEdit(OpRepositionChild(Shadow(aContainer), Shadow(aChild), Shadow(aAfter)));
406
0
  } else {
407
0
    MOZ_LAYERS_LOG(("[LayersForwarder] OpRaiseToTopChild container=%p child=%p",
408
0
                   aContainer->AsLayer(), aChild->AsLayer()));
409
0
    mTxn->AddEdit(OpRaiseToTopChild(Shadow(aContainer), Shadow(aChild)));
410
0
  }
411
0
}
412
413
414
#ifdef DEBUG
415
void
416
ShadowLayerForwarder::CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const
417
{
418
  if (!aDescriptor) {
419
    return;
420
  }
421
422
  if (aDescriptor->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
423
      aDescriptor->get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::TShmem) {
424
    const Shmem& shmem = aDescriptor->get_SurfaceDescriptorBuffer().data().get_Shmem();
425
    shmem.AssertInvariants();
426
    MOZ_ASSERT(mShadowManager &&
427
               mShadowManager->IsTrackingSharedMemory(shmem.mSegment));
428
  }
429
}
430
#endif
431
432
void
433
ShadowLayerForwarder::UseTiledLayerBuffer(CompositableClient* aCompositable,
434
                                          const SurfaceDescriptorTiles& aTileLayerDescriptor)
435
0
{
436
0
  MOZ_ASSERT(aCompositable);
437
0
438
0
  if (!aCompositable->IsConnected()) {
439
0
    return;
440
0
  }
441
0
442
0
  mTxn->AddNoSwapPaint(CompositableOperation(aCompositable->GetIPCHandle(),
443
0
                                             OpUseTiledLayerBuffer(aTileLayerDescriptor)));
444
0
}
445
446
void
447
ShadowLayerForwarder::UpdateTextureRegion(CompositableClient* aCompositable,
448
                                          const ThebesBufferData& aThebesBufferData,
449
                                          const nsIntRegion& aUpdatedRegion)
450
0
{
451
0
  MOZ_ASSERT(aCompositable);
452
0
453
0
  if (!aCompositable->IsConnected()) {
454
0
    return;
455
0
  }
456
0
457
0
  mTxn->AddNoSwapPaint(
458
0
    CompositableOperation(
459
0
      aCompositable->GetIPCHandle(),
460
0
      OpPaintTextureRegion(aThebesBufferData, aUpdatedRegion)));
461
0
}
462
463
void
464
ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
465
                                  const nsTArray<TimedTextureClient>& aTextures)
466
0
{
467
0
  MOZ_ASSERT(aCompositable);
468
0
469
0
  if (!aCompositable->IsConnected()) {
470
0
    return;
471
0
  }
472
0
473
0
  AutoTArray<TimedTexture,4> textures;
474
0
475
0
  for (auto& t : aTextures) {
476
0
    MOZ_ASSERT(t.mTextureClient);
477
0
    MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
478
0
    MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
479
0
    bool readLocked = t.mTextureClient->OnForwardedToHost();
480
0
    textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
481
0
                                        t.mTimeStamp, t.mPictureRect,
482
0
                                        t.mFrameID, t.mProducerID,
483
0
                                        readLocked));
484
0
    mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
485
0
  }
486
0
  mTxn->AddEdit(CompositableOperation(aCompositable->GetIPCHandle(),
487
0
                                      OpUseTexture(textures)));
488
0
}
489
490
void
491
ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositable,
492
                                                TextureClient* aTextureOnBlack,
493
                                                TextureClient* aTextureOnWhite)
494
0
{
495
0
  MOZ_ASSERT(aCompositable);
496
0
497
0
  if (!aCompositable->IsConnected()) {
498
0
    return;
499
0
  }
500
0
501
0
  MOZ_ASSERT(aTextureOnWhite);
502
0
  MOZ_ASSERT(aTextureOnBlack);
503
0
  MOZ_ASSERT(aCompositable->GetIPCHandle());
504
0
  MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
505
0
  MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
506
0
  MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
507
0
  MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
508
0
  MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
509
0
510
0
  bool readLockedB = aTextureOnBlack->OnForwardedToHost();
511
0
  bool readLockedW = aTextureOnWhite->OnForwardedToHost();
512
0
513
0
  mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
514
0
  mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
515
0
516
0
  mTxn->AddEdit(
517
0
    CompositableOperation(
518
0
      aCompositable->GetIPCHandle(),
519
0
      OpUseComponentAlphaTextures(
520
0
        nullptr, aTextureOnBlack->GetIPDLActor(),
521
0
        nullptr, aTextureOnWhite->GetIPDLActor(),
522
0
        readLockedB, readLockedW)
523
0
      )
524
0
    );
525
0
}
526
527
static bool
528
AddOpDestroy(Transaction* aTxn, const OpDestroy& op)
529
0
{
530
0
  if (!aTxn->Opened()) {
531
0
    return false;
532
0
  }
533
0
534
0
  aTxn->mDestroyedActors.AppendElement(op);
535
0
  return true;
536
0
}
537
538
bool
539
ShadowLayerForwarder::DestroyInTransaction(PTextureChild* aTexture)
540
0
{
541
0
  return AddOpDestroy(mTxn, OpDestroy(aTexture));
542
0
}
543
544
bool
545
ShadowLayerForwarder::DestroyInTransaction(const CompositableHandle& aHandle)
546
0
{
547
0
  return AddOpDestroy(mTxn, OpDestroy(aHandle));
548
0
}
549
550
void
551
ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable,
552
                                                    TextureClient* aTexture)
553
0
{
554
0
  MOZ_ASSERT(aCompositable);
555
0
  MOZ_ASSERT(aTexture);
556
0
  MOZ_ASSERT(aTexture->GetIPDLActor());
557
0
  MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
558
0
  if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
559
0
    // We don't have an actor anymore, don't try to use it!
560
0
    return;
561
0
  }
562
0
563
0
  mTxn->AddEdit(
564
0
    CompositableOperation(
565
0
      aCompositable->GetIPCHandle(),
566
0
      OpRemoveTexture(nullptr, aTexture->GetIPDLActor())));
567
0
}
568
569
bool
570
ShadowLayerForwarder::InWorkerThread()
571
0
{
572
0
  return MessageLoop::current() && (GetTextureForwarder()->GetMessageLoop()->id() == MessageLoop::current()->id());
573
0
}
574
575
void
576
ShadowLayerForwarder::StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>&
577
                                                      aConfigurations)
578
0
{
579
0
  // Cache new plugin widget configs here until we call update, at which
580
0
  // point this data will get shipped over to chrome.
581
0
  mPluginWindowData.Clear();
582
0
  for (uint32_t idx = 0; idx < aConfigurations.Length(); idx++) {
583
0
    const nsIWidget::Configuration& configuration = aConfigurations[idx];
584
0
    mPluginWindowData.AppendElement(PluginWindowData(configuration.mWindowID,
585
0
                                                     configuration.mClipRegion,
586
0
                                                     configuration.mBounds,
587
0
                                                     configuration.mVisible));
588
0
  }
589
0
}
590
591
void
592
ShadowLayerForwarder::SendPaintTime(TransactionId aId, TimeDuration aPaintTime)
593
0
{
594
0
  if (!IPCOpen() ||
595
0
      !mShadowManager->SendPaintTime(aId, aPaintTime)) {
596
0
    NS_WARNING("Could not send paint times over IPC");
597
0
  }
598
0
}
599
600
bool
601
ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
602
                                     TransactionId aId,
603
                                     bool aScheduleComposite,
604
                                     uint32_t aPaintSequenceNumber,
605
                                     bool aIsRepeatTransaction,
606
                                     const mozilla::TimeStamp& aRefreshStart,
607
                                     const mozilla::TimeStamp& aTransactionStart,
608
                                     bool* aSent)
609
0
{
610
0
  *aSent = false;
611
0
612
0
  TransactionInfo info;
613
0
614
0
  MOZ_ASSERT(IPCOpen(), "no manager to forward to");
615
0
  if (!IPCOpen()) {
616
0
    return false;
617
0
  }
618
0
619
0
  Maybe<TimeStamp> startTime;
620
0
  if (gfxPrefs::LayersDrawFPS()) {
621
0
    startTime = Some(TimeStamp::Now());
622
0
  }
623
0
624
0
  GetCompositorBridgeChild()->WillEndTransaction();
625
0
626
0
  MOZ_ASSERT(aId.IsValid());
627
0
628
0
  AUTO_PROFILER_LABEL("ShadowLayerForwarder::EndTransaction", GRAPHICS);
629
0
630
0
  RenderTraceScope rendertrace("Foward Transaction", "000091");
631
0
  MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
632
0
633
0
  DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
634
0
  if (mDiagnosticTypes != diagnostics) {
635
0
    mDiagnosticTypes = diagnostics;
636
0
    mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics));
637
0
  }
638
0
  if (mWindowOverlayChanged) {
639
0
    mTxn->AddEdit(OpWindowOverlayChanged());
640
0
  }
641
0
642
0
  AutoTxnEnd _(mTxn);
643
0
644
0
  if (mTxn->Empty() && !mTxn->RotationChanged()) {
645
0
    MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?) and no rotation event, skipping Update()"));
646
0
    return true;
647
0
  }
648
0
649
0
  if (!mTxn->mPaints.IsEmpty()) {
650
0
    // With some platforms, telling the drawing backend that there will be no more
651
0
    // drawing for this frame helps with preventing command queues from spanning
652
0
    // across multiple frames.
653
0
    gfxPlatform::GetPlatform()->FlushContentDrawing();
654
0
  }
655
0
656
0
  MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers..."));
657
0
658
0
  MOZ_LAYERS_LOG(("[LayersForwarder] building transaction..."));
659
0
660
0
  nsTArray<OpSetSimpleLayerAttributes> setSimpleAttrs;
661
0
  for (ShadowableLayerSet::Iterator it(&mTxn->mSimpleMutants); !it.Done(); it.Next()) {
662
0
    ShadowableLayer* shadow = it.Get()->GetKey();
663
0
    if (!shadow->HasShadow()) {
664
0
      continue;
665
0
    }
666
0
667
0
    Layer* mutant = shadow->AsLayer();
668
0
    setSimpleAttrs.AppendElement(OpSetSimpleLayerAttributes(
669
0
      Shadow(shadow),
670
0
      mutant->GetSimpleAttributes()));
671
0
  }
672
0
673
0
  nsTArray<OpSetLayerAttributes> setAttrs;
674
0
675
0
  // We purposely add attribute-change ops to the final changeset
676
0
  // before we add paint ops.  This allows layers to record the
677
0
  // attribute changes before new pixels arrive, which can be useful
678
0
  // for setting up back/front buffers.
679
0
  RenderTraceScope rendertrace2("Foward Transaction", "000092");
680
0
  for (ShadowableLayerSet::Iterator it(&mTxn->mMutants);
681
0
       !it.Done(); it.Next()) {
682
0
    ShadowableLayer* shadow = it.Get()->GetKey();
683
0
684
0
    if (!shadow->HasShadow()) {
685
0
      continue;
686
0
    }
687
0
    Layer* mutant = shadow->AsLayer();
688
0
    MOZ_ASSERT(!!mutant, "unshadowable layer?");
689
0
690
0
    OpSetLayerAttributes op;
691
0
    op.layer() = Shadow(shadow);
692
0
693
0
    LayerAttributes& attrs = op.attrs();
694
0
    CommonLayerAttributes& common = attrs.common();
695
0
    common.visibleRegion() = mutant->GetVisibleRegion();
696
0
    common.eventRegions() = mutant->GetEventRegions();
697
0
    common.useClipRect() = !!mutant->GetClipRect();
698
0
    common.clipRect() = (common.useClipRect() ?
699
0
                         *mutant->GetClipRect() : ParentLayerIntRect());
700
0
    if (Layer* maskLayer = mutant->GetMaskLayer()) {
701
0
      common.maskLayer() = Shadow(maskLayer->AsShadowableLayer());
702
0
    } else {
703
0
      common.maskLayer() = LayerHandle();
704
0
    }
705
0
    common.compositorAnimations().id() = mutant->GetCompositorAnimationsId();
706
0
    common.compositorAnimations().animations() = mutant->GetAnimations();
707
0
    common.invalidRegion() = mutant->GetInvalidRegion().GetRegion();
708
0
    common.scrollMetadata() = mutant->GetAllScrollMetadata();
709
0
    for (size_t i = 0; i < mutant->GetAncestorMaskLayerCount(); i++) {
710
0
      auto layer = Shadow(mutant->GetAncestorMaskLayerAt(i)->AsShadowableLayer());
711
0
      common.ancestorMaskLayers().AppendElement(layer);
712
0
    }
713
0
    nsCString log;
714
0
    mutant->GetDisplayListLog(log);
715
0
    common.displayListLog() = log;
716
0
717
0
    attrs.specific() = null_t();
718
0
    mutant->FillSpecificAttributes(attrs.specific());
719
0
720
0
    MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant));
721
0
722
0
    setAttrs.AppendElement(op);
723
0
  }
724
0
725
0
  if (mTxn->mCset.IsEmpty() &&
726
0
      mTxn->mPaints.IsEmpty() &&
727
0
      setAttrs.IsEmpty() &&
728
0
      !mTxn->RotationChanged())
729
0
  {
730
0
    return true;
731
0
  }
732
0
733
0
  mWindowOverlayChanged = false;
734
0
735
0
  info.cset() = std::move(mTxn->mCset);
736
0
  info.setSimpleAttrs() = std::move(setSimpleAttrs);
737
0
  info.setAttrs() = std::move(setAttrs);
738
0
  info.paints() = std::move(mTxn->mPaints);
739
0
  info.toDestroy() = mTxn->mDestroyedActors;
740
0
  info.fwdTransactionId() = GetFwdTransactionId();
741
0
  info.id() = aId;
742
0
  info.plugins() = mPluginWindowData;
743
0
  info.isFirstPaint() = mIsFirstPaint;
744
0
  info.focusTarget() = mFocusTarget;
745
0
  info.scheduleComposite() = aScheduleComposite;
746
0
  info.paintSequenceNumber() = aPaintSequenceNumber;
747
0
  info.isRepeatTransaction() = aIsRepeatTransaction;
748
0
  info.refreshStart() = aRefreshStart;
749
0
  info.transactionStart() = aTransactionStart;
750
#if defined(ENABLE_FRAME_LATENCY_LOG)
751
  info.fwdTime() = TimeStamp::Now();
752
#endif
753
754
0
  TargetConfig targetConfig(mTxn->mTargetBounds,
755
0
                            mTxn->mTargetRotation,
756
0
                            mTxn->mTargetOrientation,
757
0
                            aRegionToClear);
758
0
  info.targetConfig() = targetConfig;
759
0
760
0
  if (!GetTextureForwarder()->IsSameProcess()) {
761
0
    MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
762
0
    PlatformSyncBeforeUpdate();
763
0
  }
764
0
765
0
  if (startTime) {
766
0
    mPaintTiming.serializeMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds();
767
0
    startTime = Some(TimeStamp::Now());
768
0
  }
769
0
770
0
  // We delay at the last possible minute, to give the paint thread a chance to
771
0
  // finish. If it does we don't have to delay messages at all.
772
0
  GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting();
773
0
774
0
  if (recordreplay::IsRecordingOrReplaying()) {
775
0
    recordreplay::child::NotifyPaintStart();
776
0
  }
777
0
778
0
  MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
779
0
  RenderTraceScope rendertrace3("Forward Transaction", "000093");
780
0
  if (!mShadowManager->SendUpdate(info)) {
781
0
    MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
782
0
    return false;
783
0
  }
784
0
785
0
  if (recordreplay::IsRecordingOrReplaying()) {
786
0
    recordreplay::child::WaitForPaintToComplete();
787
0
  }
788
0
789
0
  if (startTime) {
790
0
    mPaintTiming.sendMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds();
791
0
    mShadowManager->SendRecordPaintTimes(mPaintTiming);
792
0
  }
793
0
794
0
  *aSent = true;
795
0
  mIsFirstPaint = false;
796
0
  mFocusTarget = FocusTarget();
797
0
  MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
798
0
  return true;
799
0
}
800
801
RefPtr<CompositableClient>
802
ShadowLayerForwarder::FindCompositable(const CompositableHandle& aHandle)
803
0
{
804
0
  CompositableClient* client = nullptr;
805
0
  if (!mCompositables.Get(aHandle.Value(), &client)) {
806
0
    return nullptr;
807
0
  }
808
0
  return client;
809
0
}
810
811
void
812
ShadowLayerForwarder::SetLayersObserverEpoch(LayersObserverEpoch aEpoch)
813
0
{
814
0
  if (!IPCOpen()) {
815
0
    return;
816
0
  }
817
0
  Unused << mShadowManager->SendSetLayersObserverEpoch(aEpoch);
818
0
}
819
820
void
821
ShadowLayerForwarder::UpdateTextureLocks()
822
0
{
823
#ifdef XP_DARWIN
824
  if (!IPCOpen()) {
825
    return;
826
  }
827
828
  auto compositorBridge = GetCompositorBridgeChild();
829
  if (compositorBridge) {
830
    auto pid = compositorBridge->OtherPid();
831
    TextureSync::UpdateTextureLocks(pid);
832
  }
833
#endif
834
}
835
836
void
837
ShadowLayerForwarder::SyncTextures(const nsTArray<uint64_t>& aSerials)
838
0
{
839
#ifdef XP_DARWIN
840
  if (!IPCOpen()) {
841
    return;
842
  }
843
844
  auto compositorBridge = GetCompositorBridgeChild();
845
  if (compositorBridge) {
846
    auto pid = compositorBridge->OtherPid();
847
    TextureSync::WaitForTextures(pid, aSerials);
848
  }
849
#endif
850
}
851
852
void
853
ShadowLayerForwarder::ReleaseLayer(const LayerHandle& aHandle)
854
0
{
855
0
  if (!IPCOpen()) {
856
0
    return;
857
0
  }
858
0
  Unused << mShadowManager->SendReleaseLayer(aHandle);
859
0
}
860
861
bool
862
ShadowLayerForwarder::IPCOpen() const
863
0
{
864
0
  return HasShadowManager() && mShadowManager->IPCOpen();
865
0
}
866
867
/**
868
  * We bail out when we have no shadow manager. That can happen when the
869
  * layer manager is created by the preallocated process.
870
  * See bug 914843 for details.
871
  */
872
LayerHandle
873
ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer)
874
0
{
875
0
  return LayerHandle(mNextLayerHandle++);
876
0
}
877
878
#if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
879
880
/*static*/ void
881
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
882
{
883
}
884
885
#endif  // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
886
887
void
888
ShadowLayerForwarder::Connect(CompositableClient* aCompositable,
889
                              ImageContainer* aImageContainer)
890
0
{
891
#ifdef GFX_COMPOSITOR_LOGGING
892
  printf("ShadowLayerForwarder::Connect(Compositable)\n");
893
#endif
894
0
  MOZ_ASSERT(aCompositable);
895
0
  MOZ_ASSERT(mShadowManager);
896
0
  if (!IPCOpen()) {
897
0
    return;
898
0
  }
899
0
900
0
  static uint64_t sNextID = 1;
901
0
  uint64_t id = sNextID++;
902
0
903
0
  mCompositables.Put(id, aCompositable);
904
0
905
0
  CompositableHandle handle(id);
906
0
  aCompositable->InitIPDL(handle);
907
0
  mShadowManager->SendNewCompositable(handle, aCompositable->GetTextureInfo());
908
0
}
909
910
void ShadowLayerForwarder::Attach(CompositableClient* aCompositable,
911
                                  ShadowableLayer* aLayer)
912
0
{
913
0
  MOZ_ASSERT(aLayer);
914
0
  MOZ_ASSERT(aCompositable);
915
0
  mTxn->AddEdit(OpAttachCompositable(Shadow(aLayer), aCompositable->GetIPCHandle()));
916
0
}
917
918
void ShadowLayerForwarder::AttachAsyncCompositable(const CompositableHandle& aHandle,
919
                                                   ShadowableLayer* aLayer)
920
0
{
921
0
  MOZ_ASSERT(aLayer);
922
0
  MOZ_ASSERT(aHandle);
923
0
  mTxn->AddEdit(OpAttachAsyncCompositable(Shadow(aLayer), aHandle));
924
0
}
925
926
void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager)
927
0
{
928
0
  mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager);
929
0
  mShadowManager->SetForwarder(this);
930
0
}
931
932
void ShadowLayerForwarder::StopReceiveAsyncParentMessge()
933
0
{
934
0
  if (!IPCOpen()) {
935
0
    return;
936
0
  }
937
0
  mShadowManager->SetForwarder(nullptr);
938
0
}
939
940
void ShadowLayerForwarder::ClearCachedResources()
941
0
{
942
0
  if (!IPCOpen()) {
943
0
    return;
944
0
  }
945
0
  mShadowManager->SendClearCachedResources();
946
0
}
947
948
void ShadowLayerForwarder::ScheduleComposite()
949
0
{
950
0
  if (!IPCOpen()) {
951
0
    return;
952
0
  }
953
0
  mShadowManager->SendScheduleComposite();
954
0
}
955
956
bool
957
IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
958
0
{
959
0
  return aSurface.type() != SurfaceDescriptor::T__None &&
960
0
         aSurface.type() != SurfaceDescriptor::Tnull_t;
961
0
}
962
963
uint8_t*
964
GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor)
965
0
{
966
0
  MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor));
967
0
  MOZ_RELEASE_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer, "GFX: surface descriptor is not the right type.");
968
0
969
0
  auto memOrShmem = aDescriptor.get_SurfaceDescriptorBuffer().data();
970
0
  if (memOrShmem.type() == MemoryOrShmem::TShmem) {
971
0
    return memOrShmem.get_Shmem().get<uint8_t>();
972
0
  } else {
973
0
    return reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
974
0
  }
975
0
}
976
977
already_AddRefed<gfx::DataSourceSurface>
978
GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor)
979
0
{
980
0
  if (aDescriptor.type() != SurfaceDescriptor::TSurfaceDescriptorBuffer) {
981
0
    return nullptr;
982
0
  }
983
0
  uint8_t* data = GetAddressFromDescriptor(aDescriptor);
984
0
  auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
985
0
  uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
986
0
  return gfx::Factory::CreateWrappingDataSourceSurface(data, stride, rgb.size(),
987
0
                                                       rgb.format());
988
0
}
989
990
already_AddRefed<gfx::DrawTarget>
991
GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend)
992
0
{
993
0
  uint8_t* data = GetAddressFromDescriptor(aDescriptor);
994
0
  auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
995
0
  uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
996
0
  return gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
997
0
                                               data, rgb.size(),
998
0
                                               stride, rgb.format());
999
0
}
1000
1001
void
1002
DestroySurfaceDescriptor(IShmemAllocator* aAllocator, SurfaceDescriptor* aSurface)
1003
0
{
1004
0
  MOZ_ASSERT(aSurface);
1005
0
1006
0
  SurfaceDescriptorBuffer& desc = aSurface->get_SurfaceDescriptorBuffer();
1007
0
  switch (desc.data().type()) {
1008
0
    case MemoryOrShmem::TShmem: {
1009
0
      aAllocator->DeallocShmem(desc.data().get_Shmem());
1010
0
      break;
1011
0
    }
1012
0
    case MemoryOrShmem::Tuintptr_t: {
1013
0
      uint8_t* ptr = (uint8_t*)desc.data().get_uintptr_t();
1014
0
      GfxMemoryImageReporter::WillFree(ptr);
1015
0
      delete [] ptr;
1016
0
      break;
1017
0
    }
1018
0
    default:
1019
0
      MOZ_CRASH("surface type not implemented!");
1020
0
  }
1021
0
  *aSurface = SurfaceDescriptor();
1022
0
}
1023
1024
bool
1025
ShadowLayerForwarder::AllocSurfaceDescriptor(const gfx::IntSize& aSize,
1026
                                             gfxContentType aContent,
1027
                                             SurfaceDescriptor* aBuffer)
1028
0
{
1029
0
  if (!IPCOpen()) {
1030
0
    return false;
1031
0
  }
1032
0
  return AllocSurfaceDescriptorWithCaps(aSize, aContent, DEFAULT_BUFFER_CAPS, aBuffer);
1033
0
}
1034
1035
bool
1036
ShadowLayerForwarder::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
1037
                                                     gfxContentType aContent,
1038
                                                     uint32_t aCaps,
1039
                                                     SurfaceDescriptor* aBuffer)
1040
0
{
1041
0
  if (!IPCOpen()) {
1042
0
    return false;
1043
0
  }
1044
0
  gfx::SurfaceFormat format =
1045
0
    gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
1046
0
  size_t size = ImageDataSerializer::ComputeRGBBufferSize(aSize, format);
1047
0
  if (!size) {
1048
0
    return false;
1049
0
  }
1050
0
1051
0
  MemoryOrShmem bufferDesc;
1052
0
  if (GetTextureForwarder()->IsSameProcess()) {
1053
0
    uint8_t* data = new (std::nothrow) uint8_t[size];
1054
0
    if (!data) {
1055
0
      return false;
1056
0
    }
1057
0
    GfxMemoryImageReporter::DidAlloc(data);
1058
0
    memset(data, 0, size);
1059
0
    bufferDesc = reinterpret_cast<uintptr_t>(data);
1060
0
  } else {
1061
0
1062
0
    mozilla::ipc::Shmem shmem;
1063
0
    if (!GetTextureForwarder()->AllocUnsafeShmem(size, OptimalShmemType(), &shmem)) {
1064
0
      return false;
1065
0
    }
1066
0
1067
0
    bufferDesc = shmem;
1068
0
  }
1069
0
1070
0
  // Use an intermediate buffer by default. Skipping the intermediate buffer is
1071
0
  // only possible in certain configurations so let's keep it simple here for now.
1072
0
  const bool hasIntermediateBuffer = true;
1073
0
  *aBuffer = SurfaceDescriptorBuffer(RGBDescriptor(aSize, format, hasIntermediateBuffer),
1074
0
                                     bufferDesc);
1075
0
1076
0
  return true;
1077
0
}
1078
1079
/* static */ bool
1080
ShadowLayerForwarder::IsShmem(SurfaceDescriptor* aSurface)
1081
0
{
1082
0
  return aSurface && (aSurface->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer)
1083
0
      && (aSurface->get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::TShmem);
1084
0
}
1085
1086
void
1087
ShadowLayerForwarder::DestroySurfaceDescriptor(SurfaceDescriptor* aSurface)
1088
0
{
1089
0
  MOZ_ASSERT(aSurface);
1090
0
  MOZ_ASSERT(IPCOpen());
1091
0
  if (!IPCOpen() || !aSurface) {
1092
0
    return;
1093
0
  }
1094
0
1095
0
  ::mozilla::layers::DestroySurfaceDescriptor(GetTextureForwarder(), aSurface);
1096
0
}
1097
1098
void
1099
ShadowLayerForwarder::UpdateFwdTransactionId()
1100
0
{
1101
0
  auto compositorBridge = GetCompositorBridgeChild();
1102
0
  if (compositorBridge) {
1103
0
    compositorBridge->UpdateFwdTransactionId();
1104
0
  }
1105
0
}
1106
1107
uint64_t
1108
ShadowLayerForwarder::GetFwdTransactionId()
1109
0
{
1110
0
  auto compositorBridge = GetCompositorBridgeChild();
1111
0
  MOZ_DIAGNOSTIC_ASSERT(compositorBridge);
1112
0
  return compositorBridge ? compositorBridge->GetFwdTransactionId() : 0;
1113
0
}
1114
1115
CompositorBridgeChild*
1116
ShadowLayerForwarder::GetCompositorBridgeChild()
1117
0
{
1118
0
  if (mCompositorBridgeChild) {
1119
0
    return mCompositorBridgeChild;
1120
0
  }
1121
0
  if (!mShadowManager) {
1122
0
    return nullptr;
1123
0
  }
1124
0
  mCompositorBridgeChild = static_cast<CompositorBridgeChild*>(mShadowManager->Manager());
1125
0
  return mCompositorBridgeChild;
1126
0
}
1127
1128
void
1129
ShadowLayerForwarder::SyncWithCompositor()
1130
0
{
1131
0
  auto compositorBridge = GetCompositorBridgeChild();
1132
0
  if (compositorBridge && compositorBridge->IPCOpen()) {
1133
0
    compositorBridge->SendSyncWithCompositor();
1134
0
  }
1135
0
}
1136
1137
void
1138
ShadowLayerForwarder::ReleaseCompositable(const CompositableHandle& aHandle)
1139
0
{
1140
0
  AssertInForwarderThread();
1141
0
  if (!DestroyInTransaction(aHandle)) {
1142
0
    if (!IPCOpen()) {
1143
0
      return;
1144
0
    }
1145
0
    mShadowManager->SendReleaseCompositable(aHandle);
1146
0
  }
1147
0
  mCompositables.Remove(aHandle.Value());
1148
0
}
1149
1150
void
1151
ShadowLayerForwarder::SynchronouslyShutdown()
1152
0
{
1153
0
  if (IPCOpen()) {
1154
0
    mShadowManager->SendShutdownSync();
1155
0
    mShadowManager->MarkDestroyed();
1156
0
  }
1157
0
}
1158
1159
ShadowableLayer::~ShadowableLayer()
1160
0
{
1161
0
  if (mShadow) {
1162
0
    mForwarder->ReleaseLayer(GetShadow());
1163
0
  }
1164
0
}
1165
1166
} // namespace layers
1167
} // namespace mozilla