summaryrefslogtreecommitdiffstats
path: root/gfx/layers/client/CompositableClient.h
blob: 43107855b60ef7b9d8af6e60ff87ac882f726eb5 (plain)
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
/* -*- 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_GFX_BUFFERCLIENT_H
#define MOZILLA_GFX_BUFFERCLIENT_H

#include <stdint.h>  // for uint64_t

#include <map>     // for map
#include <vector>  // for vector

#include "mozilla/Assertions.h"  // for MOZ_CRASH
#include "mozilla/DataMutex.h"
#include "mozilla/RefPtr.h"     // for already_AddRefed, RefCounted
#include "mozilla/gfx/Types.h"  // for SurfaceFormat
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayersTypes.h"    // for LayersBackend, TextureDumpMode
#include "mozilla/layers/TextureClient.h"  // for TextureClient
#include "mozilla/webrender/WebRenderTypes.h"  // for RenderRoot
#include "nsISupportsImpl.h"                   // for MOZ_COUNT_CTOR, etc

namespace mozilla {
namespace layers {

class CompositableClient;
class ImageBridgeChild;
class ImageContainer;
class CompositableForwarder;
class CompositableChild;
class TextureClientRecycleAllocator;
class ContentClientRemoteBuffer;

/**
 * CompositableClient manages the texture-specific logic for composite layers,
 * independently of the layer. It is the content side of a CompositableClient/
 * CompositableHost pair.
 *
 * CompositableClient's purpose is to send texture data to the compositor side
 * along with any extra information about how the texture is to be composited.
 * Things like opacity or transformation belong to layer and not compositable.
 *
 * Since Compositables are independent of layers it is possible to create one,
 * connect it to the compositor side, and start sending images to it. This alone
 * is arguably not very useful, but it means that as long as a shadow layer can
 * do the proper magic to find a reference to the right CompositableHost on the
 * Compositor side, a Compositable client can be used outside of the main
 * shadow layer forwarder machinery that is used on the main thread.
 *
 * The first step is to create a Compositable client and call Connect().
 * Connect() creates the underlying IPDL actor (see CompositableChild) and the
 * corresponding CompositableHost on the other side.
 *
 * To do async texture transfer (like async-video), the CompositableClient
 * should be created with a different CompositableForwarder (like
 * ImageBridgeChild) and attachment is done with
 * CompositableForwarder::AttachAsyncCompositable that takes an identifier
 * instead of a CompositableChild, since the CompositableClient is not managed
 * by this layer forwarder (the matching uses a global map on the compositor
 * side, see CompositableMap in ImageBridgeParent.cpp)
 *
 * Subclasses: Painted layers use ContentClients, ImageLayers use ImageClients,
 * Canvas layers use CanvasClients (but ImageHosts). We have a different
 * subclass where we have a different way of interfacing with the textures - in
 * terms of drawing into the compositable and/or passing its contents to the
 * compostior.
 */
class CompositableClient {
 protected:
  virtual ~CompositableClient();

 public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient)

  explicit CompositableClient(CompositableForwarder* aForwarder,
                              TextureFlags aFlags = TextureFlags::NO_FLAGS);

  virtual void Dump(std::stringstream& aStream, const char* aPrefix = "",
                    bool aDumpHtml = false,
                    TextureDumpMode aCompress = TextureDumpMode::Compress){};

  virtual TextureInfo GetTextureInfo() const = 0;

  LayersBackend GetCompositorBackendType() const;

  already_AddRefed<TextureClient> CreateBufferTextureClient(
      gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
      gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE,
      TextureFlags aFlags = TextureFlags::DEFAULT);

  already_AddRefed<TextureClient> CreateTextureClientForDrawing(
      gfx::SurfaceFormat aFormat, gfx::IntSize aSize, BackendSelector aSelector,
      TextureFlags aTextureFlags,
      TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);

  /**
   * Establishes the connection with compositor side through IPDL
   */
  virtual bool Connect(ImageContainer* aImageContainer = nullptr);

  void Destroy();

  bool IsConnected() const;

  CompositableForwarder* GetForwarder() const { return mForwarder; }

  /**
   * This identifier is what lets us attach async compositables with a shadow
   * layer. It is not used if the compositable is used with the regular shadow
   * layer forwarder.
   *
   * If this returns empty, it means the compositable is not async (it is used
   * on the main thread).
   */
  CompositableHandle GetAsyncHandle() const;

  /**
   * Handle for IPDL communication.
   */
  CompositableHandle GetIPCHandle() const { return mHandle; }

  /**
   * Tells the Compositor to create a TextureHost for this TextureClient.
   */
  virtual bool AddTextureClient(TextureClient* aClient);

  /**
   * A hook for the when the Compositable is detached from it's layer.
   */
  virtual void OnDetach() {}

  /**
   * Clear any resources that are not immediately necessary. This may be called
   * in low-memory conditions.
   */
  virtual void ClearCachedResources();

  /**
   * Shrink memory usage.
   * Called when "memory-pressure" is observed.
   */
  virtual void HandleMemoryPressure();

  /**
   * Should be called when deataching a TextureClient from a Compositable,
   * because some platforms need to do some extra book keeping when this
   * happens.
   *
   * See AutoRemoveTexture to automatically invoke this at the end of a scope.
   */
  virtual void RemoveTexture(TextureClient* aTexture);

  void InitIPDL(const CompositableHandle& aHandle);

  TextureFlags GetTextureFlags() const { return mTextureFlags; }

  TextureClientRecycleAllocator* GetTextureClientRecycler();

  bool HasTextureClientRecycler() {
    auto lock = mTextureClientRecycler.Lock();
    return !!(*lock);
  }

  static void DumpTextureClient(std::stringstream& aStream,
                                TextureClient* aTexture,
                                TextureDumpMode aCompress);

 protected:
  RefPtr<CompositableForwarder> mForwarder;
  // Some layers may want to enforce some flags to all their textures
  // (like disallowing tiling)
  Atomic<TextureFlags> mTextureFlags;
  DataMutex<RefPtr<TextureClientRecycleAllocator>> mTextureClientRecycler;

  // Only ever accessed via mTextureClientRecycler's Lock
  CompositableHandle mHandle;
  bool mIsAsync;

  friend class CompositableChild;
};

/**
 * Helper to call RemoveTexture at the end of a scope.
 */
struct AutoRemoveTexture {
  explicit AutoRemoveTexture(CompositableClient* aCompositable,
                             TextureClient* aTexture = nullptr)
      : mTexture(aTexture), mCompositable(aCompositable) {}

  ~AutoRemoveTexture();

  RefPtr<TextureClient> mTexture;

 private:
  CompositableClient* mCompositable;
};

}  // namespace layers
}  // namespace mozilla

#endif