Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/layers/TextureHost.h
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
#ifndef MOZILLA_GFX_TEXTUREHOST_H
8
#define MOZILLA_GFX_TEXTUREHOST_H
9
10
#include <functional>
11
#include <stddef.h>                     // for size_t
12
#include <stdint.h>                     // for uint64_t, uint32_t, uint8_t
13
#include "gfxTypes.h"
14
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
15
#include "mozilla/Attributes.h"         // for override
16
#include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed, etc
17
#include "mozilla/gfx/2D.h"             // for DataSourceSurface
18
#include "mozilla/gfx/Point.h"          // for IntSize, IntPoint
19
#include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
20
#include "mozilla/layers/Compositor.h"  // for Compositor
21
#include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
22
#include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
23
#include "mozilla/layers/LayersSurfaces.h"
24
#include "mozilla/mozalloc.h"           // for operator delete
25
#include "mozilla/Range.h"
26
#include "mozilla/UniquePtr.h"          // for UniquePtr
27
#include "mozilla/webrender/WebRenderTypes.h"
28
#include "nsCOMPtr.h"                   // for already_AddRefed
29
#include "nsDebug.h"                    // for NS_WARNING
30
#include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
31
#include "nsRegion.h"                   // for nsIntRegion
32
#include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
33
#include "nscore.h"                     // for nsACString
34
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
35
#include "mozilla/gfx/Rect.h"
36
37
class MacIOSurface;
38
namespace mozilla {
39
namespace ipc {
40
class Shmem;
41
} // namespace ipc
42
43
namespace wr {
44
class DisplayListBuilder;
45
class TransactionBuilder;
46
}
47
48
namespace layers {
49
50
class BufferDescriptor;
51
class BufferTextureHost;
52
class Compositor;
53
class CompositableParentManager;
54
class ReadLockDescriptor;
55
class CompositorBridgeParent;
56
class SurfaceDescriptor;
57
class HostIPCAllocator;
58
class ISurfaceAllocator;
59
class MacIOSurfaceTextureHostOGL;
60
class TextureHostOGL;
61
class TextureReadLock;
62
class TextureSourceOGL;
63
class TextureSourceD3D11;
64
class TextureSourceBasic;
65
class DataTextureSource;
66
class PTextureParent;
67
class TextureParent;
68
class WebRenderTextureHost;
69
class WrappingTextureSourceYCbCrBasic;
70
71
/**
72
 * A view on a TextureHost where the texture is internally represented as tiles
73
 * (contrast with a tiled buffer, where each texture is a tile). For iteration by
74
 * the texture's buffer host.
75
 * This is only useful when the underlying surface is too big to fit in one
76
 * device texture, which forces us to split it in smaller parts.
77
 * Tiled Compositable is a different thing.
78
 */
79
class BigImageIterator
80
{
81
public:
82
  virtual void BeginBigImageIteration() = 0;
83
0
  virtual void EndBigImageIteration() {};
84
  virtual gfx::IntRect GetTileRect() = 0;
85
  virtual size_t GetTileCount() = 0;
86
  virtual bool NextTile() = 0;
87
};
88
89
/**
90
 * TextureSource is the interface for texture objects that can be composited
91
 * by a given compositor backend. Since the drawing APIs are different
92
 * between backends, the TextureSource interface is split into different
93
 * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
94
 * access to these interfaces.
95
 *
96
 * This class is used on the compositor side.
97
 */
98
class TextureSource: public RefCounted<TextureSource>
99
{
100
public:
101
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureSource)
102
103
  TextureSource();
104
105
  virtual ~TextureSource();
106
107
  virtual const char* Name() const = 0;
108
109
  /**
110
   * Should be overridden in order to deallocate the data that is associated
111
   * with the rendering backend, such as GL textures.
112
   */
113
0
  virtual void DeallocateDeviceData() {}
114
115
116
  /**
117
   * Return the size of the texture in texels.
118
   * If this is a tile iterator, GetSize must return the size of the current tile.
119
   */
120
  virtual gfx::IntSize GetSize() const = 0;
121
122
  /**
123
   * Return the pixel format of this texture
124
   */
125
0
  virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::UNKNOWN; }
126
127
  /**
128
   * Cast to a TextureSource for for each backend..
129
   */
130
0
  virtual TextureSourceOGL* AsSourceOGL() {
131
0
    gfxCriticalNote << "Failed to cast " << Name() << " into a TextureSourceOGL";
132
0
    return nullptr;
133
0
  }
134
0
  virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
135
0
  virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
136
  /**
137
   * Cast to a DataTextureSurce.
138
   */
139
0
  virtual DataTextureSource* AsDataTextureSource() { return nullptr; }
140
0
  virtual WrappingTextureSourceYCbCrBasic* AsWrappingTextureSourceYCbCrBasic() { return nullptr; }
141
142
  /**
143
   * Overload this if the TextureSource supports big textures that don't fit in
144
   * one device texture and must be tiled internally.
145
   */
146
0
  virtual BigImageIterator* AsBigImageIterator() { return nullptr; }
147
148
0
  virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) {}
