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 class ImageContainer; 27 } // namespace layers 28 29 namespace dom { 30 class Blob; 31 class ImageBitmap; 32 33 // This is helper class for transferring OffscreenCanvas to worker thread. 34 // Because OffscreenCanvas is not thread-safe. So we cannot pass Offscreen- 35 // Canvas to worker thread directly. Thus, we create this helper class and 36 // store necessary data in it then pass it to worker thread. 37 struct OffscreenCanvasCloneData final { 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 public: 55 NS_DECL_ISUPPORTS_INHERITED 56 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OffscreenCanvas, 57 DOMEventTargetHelper) 58 59 OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight, 60 layers::LayersBackend aCompositorBackend, 61 layers::AsyncCanvasRenderer* aRenderer); 62 GetParentObject()63 nsCOMPtr<nsIGlobalObject> GetParentObject() const { return GetOwnerGlobal(); } 64 65 virtual JSObject* WrapObject(JSContext* aCx, 66 JS::Handle<JSObject*> aGivenProto) override; 67 68 static already_AddRefed<OffscreenCanvas> Constructor( 69 const GlobalObject& aGlobal, uint32_t aWidth, uint32_t aHeight); 70 71 void ClearResources(); 72 Width()73 uint32_t Width() const { return mWidth; } 74 Height()75 uint32_t Height() const { return mHeight; } 76 SetWidth(uint32_t aWidth,ErrorResult & aRv)77 void SetWidth(uint32_t aWidth, ErrorResult& aRv) { 78 if (mNeutered) { 79 aRv.Throw(NS_ERROR_FAILURE); 80 return; 81 } 82 83 if (mWidth != aWidth) { 84 mWidth = aWidth; 85 CanvasAttrChanged(); 86 } 87 } 88 SetHeight(uint32_t aHeight,ErrorResult & aRv)89 void SetHeight(uint32_t aHeight, ErrorResult& aRv) { 90 if (mNeutered) { 91 aRv.Throw(NS_ERROR_FAILURE); 92 return; 93 } 94 95 if (mHeight != aHeight) { 96 mHeight = aHeight; 97 CanvasAttrChanged(); 98 } 99 } 100 101 already_AddRefed<ImageBitmap> TransferToImageBitmap(ErrorResult& aRv); 102 103 already_AddRefed<Promise> ToBlob(JSContext* aCx, const nsAString& aType, 104 JS::Handle<JS::Value> aParams, 105 ErrorResult& aRv); 106 GetContext()107 nsICanvasRenderingContextInternal* GetContext() const { 108 return mCurrentContext; 109 } 110 111 already_AddRefed<gfx::SourceSurface> GetSurfaceSnapshot( 112 gfxAlphaType* aOutAlphaType = nullptr); 113 114 static already_AddRefed<OffscreenCanvas> CreateFromCloneData( 115 nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData); 116 117 // Return true on main-thread, and return gfx.offscreencanvas.enabled 118 // on worker thread. 119 static bool PrefEnabledOnWorkerThread(JSContext* aCx, JSObject* aObj); 120 121 OffscreenCanvasCloneData* ToCloneData(); 122 123 void CommitFrameToCompositor(); 124 GetOpaqueAttr()125 virtual bool GetOpaqueAttr() override { return false; } 126 GetWidthHeight()127 virtual nsIntSize GetWidthHeight() override { 128 return nsIntSize(mWidth, mHeight); 129 } 130 131 virtual already_AddRefed<nsICanvasRenderingContextInternal> CreateContext( 132 CanvasContextType aContextType) override; 133 134 virtual already_AddRefed<nsISupports> GetContext( 135 JSContext* aCx, const nsAString& aContextId, 136 JS::Handle<JS::Value> aContextOptions, ErrorResult& aRv) override; 137 SetNeutered()138 void SetNeutered() { mNeutered = true; } 139 IsNeutered()140 bool IsNeutered() const { return mNeutered; } 141 SetWriteOnly()142 void SetWriteOnly() { mIsWriteOnly = true; } 143 IsWriteOnly()144 bool IsWriteOnly() const { return mIsWriteOnly; } 145 GetCompositorBackendType()146 layers::LayersBackend GetCompositorBackendType() const { 147 return mCompositorBackendType; 148 } 149 150 layers::ImageContainer* GetImageContainer(); 151 152 private: 153 ~OffscreenCanvas(); 154 155 nsCOMPtr<nsIGlobalObject> GetGlobalObject(); 156 CanvasAttrChanged()157 void CanvasAttrChanged() { 158 mAttrDirty = true; 159 ErrorResult dummy; 160 UpdateContext(nullptr, JS::NullHandleValue, dummy); 161 } 162 163 bool mAttrDirty; 164 bool mNeutered; 165 bool mIsWriteOnly; 166 167 uint32_t mWidth; 168 uint32_t mHeight; 169 170 layers::LayersBackend mCompositorBackendType; 171 172 RefPtr<layers::CanvasClient> mCanvasClient; 173 RefPtr<layers::AsyncCanvasRenderer> mCanvasRenderer; 174 }; 175 176 } // namespace dom 177 } // namespace mozilla 178 179 #endif // MOZILLA_DOM_OFFSCREENCANVAS_H_ 180