Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
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_DOM_OFFSCREENCANVAS_H_
8 : #define MOZILLA_DOM_OFFSCREENCANVAS_H_
9 :
10 : #include "gfxTypes.h"
11 : #include "mozilla/DOMEventTargetHelper.h"
12 : #include "mozilla/layers/LayersTypes.h"
13 : #include "mozilla/RefPtr.h"
14 : #include "CanvasRenderingContextHelper.h"
15 : #include "nsCycleCollectionParticipant.h"
16 :
17 : struct JSContext;
18 :
19 : namespace mozilla {
20 :
21 : class ErrorResult;
22 :
23 : namespace layers {
24 : class AsyncCanvasRenderer;
25 : class CanvasClient;
26 : } // namespace layers
27 :
28 : namespace dom {
29 : class Blob;
30 : class ImageBitmap;
31 :
32 : // This is helper class for transferring OffscreenCanvas to worker thread.
33 : // Because OffscreenCanvas is not thread-safe. So we cannot pass Offscreen-
34 : // Canvas to worker thread directly. Thus, we create this helper class and
35 : // store necessary data in it then pass it to worker thread.
36 : struct OffscreenCanvasCloneData final
37 : {
38 : OffscreenCanvasCloneData(layers::AsyncCanvasRenderer* aRenderer,
39 : uint32_t aWidth, uint32_t aHeight,
40 : layers::LayersBackend aCompositorBackend,
41 : bool aNeutered, bool aIsWriteOnly);
42 : ~OffscreenCanvasCloneData();
43 :
44 : RefPtr<layers::AsyncCanvasRenderer> mRenderer;
45 : uint32_t mWidth;
46 : uint32_t mHeight;
47 : layers::LayersBackend mCompositorBackendType;
48 : bool mNeutered;
49 : bool mIsWriteOnly;
50 : };
51 :
52 : class OffscreenCanvas final : public DOMEventTargetHelper
53 : , public CanvasRenderingContextHelper
54 : {
55 : public:
56 : NS_DECL_ISUPPORTS_INHERITED
57 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OffscreenCanvas, DOMEventTargetHelper)
58 :
59 : OffscreenCanvas(nsIGlobalObject* aGlobal,
60 : uint32_t aWidth,
61 : uint32_t aHeight,
62 : layers::LayersBackend aCompositorBackend,
63 : layers::AsyncCanvasRenderer* aRenderer);
64 :
65 0 : nsCOMPtr<nsIGlobalObject> GetParentObject() const { return GetOwnerGlobal(); }
66 :
67 : virtual JSObject* WrapObject(JSContext* aCx,
68 : JS::Handle<JSObject*> aGivenProto) override;
69 :
70 : static already_AddRefed<OffscreenCanvas>
71 : Constructor(const GlobalObject& aGlobal,
72 : uint32_t aWidth,
73 : uint32_t aHeight,
74 : ErrorResult& aRv);
75 :
76 : void ClearResources();
77 :
78 0 : uint32_t Width() const
79 : {
80 0 : return mWidth;
81 : }
82 :
83 0 : uint32_t Height() const
84 : {
85 0 : return mHeight;
86 : }
87 :
88 0 : void SetWidth(uint32_t aWidth, ErrorResult& aRv)
89 : {
90 0 : if (mNeutered) {
91 0 : aRv.Throw(NS_ERROR_FAILURE);
92 0 : return;
93 : }
94 :
95 0 : if (mWidth != aWidth) {
96 0 : mWidth = aWidth;
97 0 : CanvasAttrChanged();
98 : }
99 : }
100 :
101 0 : void SetHeight(uint32_t aHeight, ErrorResult& aRv)
102 : {
103 0 : if (mNeutered) {
104 0 : aRv.Throw(NS_ERROR_FAILURE);
105 0 : return;
106 : }
107 :
108 0 : if (mHeight != aHeight) {
109 0 : mHeight = aHeight;
110 0 : CanvasAttrChanged();
111 : }
112 : }
113 :
114 : already_AddRefed<ImageBitmap>
115 : TransferToImageBitmap();
116 :
117 : already_AddRefed<Promise>
118 : ToBlob(JSContext* aCx,
119 : const nsAString& aType,
120 : JS::Handle<JS::Value> aParams,
121 : ErrorResult& aRv);
122 :
123 : nsICanvasRenderingContextInternal* GetContext() const
124 : {
125 : return mCurrentContext;
126 : }
127 :
128 : already_AddRefed<gfx::SourceSurface> GetSurfaceSnapshot(gfxAlphaType* aOutAlphaType = nullptr);
129 :
130 : static already_AddRefed<OffscreenCanvas>
131 : CreateFromCloneData(nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData);
132 :
133 : static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
134 :
135 : // Return true on main-thread, and return gfx.offscreencanvas.enabled
136 : // on worker thread.
137 : static bool PrefEnabledOnWorkerThread(JSContext* aCx, JSObject* aObj);
138 :
139 : OffscreenCanvasCloneData* ToCloneData();
140 :
141 : void CommitFrameToCompositor();
142 :
143 0 : virtual bool GetOpaqueAttr() override
144 : {
145 0 : return false;
146 : }
147 :
148 0 : virtual nsIntSize GetWidthHeight() override
149 : {
150 0 : return nsIntSize(mWidth, mHeight);
151 : }
152 :
153 : virtual already_AddRefed<nsICanvasRenderingContextInternal>
154 : CreateContext(CanvasContextType aContextType) override;
155 :
156 : virtual already_AddRefed<nsISupports>
157 : GetContext(JSContext* aCx,
158 : const nsAString& aContextId,
159 : JS::Handle<JS::Value> aContextOptions,
160 : ErrorResult& aRv) override;
161 :
162 0 : void SetNeutered()
163 : {
164 0 : mNeutered = true;
165 0 : }
166 :
167 : bool IsNeutered() const
168 : {
169 : return mNeutered;
170 : }
171 :
172 0 : void SetWriteOnly()
173 : {
174 0 : mIsWriteOnly = true;
175 0 : }
176 :
177 0 : bool IsWriteOnly() const
178 : {
179 0 : return mIsWriteOnly;
180 : }
181 :
182 0 : layers::LayersBackend GetCompositorBackendType() const
183 : {
184 0 : return mCompositorBackendType;
185 : }
186 :
187 : private:
188 : ~OffscreenCanvas();
189 :
190 : nsCOMPtr<nsIGlobalObject> GetGlobalObject();
191 :
192 0 : void CanvasAttrChanged()
193 : {
194 0 : mAttrDirty = true;
195 0 : ErrorResult dummy;
196 0 : UpdateContext(nullptr, JS::NullHandleValue, dummy);
197 0 : }
198 :
199 : bool mAttrDirty;
200 : bool mNeutered;
201 : bool mIsWriteOnly;
202 :
203 : uint32_t mWidth;
204 : uint32_t mHeight;
205 :
206 : layers::LayersBackend mCompositorBackendType;
207 :
208 : RefPtr<layers::CanvasClient> mCanvasClient;
209 : RefPtr<layers::AsyncCanvasRenderer> mCanvasRenderer;
210 : };
211 :
212 : } // namespace dom
213 : } // namespace mozilla
214 :
215 : #endif // MOZILLA_DOM_OFFSCREENCANVAS_H_
|