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/. */
7 #ifndef MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
8 #define MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
10 #include "LayersTypes.h"
11 #include "mozilla/dom/CanvasRenderingContextHelper.h"
12 #include "mozilla/gfx/Point.h" // for IntSize
13 #include "mozilla/Mutex.h"
14 #include "nsCOMPtr.h" // for nsCOMPtr
16 class nsICanvasRenderingContextInternal
;
18 class nsISerialEventTarget
;
23 class DataSourceSurface
;
31 class HTMLCanvasElement
;
41 * Since HTMLCanvasElement and OffscreenCanvas are not thread-safe, we create
42 * AsyncCanvasRenderer which is thread-safe wrapper object for communicating
43 * among main, worker and ImageBridgeChild threads.
45 * Each HTMLCanvasElement object is responsible for creating
46 * AsyncCanvasRenderer object. Once Canvas is transfered to worker,
47 * OffscreenCanvas will keep reference pointer of this object.
49 * Sometimes main thread needs AsyncCanvasRenderer's result, such as layers
50 * fallback to BasicLayerManager or calling toDataURL in Javascript. Simply call
51 * GetSurface() in main thread will readback the result to mSurface.
53 * If layers backend is LAYERS_CLIENT, this object will pass to ImageBridgeChild
54 * for submitting frames to Compositor.
56 class AsyncCanvasRenderer final
{
57 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncCanvasRenderer
)
60 AsyncCanvasRenderer();
62 void NotifyElementAboutAttributesChanged();
63 void NotifyElementAboutInvalidation();
65 void SetCanvasClient(CanvasClient
* aClient
);
67 void SetWidth(uint32_t aWidth
) { mWidth
= aWidth
; }
69 void SetHeight(uint32_t aHeight
) { mHeight
= aHeight
; }
71 void SetIsAlphaPremultiplied(bool aIsAlphaPremultiplied
) {
72 mIsAlphaPremultiplied
= aIsAlphaPremultiplied
;
75 // Active thread means the thread which spawns GLContext.
76 void SetActiveEventTarget();
77 void ResetActiveEventTarget();
79 // This will readback surface and return the surface
80 // in the DataSourceSurface.
81 // Can be called in main thread only.
82 already_AddRefed
<gfx::DataSourceSurface
> GetSurface();
84 // For SharedSurface_Basic case, before the frame sending to the compositor,
85 // we readback it to a texture client because SharedSurface_Basic cannot
86 // shared. We don't want to readback it again here, so just copy the content
87 // of that texture client here to avoid readback again.
88 void CopyFromTextureClient(TextureClient
* aClient
);
90 // Readback current WebGL's content and convert it to InputStream. This
91 // function called GetSurface implicitly and GetSurface handles only get
92 // called in the main thread. So this function can be called in main thread.
93 nsresult
GetInputStream(const char* aMimeType
,
94 const nsAString
& aEncoderOptions
,
95 nsIInputStream
** aStream
);
97 gfx::IntSize
GetSize() const { return gfx::IntSize(mWidth
, mHeight
); }
99 CompositableHandle
GetCanvasClientAsyncHandle() const {
100 return mCanvasClientAsyncHandle
;
103 CanvasClient
* GetCanvasClient() const { return mCanvasClient
; }
105 already_AddRefed
<nsISerialEventTarget
> GetActiveEventTarget();
107 ImageContainer
* GetImageContainer();
109 dom::CanvasContextType
GetContextType();
110 void SetContextType(dom::CanvasContextType aContextType
);
112 // The lifetime is controllered by HTMLCanvasElement.
113 // Only accessed in main thread.
114 dom::HTMLCanvasElement
* mHTMLCanvasElement
;
116 // Only accessed in active thread.
117 nsICanvasRenderingContextInternal
* mContext
;
119 // We need to keep a reference to the context around here, otherwise the
120 // canvas' surface texture destructor will deref and destroy it too early
121 // Only accessed in active thread.
122 RefPtr
<gl::GLContext
> mGLContext
;
125 virtual ~AsyncCanvasRenderer();
127 // Readback current WebGL's content and return it as DataSourceSurface.
128 already_AddRefed
<gfx::DataSourceSurface
> UpdateTarget();
130 bool mIsAlphaPremultiplied
;
134 CompositableHandle mCanvasClientAsyncHandle
;
136 // The lifetime of this pointer is controlled by OffscreenCanvas
137 // Can be accessed in active thread and ImageBridge thread.
138 // But we never accessed it at the same time on both thread. So no
139 // need to protect this member.
140 CanvasClient
* mCanvasClient
;
142 // When backend is LAYER_BASIC and SharedSurface type is Basic.
143 // CanvasClient will readback the GLContext to a TextureClient
144 // in order to send frame to compositor. To avoid readback again,
145 // we copy from this TextureClient to this mSurfaceForBasic directly
146 // by calling CopyFromTextureClient().
147 RefPtr
<gfx::DataSourceSurface
> mSurfaceForBasic
;
149 // Protect non thread-safe objects.
152 // Can be accessed in any thread, need protect by mutex.
153 nsCOMPtr
<nsISerialEventTarget
> mActiveEventTarget
;
155 // Can be accessed in any thread, need protect by mutex.
156 RefPtr
<ImageContainer
> mImageContainer
;
158 // Can be accessed in any thread, need protect by mutex.
159 dom::CanvasContextType mContextType
;
162 } // namespace layers
163 } // namespace mozilla
165 #endif // MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_