OffscreenCanvas.h (6959B)
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 "FontVisibilityProvider.h" 11 #include "gfxTypes.h" 12 #include "mozilla/DOMEventTargetHelper.h" 13 #include "mozilla/Maybe.h" 14 #include "mozilla/RefPtr.h" 15 #include "mozilla/UniquePtr.h" 16 #include "mozilla/dom/CanvasRenderingContextHelper.h" 17 #include "mozilla/dom/ImageEncoder.h" 18 #include "mozilla/dom/OffscreenCanvasDisplayHelper.h" 19 #include "mozilla/layers/LayersTypes.h" 20 #include "nsCycleCollectionParticipant.h" 21 22 struct JSContext; 23 24 namespace mozilla { 25 class CancelableRunnable; 26 class ErrorResult; 27 enum class RFPTarget : uint64_t; 28 29 namespace gfx { 30 class SourceSurface; 31 } 32 33 namespace dom { 34 enum class OffscreenRenderingContextId : uint8_t; 35 class Blob; 36 class EncodeCompleteCallback; 37 class OffscreenCanvasDisplayHelper; 38 class ImageBitmap; 39 struct ImageEncodeOptions; 40 41 using OwningOffscreenRenderingContext = class 42 OwningOffscreenCanvasRenderingContext2DOrImageBitmapRenderingContextOrWebGLRenderingContextOrWebGL2RenderingContextOrGPUCanvasContext; 43 44 // This is helper class for transferring OffscreenCanvas to worker thread. 45 // Because OffscreenCanvas is not thread-safe. So we cannot pass Offscreen- 46 // Canvas to worker thread directly. Thus, we create this helper class and 47 // store necessary data in it then pass it to worker thread. 48 struct OffscreenCanvasCloneData final { 49 OffscreenCanvasCloneData(OffscreenCanvasDisplayHelper* aDisplay, 50 uint32_t aWidth, uint32_t aHeight, 51 layers::LayersBackend aCompositorBackend, 52 bool aNeutered, bool aIsWriteOnly, 53 nsIPrincipal* aExpandedReader); 54 ~OffscreenCanvasCloneData(); 55 56 RefPtr<OffscreenCanvasDisplayHelper> mDisplay; 57 uint32_t mWidth; 58 uint32_t mHeight; 59 layers::LayersBackend mCompositorBackendType; 60 bool mNeutered; 61 bool mIsWriteOnly; 62 RefPtr<nsIPrincipal> mExpandedReader; 63 }; 64 65 class OffscreenCanvas final : public DOMEventTargetHelper, 66 public CanvasRenderingContextHelper, 67 public FontVisibilityProvider { 68 public: 69 NS_DECL_ISUPPORTS_INHERITED 70 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OffscreenCanvas, 71 DOMEventTargetHelper) 72 73 IMPL_EVENT_HANDLER(contextlost); 74 IMPL_EVENT_HANDLER(contextrestored); 75 76 FONT_VISIBILITY_PROVIDER_IMPL 77 78 OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight); 79 80 OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight, 81 layers::LayersBackend aCompositorBackend, 82 already_AddRefed<OffscreenCanvasDisplayHelper> aDisplay); 83 84 void Destroy(); 85 86 nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } 87 88 virtual JSObject* WrapObject(JSContext* aCx, 89 JS::Handle<JSObject*> aGivenProto) override; 90 91 static already_AddRefed<OffscreenCanvas> Constructor( 92 const GlobalObject& aGlobal, uint32_t aWidth, uint32_t aHeight, 93 ErrorResult& aRv); 94 95 void ClearResources(); 96 97 uint32_t Width() const { return mWidth; } 98 uint32_t Height() const { return mHeight; } 99 void SetWidth(uint32_t aWidth, ErrorResult& aRv); 100 void SetHeight(uint32_t aHeight, ErrorResult& aRv); 101 102 void GetContext(JSContext* aCx, const OffscreenRenderingContextId& aContextId, 103 JS::Handle<JS::Value> aContextOptions, 104 Nullable<OwningOffscreenRenderingContext>& aResult, 105 ErrorResult& aRv); 106 107 already_AddRefed<ImageBitmap> TransferToImageBitmap(ErrorResult& aRv); 108 109 already_AddRefed<Promise> ConvertToBlob(const ImageEncodeOptions& aOptions, 110 ErrorResult& aRv); 111 112 already_AddRefed<Promise> ToBlob(JSContext* aCx, const nsAString& aType, 113 JS::Handle<JS::Value> aParams, 114 ErrorResult& aRv); 115 116 Maybe<uint64_t> GetWindowID() const; 117 118 nsICanvasRenderingContextInternal* GetContext() const { 119 return mCurrentContext; 120 } 121 122 CanvasContextType GetContextType() const { return mCurrentContextType; } 123 124 already_AddRefed<gfx::SourceSurface> GetSurfaceSnapshot( 125 gfxAlphaType* aOutAlphaType = nullptr); 126 127 static already_AddRefed<OffscreenCanvas> CreateFromCloneData( 128 nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData); 129 130 UniquePtr<OffscreenCanvasCloneData> ToCloneData(JSContext* aCx); 131 132 void UpdateDisplayData(const OffscreenCanvasDisplayData& aData); 133 134 void CommitFrameToCompositor(); 135 void DequeueCommitToCompositor(); 136 void QueueCommitToCompositor(); 137 138 virtual bool GetOpaqueAttr() override { return false; } 139 140 CSSIntSize GetWidthHeight() override { return CSSIntSize(mWidth, mHeight); } 141 142 virtual already_AddRefed<nsICanvasRenderingContextInternal> CreateContext( 143 CanvasContextType aContextType) override; 144 145 void SetNeutered() { 146 mWidth = 0; 147 mHeight = 0; 148 mNeutered = true; 149 } 150 151 bool MayNeuter() const { return !mNeutered && !mCurrentContext; } 152 153 void SetSize(const nsIntSize& aSize, ErrorResult& aRv); 154 155 nsIPrincipal* GetExpandedReader() const { return mExpandedReader; } 156 157 void SetWriteOnly(RefPtr<nsIPrincipal>&& aExpandedReader); 158 159 void SetWriteOnly(nsIPrincipal* aExpandedReader = nullptr) { 160 RefPtr<nsIPrincipal> expandedReader(aExpandedReader); 161 SetWriteOnly(std::move(expandedReader)); 162 } 163 164 bool IsWriteOnly() const { return mIsWriteOnly; } 165 166 // Determines if the caller should be able to read the content. 167 bool CallerCanRead(nsIPrincipal& aPrincipal) const; 168 169 layers::LayersBackend GetCompositorBackendType() const { 170 return mCompositorBackendType; 171 } 172 173 bool IsTransferredFromElement() const { return !!mDisplay; } 174 175 private: 176 ~OffscreenCanvas(); 177 178 void RecordCanvasUsage(CanvasExtractionAPI aExtractionAPI, 179 CanvasUtils::ImageExtraction aExtractionBehaviour); 180 181 already_AddRefed<EncodeCompleteCallback> CreateEncodeCompleteCallback( 182 Promise* aPromise); 183 184 void CanvasAttrChanged() { 185 ErrorResult dummy; 186 UpdateContext(nullptr, JS::NullHandleValue, dummy); 187 } 188 189 bool mNeutered = false; 190 bool mIsWriteOnly = false; 191 192 uint32_t mWidth = 0; 193 uint32_t mHeight = 0; 194 195 layers::LayersBackend mCompositorBackendType = 196 layers::LayersBackend::LAYERS_NONE; 197 198 RefPtr<OffscreenCanvasDisplayHelper> mDisplay; 199 RefPtr<CancelableRunnable> mPendingCommit; 200 RefPtr<nsIPrincipal> mExpandedReader; 201 Maybe<OffscreenCanvasDisplayData> mPendingUpdate; 202 const FontVisibility mFontVisibility; 203 }; 204 205 } // namespace dom 206 } // namespace mozilla 207 208 #endif // MOZILLA_DOM_OFFSCREENCANVAS_H_