149
150
0
  virtual void Unbind() {}
151
152
0
  void SetNextSibling(TextureSource* aTexture) { mNextSibling = aTexture; }
153
154
0
  TextureSource* GetNextSibling() const { return mNextSibling; }
155
156
  /**
157
   * In some rare cases we currently need to consider a group of textures as one
158
   * TextureSource, that can be split in sub-TextureSources.
159
   */
160
  TextureSource* GetSubSource(int index)
161
0
  {
162
0
    switch (index) {
163
0
      case 0: return this;
164
0
      case 1: return GetNextSibling();
165
0
      case 2: return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
166
0
    }
167
0
    return nullptr;
168
0
  }
169
170
0
  void AddCompositableRef() { ++mCompositableCount; }
171
172
0
  void ReleaseCompositableRef() {
173
0
    --mCompositableCount;
174
0
    MOZ_ASSERT(mCompositableCount >= 0);
175
0
  }
176
177
  // When iterating as a BigImage, this creates temporary TextureSources wrapping
178
  // individual tiles.
179
0
  virtual RefPtr<TextureSource> ExtractCurrentTile() {
180
0
    NS_WARNING("Implementation does not expose tile sources");
181
0
    return nullptr;
182
0
  }
183
184
  int NumCompositableRefs() const { return mCompositableCount; }
185
186
  // Some texture sources could wrap the cpu buffer to gpu directly. Then,
187
  // we could get better performance of texture uploading.
188
0
  virtual bool IsDirectMap() { return false; }
189
  // The direct-map cpu buffer should be alive when gpu uses it. And it
190
  // should not be updated while gpu reads it. This Sync() function
191
  // implements this synchronized behavior by allowing us to check if
192
  // the GPU is done with the texture, and block on it if aBlocking is
193
  // true.
194
0
  virtual bool Sync(bool aBlocking) { return true; }
195
196
protected:
197
198
  RefPtr<TextureSource> mNextSibling;
199
  int mCompositableCount;
200
};
201
202
/// Equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
203
/// ReleaseCompositableRef in addition to the usual AddRef and Release.
204
///
205
/// The semantoics of these CompositableTextureRefs are important because they
206
/// are used both as a synchronization/safety mechanism, and as an optimization
207
/// mechanism. They are also tricky and subtle because we use them in a very
208
/// implicit way (assigning to a CompositableTextureRef is less visible than
209
/// explicitly calling a method or whatnot).
210
/// It is Therefore important to be careful about the way we use this tool.
211
///
212
/// CompositableTextureRef is a mechanism that lets us count how many compositables
213
/// are using a given texture (for TextureSource and TextureHost).
214
/// We use it to run specific code when a texture is not used anymore, and also
215
/// we trigger fast paths on some operations when we can see that the texture's
216
/// CompositableTextureRef counter is equal to 1 (the texture is not shared
217
/// between compositables).
218
/// This means that it is important to observe the following rules:
219
/// * CompositableHosts that receive UseTexture and similar messages *must* store
220
/// all of the TextureHosts they receive in CompositableTextureRef slots for as
221
/// long as they may be using them.
222
/// * CompositableHosts must store each texture in a *single* CompositableTextureRef
223
/// slot to ensure that the counter properly reflects how many compositables are
224
/// using the texture.
225
/// If a compositable needs to hold two references to a given texture (for example
226
/// to have a pointer to the current texture in a list of textures that may be
227
/// used), it can hold its extra references with RefPtr or whichever pointer type
228
/// makes sense.
229
template<typename T>
230
class CompositableTextureRef {
231
public:
232
0
  CompositableTextureRef() {}
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::CompositableTextureRef()
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::CompositableTextureRef()
233
234
  explicit CompositableTextureRef(const CompositableTextureRef& aOther)
235
0
  {
236
0
    *this = aOther;
237
0
  }
238
239
  explicit CompositableTextureRef(T* aOther)
240
0
  {
241
0
    *this = aOther;
242
0
  }
243
244
  ~CompositableTextureRef()
245
0
  {
246
0
    if (mRef) {
247
0
      mRef->ReleaseCompositableRef();
248
0
    }
249
0
  }
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::~CompositableTextureRef()
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::~CompositableTextureRef()
250
251
  CompositableTextureRef& operator=(const CompositableTextureRef& aOther)
252
0
  {
253
0
    if (aOther.get()) {
254
0
      aOther->AddCompositableRef();
255
0
    }
256
0
    if (mRef) {
257
0
      mRef->ReleaseCompositableRef();
258
0
    }
259
0
    mRef = aOther.get();
260
0
    return *this;
261
0
  }
262
263
  CompositableTextureRef& operator=(T* aOther)
264
0
  {
265
0
    if (aOther) {
266
0
      aOther->AddCompositableRef();
267
0
    }
268
0
    if (mRef) {
269
0
      mRef->ReleaseCompositableRef();
270
0
    }
271
0
    mRef = aOther;
272
0
    return *this;
273
0
  }
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::operator=(mozilla::layers::TextureSource*)
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::operator=(mozilla::layers::TextureHost*)
274
275
0
  T* get() const { return mRef; }
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::get() const
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::get() const
276
0
  operator T*() const { return mRef; }
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::operator mozilla::layers::TextureSource*() const
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::operator mozilla::layers::TextureHost*() const
277
0
  T* operator->() const { return mRef; }
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureHost>::operator->() const
Unexecuted instantiation: mozilla::layers::CompositableTextureRef<mozilla::layers::TextureSource>::operator->() const
278
  T& operator*() const { return *mRef; }
279
280
private:
281
  RefPtr<T> mRef;
282
};
283
284
typedef CompositableTextureRef<TextureSource> CompositableTextureSourceRef;
285
typedef CompositableTextureRef<TextureHost> CompositableTextureHostRef;
286
287
/**
288
 * Interface for TextureSources that can be updated from a DataSourceSurface.
289
 *
290
 * All backend should implement at least one DataTextureSource.
291
 */
