DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (56e7b9127e89)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_LAYERS_KNOWSCOMPOSITOR
#define MOZILLA_LAYERS_KNOWSCOMPOSITOR

#include "mozilla/layers/LayersTypes.h"  // for LayersBackend
#include "mozilla/layers/CompositorTypes.h"
#include "nsExpirationTracker.h"

namespace mozilla {
namespace layers {

class SyncObjectClient;
class TextureForwarder;
class LayersIPCActor;
class ImageBridgeChild;

/**
 * See ActiveResourceTracker below.
 */
class ActiveResource
{
public:
 virtual void NotifyInactive() = 0;
  nsExpirationState* GetExpirationState() { return &mExpirationState; }
  bool IsActivityTracked() { return mExpirationState.IsTracked(); }
private:
  nsExpirationState mExpirationState;
};

/**
 * A convenience class on top of nsExpirationTracker
 */
class ActiveResourceTracker : public nsExpirationTracker<ActiveResource, 3>
{
public:
  ActiveResourceTracker(uint32_t aExpirationCycle, const char* aName,
                        nsIEventTarget* aEventTarget)
  : nsExpirationTracker(aExpirationCycle, aName, aEventTarget)
  {}

  virtual void NotifyExpired(ActiveResource* aResource) override
  {
    RemoveObject(aResource);
    aResource->NotifyInactive();
  }
};

/**
 * An abstract interface for classes that are tied to a specific Compositor across
 * IPDL and uses TextureFactoryIdentifier to describe this Compositor.
 */
class KnowsCompositor
{
public:
  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING

  KnowsCompositor();
  ~KnowsCompositor();

  void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);

  SyncObjectClient* GetSyncObject() { return mSyncObject; }

  /// And by "thread-safe" here we merely mean "okay to hold strong references to
  /// from multiple threads". Not all methods actually are thread-safe.
  virtual bool IsThreadSafe() const { return true; }

  virtual RefPtr<KnowsCompositor> GetForMedia() { return RefPtr<KnowsCompositor>(this); }

  int32_t GetMaxTextureSize() const
  {
    return mTextureFactoryIdentifier.mMaxTextureSize;
  }

  /**
   * Returns the type of backend that is used off the main thread.
   * We only don't allow changing the backend type at runtime so this value can
   * be queried once and will not change until Gecko is restarted.
   */
  LayersBackend GetCompositorBackendType() const
  {
    return mTextureFactoryIdentifier.mParentBackend;
  }

  bool SupportsTextureBlitting() const
  {
    return mTextureFactoryIdentifier.mSupportsTextureBlitting;
  }

  bool SupportsPartialUploads() const
  {
    return mTextureFactoryIdentifier.mSupportsPartialUploads;
  }

  bool SupportsComponentAlpha() const
  {
    return mTextureFactoryIdentifier.mSupportsComponentAlpha;
  }

  bool SupportsTextureDirectMapping() const
  {
    return mTextureFactoryIdentifier.mSupportsTextureDirectMapping;
  }

  bool SupportsD3D11() const
  {
    return GetCompositorBackendType() == layers::LayersBackend::LAYERS_D3D11 ||
           (GetCompositorBackendType() == layers::LayersBackend::LAYERS_WR && GetCompositorUseANGLE());
  }

  bool GetCompositorUseANGLE() const
  {
    return mTextureFactoryIdentifier.mCompositorUseANGLE;
  }

  bool GetCompositorUseDComp() const
  {
    return mTextureFactoryIdentifier.mCompositorUseDComp;
  }

  const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
  {
    return mTextureFactoryIdentifier;
  }

  bool DeviceCanReset() const
  {
    return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC;
  }

  int32_t GetSerial() const { return mSerial; }

  /**
   * Sends a synchronous ping to the compsoitor.
   *
   * This is bad for performance and should only be called as a last resort if the
   * compositor may be blocked for a long period of time, to avoid that the content
   * process accumulates resource allocations that the compositor is not consuming
   * and releasing.
   */
  virtual void SyncWithCompositor()
  {
    MOZ_ASSERT_UNREACHABLE("Unimplemented");
  }

  /**
   * Helpers for finding other related interface. These are infallible.
   */
   virtual TextureForwarder* GetTextureForwarder() = 0;
  virtual LayersIPCActor* GetLayersIPCActor() = 0;
  virtual ActiveResourceTracker* GetActiveResourceTracker()
  {
    MOZ_ASSERT_UNREACHABLE("Unimplemented");
    return nullptr;
  }

protected:
  TextureFactoryIdentifier mTextureFactoryIdentifier;
  RefPtr<SyncObjectClient> mSyncObject;

  const int32_t mSerial;
  static mozilla::Atomic<int32_t> sSerialCounter;
};


/// Some implementations of KnowsCompositor can be used off their IPDL thread
/// like the ImageBridgeChild, and others just can't. Instead of passing them
/// we create a proxy KnowsCompositor that has information about compositor
/// backend but proxies allocations to the ImageBridge.
/// This is kind of specific to the needs of media which wants to allocate
/// textures, usually through the Image Bridge accessed by KnowsCompositor but
/// also wants access to the compositor backend information that ImageBridge
/// doesn't know about.
///
/// This is really a band aid to what turned into a class hierarchy horror show.
/// Hopefully we can come back and simplify this some way.
class KnowsCompositorMediaProxy: public KnowsCompositor
{
public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KnowsCompositorMediaProxy, override);

  explicit KnowsCompositorMediaProxy(const TextureFactoryIdentifier& aIdentifier);

  virtual TextureForwarder* GetTextureForwarder() override;


  virtual LayersIPCActor* GetLayersIPCActor() override;

  virtual ActiveResourceTracker* GetActiveResourceTracker() override;

  virtual void SyncWithCompositor() override;

protected:
  virtual ~KnowsCompositorMediaProxy();

  RefPtr<ImageBridgeChild> mThreadSafeAllocator;
};

} // namespace layers
} // namespace mozilla

#endif