1 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef nsICanvasRenderingContextInternal_h___
7 #define nsICanvasRenderingContextInternal_h___
8 
9 #include "gfxRect.h"
10 #include "mozilla/gfx/2D.h"
11 #include "nsISupports.h"
12 #include "nsIInputStream.h"
13 #include "nsIDocShell.h"
14 #include "nsRefreshObservers.h"
15 #include "mozilla/dom/HTMLCanvasElement.h"
16 #include "mozilla/dom/OffscreenCanvas.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/RefPtr.h"
19 #include "mozilla/StateWatching.h"
20 #include "mozilla/UniquePtr.h"
21 #include "mozilla/NotNull.h"
22 #include "mozilla/WeakPtr.h"
23 #include "mozilla/layers/LayersSurfaces.h"
24 
25 #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID       \
26   {                                                  \
27     0xb84f2fed, 0x9d4b, 0x430b, {                    \
28       0xbd, 0xfb, 0x85, 0x57, 0x8a, 0xc2, 0xb4, 0x4b \
29     }                                                \
30   }
31 
32 class nsIDocShell;
33 class nsIPrincipal;
34 class nsRefreshDriver;
35 
36 namespace mozilla {
37 class nsDisplayListBuilder;
38 class ClientWebGLContext;
39 class PresShell;
40 class WebGLFramebufferJS;
41 namespace layers {
42 class CanvasRenderer;
43 class CompositableHandle;
44 class Layer;
45 class Image;
46 class LayerManager;
47 class LayerTransactionChild;
48 class PersistentBufferProvider;
49 class WebRenderCanvasData;
50 }  // namespace layers
51 namespace gfx {
52 class SourceSurface;
53 }  // namespace gfx
54 }  // namespace mozilla
55 
56 enum class FrameCaptureState : uint8_t { CLEAN, DIRTY };
57 
58 class nsICanvasRenderingContextInternal : public nsISupports,
59                                           public mozilla::SupportsWeakPtr,
60                                           public nsAPostRefreshObserver {
61  public:
62   using CanvasRenderer = mozilla::layers::CanvasRenderer;
63   using WebRenderCanvasData = mozilla::layers::WebRenderCanvasData;
64 
65   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
66 
67   nsICanvasRenderingContextInternal();
68 
69   ~nsICanvasRenderingContextInternal();
70 
SetCanvasElement(mozilla::dom::HTMLCanvasElement * parentCanvas)71   void SetCanvasElement(mozilla::dom::HTMLCanvasElement* parentCanvas) {
72     RemovePostRefreshObserver();
73     mCanvasElement = parentCanvas;
74     AddPostRefreshObserverIfNecessary();
75   }
76 
77   virtual mozilla::PresShell* GetPresShell();
78 
79   void RemovePostRefreshObserver();
80 
81   void AddPostRefreshObserverIfNecessary();
82 
83   nsIGlobalObject* GetParentObject() const;
84 
85   nsIPrincipal* PrincipalOrNull() const;
86 
SetOffscreenCanvas(mozilla::dom::OffscreenCanvas * aOffscreenCanvas)87   void SetOffscreenCanvas(mozilla::dom::OffscreenCanvas* aOffscreenCanvas) {
88     mOffscreenCanvas = aOffscreenCanvas;
89   }
90 
91   // Dimensions of the canvas, in pixels.
92   virtual int32_t GetWidth() = 0;
93   virtual int32_t GetHeight() = 0;
94 
95   // Sets the dimensions of the canvas, in pixels.  Called
96   // whenever the size of the element changes.
97   NS_IMETHOD SetDimensions(int32_t width, int32_t height) = 0;
98 
99   // Initializes the canvas after the object is constructed.
Initialize()100   virtual void Initialize() {}
101 
102   // Initializes with an nsIDocShell and DrawTarget. The size is taken from the
103   // DrawTarget.
104   NS_IMETHOD InitializeWithDrawTarget(
105       nsIDocShell* aDocShell,
106       mozilla::NotNull<mozilla::gfx::DrawTarget*> aTarget) = 0;
107 
108   // Creates an image buffer. Returns null on failure.
109   virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* format) = 0;
110 
111   // Gives you a stream containing the image represented by this context.
112   // The format is given in mimeTime, for example "image/png".
113   //
114   // If the image format does not support transparency or includeTransparency
115   // is false, alpha will be discarded and the result will be the image
116   // composited on black.
117   NS_IMETHOD GetInputStream(const char* mimeType,
118                             const nsAString& encoderOptions,
119                             nsIInputStream** stream) = 0;
120 
121   // This gets an Azure SourceSurface for the canvas, this will be a snapshot
122   // of the canvas at the time it was called.
123   // If premultAlpha is provided, then it assumed the callee can handle
124   // un-premultiplied surfaces, and *premultAlpha will be set to false
125   // if one is returned.
126   virtual already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(
127       gfxAlphaType* out_alphaType = nullptr) = 0;
128 
GetFrontBufferSnapshot(bool)129   virtual RefPtr<mozilla::gfx::SourceSurface> GetFrontBufferSnapshot(bool) {
130     return GetSurfaceSnapshot();
131   }
132 
133   // If this is called with true, the backing store of the canvas should
134   // be created as opaque; all compositing operators should assume the
135   // dst alpha is always 1.0.  If this is never called, the context's
136   // opaqueness is determined by the context attributes that it's initialized
137   // with.
138   virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) = 0;
139 
140   // Returns whether the context is opaque. This value can be based both on
141   // the value of the moz-opaque attribute and on the context's initialization
142   // attributes.
143   virtual bool GetIsOpaque() = 0;
144 
145   // Invalidate this context and release any held resources, in preperation
146   // for possibly reinitializing with SetDimensions/InitializeWithSurface.
147   NS_IMETHOD Reset() = 0;
148 
GetAsImage()149   virtual already_AddRefed<mozilla::layers::Image> GetAsImage() {
150     return nullptr;
151   }
152 
UpdateWebRenderCanvasData(mozilla::nsDisplayListBuilder * aBuilder,WebRenderCanvasData * aCanvasData)153   virtual bool UpdateWebRenderCanvasData(
154       mozilla::nsDisplayListBuilder* aBuilder,
155       WebRenderCanvasData* aCanvasData) {
156     return false;
157   }
158 
InitializeCanvasRenderer(mozilla::nsDisplayListBuilder * aBuilder,CanvasRenderer * aRenderer)159   virtual bool InitializeCanvasRenderer(mozilla::nsDisplayListBuilder* aBuilder,
160                                         CanvasRenderer* aRenderer) {
161     return false;
162   }
163 
164   virtual void MarkContextClean() = 0;
165 
166   // Called when a frame is captured.
167   virtual void MarkContextCleanForFrameCapture() = 0;
168 
169   // Whether the context is clean or has been invalidated (dirty) since the last
170   // frame was captured. The Watchable allows the caller to get notified of
171   // state changes.
172   virtual mozilla::Watchable<FrameCaptureState>* GetFrameCaptureState() = 0;
173 
174   // Redraw the dirty rectangle of this canvas.
175   NS_IMETHOD Redraw(const gfxRect& dirty) = 0;
176 
SetContextOptions(JSContext * cx,JS::Handle<JS::Value> options,mozilla::ErrorResult & aRvForDictionaryInit)177   NS_IMETHOD SetContextOptions(JSContext* cx, JS::Handle<JS::Value> options,
178                                mozilla::ErrorResult& aRvForDictionaryInit) {
179     return NS_OK;
180   }
181 
182   // return true and fills in the bounding rect if elementis a child and has a
183   // hit region.
GetHitRegionRect(mozilla::dom::Element * element,nsRect & rect)184   virtual bool GetHitRegionRect(mozilla::dom::Element* element, nsRect& rect) {
185     return false;
186   }
187 
188   // Given a point, return hit region ID if it exists or an empty string if it
189   // doesn't
GetHitRegion(const mozilla::gfx::Point & point)190   virtual nsString GetHitRegion(const mozilla::gfx::Point& point) {
191     return nsString();
192   }
193 
OnMemoryPressure()194   virtual void OnMemoryPressure() {}
195 
OnBeforePaintTransaction()196   virtual void OnBeforePaintTransaction() {}
OnDidPaintTransaction()197   virtual void OnDidPaintTransaction() {}
198 
GetBufferProvider()199   virtual mozilla::layers::PersistentBufferProvider* GetBufferProvider() {
200     return nullptr;
201   }
202 
203   virtual mozilla::Maybe<mozilla::layers::SurfaceDescriptor> GetFrontBuffer(
204       mozilla::WebGLFramebufferJS*, const bool webvr = false) {
205     return mozilla::Nothing();
206   }
207 
208   virtual mozilla::Maybe<mozilla::layers::SurfaceDescriptor> PresentFrontBuffer(
209       mozilla::WebGLFramebufferJS* fb, mozilla::layers::TextureType,
210       const bool webvr = false) {
211     return GetFrontBuffer(fb, webvr);
212   }
213 
214   void DoSecurityCheck(nsIPrincipal* aPrincipal, bool forceWriteOnly,
215                        bool CORSUsed);
216 
217   //
218   // shmem support
219   //
220 
221   // If this context can be set to use Mozilla's Shmem segments as its backing
222   // store, this will set it to that state. Note that if you have drawn
223   // anything into this canvas before changing the shmem state, it will be
224   // lost.
225   NS_IMETHOD SetIsIPC(bool isIPC) = 0;
226 
227  protected:
228   RefPtr<mozilla::dom::HTMLCanvasElement> mCanvasElement;
229   RefPtr<mozilla::dom::OffscreenCanvas> mOffscreenCanvas;
230   RefPtr<nsRefreshDriver> mRefreshDriver;
231 };
232 
233 NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
234                               NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
235 
236 #endif /* nsICanvasRenderingContextInternal_h___ */
237