292
class DataTextureSource : public TextureSource
293
{
294
public:
295
  DataTextureSource()
296
    : mOwner(0)
297
    , mUpdateSerial(0)
298
0
  {}
299
300
0
  virtual const char* Name() const override { return "DataTextureSource"; }
301
302
0
  virtual DataTextureSource* AsDataTextureSource() override { return this; }
303
304
  /**
305
   * Upload a (portion of) surface to the TextureSource.
306
   *
307
   * The DataTextureSource doesn't own aSurface, although it owns and manage
308
   * the device texture it uploads to internally.
309
   */
310
  virtual bool Update(gfx::DataSourceSurface* aSurface,
311
                      nsIntRegion* aDestRegion = nullptr,
312
                      gfx::IntPoint* aSrcOffset = nullptr) = 0;
313
314
  /**
315
   * A facility to avoid reuploading when it is not necessary.
316
   * The caller of Update can use GetUpdateSerial to see if the number has changed
317
   * since last update, and call SetUpdateSerial after each successful update.
318
   * The caller is responsible for managing the update serial except when the
319
   * texture data is deallocated in which case the TextureSource should always
320
   * reset the update serial to zero.
321
   */
322
  uint32_t GetUpdateSerial() const { return mUpdateSerial; }
323
0
  void SetUpdateSerial(uint32_t aValue) { mUpdateSerial = aValue; }
324
325
  // By default at least set the update serial to zero.
326
  // overloaded versions should do that too.
327
  virtual void DeallocateDeviceData() override
328
0
  {
329
0
    SetUpdateSerial(0);
330
0
  }
331
332
#ifdef DEBUG
333
  /**
334
   * Provide read access to the data as a DataSourceSurface.
335
   *
336
   * This is expected to be very slow and should be used for mostly debugging.
337
   * XXX - implement everywhere and make it pure virtual.
338
   */
339
  virtual already_AddRefed<gfx::DataSourceSurface> ReadBack() { return nullptr; };
340
#endif
341
342
  void SetOwner(TextureHost* aOwner)
343
  {
344
    auto newOwner = (uintptr_t)aOwner;
345
    if (newOwner != mOwner) {
346
      mOwner = newOwner;
347
      SetUpdateSerial(0);
348
    }
349
  }
350
351
  bool IsOwnedBy(TextureHost* aOwner) const { return mOwner == (uintptr_t)aOwner; }
352
353
  bool HasOwner() const { return !IsOwnedBy(nullptr); }
354
355
private:
356
  // We store mOwner as an integer rather than as a pointer to make it clear
357
  // it is not intended to be dereferenced.
358
  uintptr_t mOwner;
359
  uint32_t mUpdateSerial;
360
};
361
362
/**
363
 * TextureHost is a thin abstraction over texture data that need to be shared
364
 * between the content process and the compositor process. It is the
365
 * compositor-side half of a TextureClient/TextureHost pair. A corresponding
366
 * TextureClient lives on the content-side.
367
 *
368
 * TextureHost only knows how to deserialize or synchronize generic image data
369
 * (SurfaceDescriptor) and provide access to one or more TextureSource objects
370
 * (these provide the necessary APIs for compositor backends to composite the
371
 * image).
372
 *
373
 * A TextureHost implementation corresponds to one SurfaceDescriptor type, as
374
 * opposed to TextureSource that corresponds to device textures.
375
 * This means that for YCbCr planes, even though they are represented as
376
 * 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
377
 * because the 3 planes are stored in the same buffer of shared memory, before
378
 * they are uploaded separately.
379
 *
380
 * There is always one and only one TextureHost per TextureClient, and the
381
 * TextureClient/Host pair only owns one buffer of image data through its
382
 * lifetime. This means that the lifetime of the underlying shared data
383
 * matches the lifetime of the TextureClient/Host pair. It also means
384
 * TextureClient/Host do not implement double buffering, which is the
385
 * reponsibility of the compositable (which would use two Texture pairs).
386
 *
387
 * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
388
 *
389
 */
390
class TextureHost
391
  : public AtomicRefCountedWithFinalize<TextureHost>
392
{
393
  /**
394
   * Called once, just before the destructor.
395
   *
396
   * Here goes the shut-down code that uses virtual methods.
397
   * Must only be called by Release().
398
   */
399
  void Finalize();
400
401
  friend class AtomicRefCountedWithFinalize<TextureHost>;
402
public:
403
  explicit TextureHost(TextureFlags aFlags);
404
405
protected:
406
  virtual ~TextureHost();
407
408
public:
409
  /**
410
   * Factory method.
411
   */
412
  static already_AddRefed<TextureHost> Create(
413
    const SurfaceDescriptor& aDesc,
414
    const ReadLockDescriptor& aReadLock,
415
    ISurfaceAllocator* aDeallocator,
416
    LayersBackend aBackend,
417
    TextureFlags aFlags,
418
    wr::MaybeExternalImageId& aExternalImageId);
419
420
  /**
421
   * Lock the texture host for compositing.
422
   */
423
  virtual bool Lock() { return true; }
424
  /**
425
   * Unlock the texture host after compositing. Lock() and Unlock() should be
426
   * called in pair.
427
   */
428
0
  virtual void Unlock() {}
429
430
  /**
431
   * Lock the texture host for compositing without using compositor.
432
   */
433
0
  virtual bool LockWithoutCompositor() { return true; }
434
  /**
435
   * Similar to Unlock(), but it should be called with LockWithoutCompositor().
436
   */
437
0
  virtual void UnlockWithoutCompositor() {}
438
439
  /**
440
   * Note that the texture host format can be different from its corresponding
441
   * texture source's. For example a ShmemTextureHost can have the ycbcr
442
   * format and produce 3 "alpha" textures sources.
443
   */
444
  virtual gfx::SurfaceFormat GetFormat() const = 0;
445
  /**
446
   * Return the format used for reading the texture.
447
   * Apple's YCBCR_422 is R8G8B8X8.
448
   */
449
0
  virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); }
450
451
0
  virtual YUVColorSpace GetYUVColorSpace() const { return YUVColorSpace::UNKNOWN; }
452
453
  /**
454
   * Return the bit depth of the image. Used with YUV textures.
455
   */
456
0
  virtual uint32_t GetBitDepth() const { return 8; }
457
458
  /**
459
   * Called during the transaction. The TextureSource may or may not be composited.
460
   *
461
   * Note that this is called outside of lock/unlock.
462
   */
463
0
  virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
464
465
  /**
466
   * Called at composition time, just before compositing the TextureSource composited.
467
   *
468
   * Note that this is called only withing lock/unlock.
469
   */
470
  virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) = 0;
471
472
  /**
473
   * Called when preparing the rendering pipeline for advanced-layers. This is
474
   * a lockless version of BindTextureSource.
475
   */
476
0
  virtual bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) {
477
0
    return false;
478
0
  }
479
480
  /**
481
   * Called when another TextureHost will take over.
482
   */
483
  virtual void UnbindTextureSource();
484
485
  /**
486
   * Is called before compositing if the shared data has changed since last
487
   * composition.
488
   * This method should be overload in cases like when we need to do a texture
489
   * upload for example.
490
   *
491
   * @param aRegion The region that has been changed, if nil, it means that the
492
   * entire surface should be updated.
493
   */
494
   void Updated(const nsIntRegion* aRegion = nullptr);
495
496
  /**
497
   * Sets this TextureHost's compositor. A TextureHost can change compositor
498
   * on certain occasions, in particular if it belongs to an async Compositable.
499
   * aCompositor can be null, in which case the TextureHost must cleanup  all
500
   * of its device textures.
501
   *
502
   * Setting mProvider from this callback implicitly causes the texture to
503
   * be locked for an extra frame after being detached from a compositable.
504
   */
505
  virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) {}
506
507
  /**
508
   * Should be overridden in order to deallocate the data that is associated
509
   * with the rendering backend, such as GL textures.
510
   */
511
0
  virtual void DeallocateDeviceData() {}
512
513
  /**
514
   * Should be overridden in order to deallocate the data that is shared with
515
   * the content side, such as shared memory.
516
   */
517
0
  virtual void DeallocateSharedData() {}
518
519
  /**
520
   * Should be overridden in order to force the TextureHost to drop all references
521
   * to it's shared data.
522
   *
523
   * This is important to ensure the correctness of the deallocation protocol.
524
   */
525
0
  virtual void ForgetSharedData() {}
526
527
  virtual gfx::IntSize GetSize() const = 0;
528
529
  /**
530
   * Should be overridden if TextureHost supports crop rect.
531
   */
532
0
  virtual void SetCropRect(nsIntRect aCropRect) {}
533
534
  /**
535
   * Debug facility.
536
   * XXX - cool kids use Moz2D. See bug 882113.
537
   */
538
  virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() = 0;
539
540
  /**
541
   * XXX - Flags should only be set at creation time, this will be removed.
542
   */
543
0
  void SetFlags(TextureFlags aFlags) { mFlags = aFlags; }
544
545
  /**
546
   * XXX - Flags should only be set at creation time, this will be removed.
547
   */
548
0
  void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
549
550
0
  TextureFlags GetFlags() { return mFlags; }
551
552
  /**
553
   * Allocate and deallocate a TextureParent actor.
554
   *
555
   * TextureParent< is an implementation detail of TextureHost that is not
556
   * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
557
   * are for use with the managing IPDL protocols only (so that they can
558
   * implement AllocPTextureParent and DeallocPTextureParent).
559
   */
560
  static PTextureParent* CreateIPDLActor(HostIPCAllocator* aAllocator,
561
                                         const SurfaceDescriptor& aSharedData,
562
                                         const ReadLockDescriptor& aDescriptor,
563
                                         LayersBackend aLayersBackend,
564
                                         TextureFlags aFlags,
565
                                         uint64_t aSerial,
566
                                         const wr::MaybeExternalImageId& aExternalImageId);
567
  static bool DestroyIPDLActor(PTextureParent* actor);
568
569
  /**
570
   * Destroy the TextureChild/Parent pair.
571
   */
572
  static bool SendDeleteIPDLActor(PTextureParent* actor);
573
574
  static void ReceivedDestroy(PTextureParent* actor);
575
576
  /**
577
   * Get the TextureHost corresponding to the actor passed in parameter.
578
   */
579
  static TextureHost* AsTextureHost(PTextureParent* actor);
580
581
  static uint64_t GetTextureSerial(PTextureParent* actor);
582
583
  /**
584
   * Return a pointer to the IPDLActor.
585
   *
586
   * This is to be used with IPDL messages only. Do not store the returned
587
   * pointer.
588
   */
589
  PTextureParent* GetIPDLActor();
590
591
  // If a texture host holds a reference to shmem, it should override this method
592
  // to forget about the shmem _without_ releasing it.
593
0
  virtual void OnShutdown() {}
594
595
  // Forget buffer actor. Used only for hacky fix for bug 966446.
596
0
  virtual void ForgetBufferActor() {}
597
598
  virtual const char *Name() { return "TextureHost"; }
599
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
600
601
  /**
602
   * Indicates whether the TextureHost implementation is backed by an
603
   * in-memory buffer. The consequence of this is that locking the
604
   * TextureHost does not contend with locking the texture on the client side.
605
   */
606
0
  virtual bool HasIntermediateBuffer() const { return false; }
607
608
0
  void AddCompositableRef() { ++mCompositableCount; }
609
610
  void ReleaseCompositableRef()
611
0
  {
612
0
    --mCompositableCount;
613
0
    MOZ_ASSERT(mCompositableCount >= 0);
614
0
    if (mCompositableCount == 0) {
615
0
      UnbindTextureSource();
616
0
      // Send mFwdTransactionId to client side if necessary.
617
0
      NotifyNotUsed();
618
0
    }
619
0
  }
620
621
0
  int NumCompositableRefs() const { return mCompositableCount; }
622
623
  void SetLastFwdTransactionId(uint64_t aTransactionId);
624
625
  void DeserializeReadLock(const ReadLockDescriptor& aDesc,
626
                           ISurfaceAllocator* aAllocator);
627
  void SetReadLocked();
628
629
0
  TextureReadLock* GetReadLock() { return mReadLock; }
630
631
0
  virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
632
0
  virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() { return nullptr; }
633
0
  virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
634
635
  // Create the corresponding RenderTextureHost type of this texture, and
636
  // register the RenderTextureHost into render thread.
637
  virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId)
638
0
  {
639
0
    MOZ_RELEASE_ASSERT(false, "No CreateRenderTexture() implementation for this TextureHost type.");
640
0
  }
641
642
  /// Returns the number of actual textures that will be used to render this.
643
  /// For example in a lot of YUV cases it will be 3
644
0
  virtual uint32_t NumSubTextures() const { return 1; }
645
646
  enum ResourceUpdateOp {
647
    ADD_IMAGE,
648
    UPDATE_IMAGE,
649
  };
650
651
  // Add all necessary TextureHost informations to the resource update queue.
652
  virtual void PushResourceUpdates(wr::TransactionBuilder& aResources,
653
                                   ResourceUpdateOp aOp,
654
                                   const Range<wr::ImageKey>& aImageKeys,
655
                                   const wr::ExternalImageId& aExtID)
656
0
  {
657
0
    MOZ_ASSERT_UNREACHABLE("Unimplemented");
658
0
  }
659
660
  // Put all necessary WR commands into DisplayListBuilder for this textureHost rendering.
661
  virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
662
                                const wr::LayoutRect& aBounds,
663
                                const wr::LayoutRect& aClip,
664
                                wr::ImageRendering aFilter,
665
                                const Range<wr::ImageKey>& aKeys)
666
0
  {
667
0
    MOZ_ASSERT_UNREACHABLE("No PushDisplayItems() implementation for this TextureHost type.");
668
0
  }
669
670
  /**
671
   * Some API's can use the cross-process IOSurface directly, such as OpenVR
672
   */
673
0
  virtual MacIOSurface* GetMacIOSurface() { return nullptr; }
674
675
0
  virtual bool IsDirectMap() { return false; }
676
677
0
  virtual bool SupportsWrNativeTexture() { return false; }
678
679
protected:
680
  virtual void ReadUnlock();
681
682
  void RecycleTexture(TextureFlags aFlags);
683
684
0
  virtual void MaybeNotifyUnlocked() {}
685
686
0
  virtual void UpdatedInternal(const nsIntRegion *Region) {}
687
688
  /**
689
   * Called when mCompositableCount becomes 0.
690
   */
691
  virtual void NotifyNotUsed();
692
693
  // for Compositor.
694
  void CallNotifyNotUsed();
695
696
  PTextureParent* mActor;
697
  RefPtr<TextureSourceProvider> mProvider;
698
  RefPtr<TextureReadLock> mReadLock;
699
  TextureFlags mFlags;
700
  int mCompositableCount;
701
  uint64_t mFwdTransactionId;
702
  bool mReadLocked;
703
704
  friend class Compositor;
705
  friend class TextureParent;
706
  friend class TiledLayerBufferComposite;
707
  friend class TextureSourceProvider;
708
};
709
710
/**
711
 * TextureHost that wraps a random access buffer such as a Shmem or some raw
712
 * memory.
713
 *
714
 * This TextureHost is backend-independent and the backend-specific bits are
715
 * in the TextureSource.
716
 * This class must be inherited to implement GetBuffer and DeallocSharedData
717
 * (see ShmemTextureHost and MemoryTextureHost)
718
 *
719
 * Uploads happen when Lock is called.
720
 *
721
 * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
722
 */
723
class BufferTextureHost : public TextureHost
724
{
725
public:
726
  BufferTextureHost(const BufferDescriptor& aDescriptor, TextureFlags aFlags);
727
728
  ~BufferTextureHost();
729
730
  virtual uint8_t* GetBuffer() = 0;
731
732
  virtual size_t GetBufferSize() = 0;
733
734
  virtual bool Lock() override;
735
736
  virtual void Unlock() override;
737
738
  virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
739
740
  virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
741
  virtual bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) override;
742
743
  virtual void UnbindTextureSource() override;
744
745
  virtual void DeallocateDeviceData() override;
746
747
  virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
748
749
  /**
750
   * Return the format that is exposed to the compositor when calling
751
   * BindTextureSource.
752
   *
753
   * If the shared format is YCbCr and the compositor does not support it,
754
   * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
755
   */
756
  virtual gfx::SurfaceFormat GetFormat() const override;
757
758
  virtual YUVColorSpace GetYUVColorSpace() const override;
759
760
  virtual uint32_t GetBitDepth() const override;
761
762
  virtual gfx::IntSize GetSize() const override { return mSize; }
763
764
  virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
765
766
  virtual bool HasIntermediateBuffer() const override { return mHasIntermediateBuffer; }
767
768
  virtual BufferTextureHost* AsBufferTextureHost() override { return this; }
769
770
0
  const BufferDescriptor& GetBufferDescriptor() const { return mDescriptor; }
771
772
  virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
773
774
  virtual uint32_t NumSubTextures() const override;
775
776
  virtual void PushResourceUpdates(wr::TransactionBuilder& aResources,
777
                                   ResourceUpdateOp aOp,
778
                                   const Range<wr::ImageKey>& aImageKeys,
779
                                   const wr::ExternalImageId& aExtID) override;
780
781
  virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
782
                                const wr::LayoutRect& aBounds,
783
                                const wr::LayoutRect& aClip,
784
                                wr::ImageRendering aFilter,
785
                                const Range<wr::ImageKey>& aImageKeys) override;
786
787
  virtual void ReadUnlock() override;
788
  virtual bool IsDirectMap() override { return mFirstSource && mFirstSource->IsDirectMap(); };
789
790
0
  bool CanUnlock() { return !mFirstSource || mFirstSource->Sync(false); }
791
792
protected:
793
  bool Upload(nsIntRegion *aRegion = nullptr);
794
  bool UploadIfNeeded();
795
  bool MaybeUpload(nsIntRegion *aRegion);
796
  bool EnsureWrappingTextureSource();
797
798
  virtual void UpdatedInternal(const nsIntRegion* aRegion = nullptr) override;
799
  virtual void MaybeNotifyUnlocked() override;
800
801
802
  BufferDescriptor mDescriptor;
803
  RefPtr<Compositor> mCompositor;
804
  RefPtr<DataTextureSource> mFirstSource;
805
  nsIntRegion mMaybeUpdatedRegion;
806
  gfx::IntSize mSize;
807
  gfx::SurfaceFormat mFormat;
808
  uint32_t mUpdateSerial;
809
  bool mLocked;
810
  bool mNeedsFullUpdate;
811
  bool mHasIntermediateBuffer;
812
813
  class DataTextureSourceYCbCrBasic;
814
};
815
816
/**
817
 * TextureHost that wraps shared memory.
818
 * the corresponding texture on the client side is ShmemTextureClient.
819
 * This TextureHost is backend-independent.
820
 */
821
class ShmemTextureHost : public BufferTextureHost
822
{
823
public:
824
  ShmemTextureHost(const mozilla::ipc::Shmem& aShmem,
825
                   const BufferDescriptor& aDesc,
826
                   ISurfaceAllocator* aDeallocator,
827
                   TextureFlags aFlags);
828
829
protected:
830
  ~ShmemTextureHost();
831
832
public:
833
  virtual void DeallocateSharedData() override;
834
835
  virtual void ForgetSharedData() override;
836
837
  virtual uint8_t* GetBuffer() override;
838
839
  virtual size_t GetBufferSize() override;
840
841
  virtual const char *Name() override { return "ShmemTextureHost"; }
842
843
  virtual void OnShutdown() override;
844
845
protected:
846
  UniquePtr<mozilla::ipc::Shmem> mShmem;
847
  RefPtr<ISurfaceAllocator> mDeallocator;
848
};
849
850
/**
851
 * TextureHost that wraps raw memory.
852
 * The corresponding texture on the client side is MemoryTextureClient.
853
 * Can obviously not be used in a cross process setup.
854
 * This TextureHost is backend-independent.
855
 */
856
class MemoryTextureHost : public BufferTextureHost
857
{
858
public:
859
  MemoryTextureHost(uint8_t* aBuffer,
860
                    const BufferDescriptor& aDesc,
861
                    TextureFlags aFlags);
862
863
protected:
864
  ~MemoryTextureHost();
865
866
public:
867
  virtual void DeallocateSharedData() override;
868
869
  virtual void ForgetSharedData() override;
870
871
  virtual uint8_t* GetBuffer() override;
872
873
  virtual size_t GetBufferSize() override;
874
875
  virtual const char *Name() override { return "MemoryTextureHost"; }
876
877
protected:
878
  uint8_t* mBuffer;
879
};
880
881
class MOZ_STACK_CLASS AutoLockTextureHost
882
{
883
public:
884
  explicit AutoLockTextureHost(TextureHost* aTexture)
885
    : mTexture(aTexture)
886
  {
887
    mLocked = mTexture ? mTexture->Lock() : false;
888
  }
889
890
  ~AutoLockTextureHost()
891
  {
892
    if (mTexture && mLocked) {
893
      mTexture->Unlock();
894
    }
895
  }
896
897
  bool Failed() { return mTexture && !mLocked; }
898
899
private:
900
  RefPtr<TextureHost> mTexture;
901
  bool mLocked;
902
};
903
904
class MOZ_STACK_CLASS AutoLockTextureHostWithoutCompositor
905
{
906
public:
907
  explicit AutoLockTextureHostWithoutCompositor(TextureHost* aTexture)
908
    : mTexture(aTexture)
909
0
  {
910
0
    mLocked = mTexture ? mTexture->LockWithoutCompositor() : false;
911
0
  }
912
913
  ~AutoLockTextureHostWithoutCompositor()
914
0
  {
915
0
    if (mTexture && mLocked) {
916
0
      mTexture->UnlockWithoutCompositor();
917
0
    }
918
0
  }
919
920
0
  bool Failed() { return mTexture && !mLocked; }
921
922
private:
923
  RefPtr<TextureHost> mTexture;
924
  bool mLocked;
925
};
926
927
/**
928
 * This can be used as an offscreen rendering target by the compositor, and
929
 * subsequently can be used as a source by the compositor.
930
 */
931
class CompositingRenderTarget: public TextureSource
932
{
933
public:
934
935
  explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin)
936
    : mClearOnBind(false)
937
    , mOrigin(aOrigin)
938
    , mZNear(0)
939
    , mZFar(0)
940
    , mHasComplexProjection(false)
941
    , mEnableDepthBuffer(false)
942
0
  {}
943
0
  virtual ~CompositingRenderTarget() {}
944
945
0
  virtual const char* Name() const override { return "CompositingRenderTarget"; }
946
947
#ifdef MOZ_DUMP_PAINTING
948
  virtual already_AddRefed<gfx::DataSourceSurface> Dump(Compositor* aCompositor) { return nullptr; }
949
#endif
950
951
  /**
952
   * Perform a clear when recycling a non opaque surface.
953
   * The clear is deferred to when the render target is bound.
954
   */
955
0
  void ClearOnBind() {
956
0
    mClearOnBind = true;
957
0
  }
958
959
0
  const gfx::IntPoint& GetOrigin() const { return mOrigin; }
960
0
  gfx::IntRect GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
961
962
  /**
963
   * If a Projection matrix is set, then it is used for rendering to
964
   * this render target instead of generating one.  If no explicit
965
   * projection is set, Compositors are expected to generate an
966
   * orthogonal maaping that maps 0..1 to the full size of the render
967
   * target.
968
   */
969
0
  bool HasComplexProjection() const { return mHasComplexProjection; }
970
0
  void ClearProjection() { mHasComplexProjection = false; }
971
  void SetProjection(const gfx::Matrix4x4& aNewMatrix, bool aEnableDepthBuffer,
972
                     float aZNear, float aZFar)
973
0
  {
974
0
    mProjectionMatrix = aNewMatrix;
975
0
    mEnableDepthBuffer = aEnableDepthBuffer;
976
0
    mZNear = aZNear;
977
0
    mZFar = aZFar;
978
0
    mHasComplexProjection = true;
979
0
  }
980
  void GetProjection(gfx::Matrix4x4& aMatrix, bool& aEnableDepth, float& aZNear, float& aZFar)
981
0
  {
982
0
    MOZ_ASSERT(mHasComplexProjection);
983
0
    aMatrix = mProjectionMatrix;
984
0
    aEnableDepth = mEnableDepthBuffer;
985
0
    aZNear = mZNear;
986
0
    aZFar = mZFar;
987
0
  }
988
protected:
989
  bool mClearOnBind;
990
991
private:
992
  gfx::IntPoint mOrigin;
993
994
  gfx::Matrix4x4 mProjectionMatrix;
995
  float mZNear, mZFar;
996
  bool mHasComplexProjection;
997
  bool mEnableDepthBuffer;
998
};
999
1000
/**
1001
 * Creates a TextureHost that can be used with any of the existing backends
1002
 * Not all SurfaceDescriptor types are supported
1003
 */
1004
already_AddRefed<TextureHost>
1005
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
1006
                                    ISurfaceAllocator* aDeallocator,
1007
                                    LayersBackend aBackend,
1008
                                    TextureFlags aFlags);
1009
1010
} // namespace layers
1011
} // namespace mozilla
1012
1013
#endif