1 /* -*- Mode: C++; tab-width: 20; 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 MOZILLA_GFX_CANVASCLIENT_H 7 #define MOZILLA_GFX_CANVASCLIENT_H 8 9 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 10 #include "mozilla/Attributes.h" // for override 11 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed 12 #include "mozilla/layers/CompositableClient.h" // for CompositableClient 13 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc 14 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 15 #include "mozilla/layers/TextureClient.h" // for TextureClient, etc 16 #include "mozilla/layers/PersistentBufferProvider.h" 17 18 // Fix X11 header brain damage that conflicts with MaybeOneOf::None 19 #undef None 20 #include "mozilla/MaybeOneOf.h" 21 22 #include "mozilla/mozalloc.h" // for operator delete 23 24 #include "mozilla/gfx/Point.h" // for IntSize 25 #include "mozilla/gfx/Types.h" // for SurfaceFormat 26 27 namespace mozilla { 28 namespace layers { 29 30 class AsyncCanvasRenderer; 31 class ClientCanvasLayer; 32 class CompositableForwarder; 33 class ShadowableLayer; 34 class SharedSurfaceTextureClient; 35 36 /** 37 * Compositable client for 2d and webgl canvas. 38 */ 39 class CanvasClient : public CompositableClient 40 { 41 public: 42 typedef MaybeOneOf<ClientCanvasLayer*, AsyncCanvasRenderer*> Renderer; 43 44 /** 45 * Creates, configures, and returns a new canvas client. If necessary, a 46 * message will be sent to the compositor to create a corresponding image 47 * host. 48 */ 49 enum CanvasClientType { 50 CanvasClientSurface, 51 CanvasClientGLContext, 52 CanvasClientTypeShSurf, 53 CanvasClientAsync, // webgl on workers 54 }; 55 static already_AddRefed<CanvasClient> CreateCanvasClient(CanvasClientType aType, 56 CompositableForwarder* aFwd, 57 TextureFlags aFlags); 58 CanvasClient(CompositableForwarder * aFwd,TextureFlags aFlags)59 CanvasClient(CompositableForwarder* aFwd, TextureFlags aFlags) 60 : CompositableClient(aFwd, aFlags) 61 , mFrameID(0) 62 { 63 mTextureFlags = aFlags; 64 } 65 ~CanvasClient()66 virtual ~CanvasClient() {} 67 Clear()68 virtual void Clear() {}; 69 70 virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) = 0; 71 AddTextureClient(TextureClient * aTexture)72 virtual bool AddTextureClient(TextureClient* aTexture) override 73 { 74 ++mFrameID; 75 return CompositableClient::AddTextureClient(aTexture); 76 } 77 UpdateAsync(AsyncCanvasRenderer * aRenderer)78 virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) {} 79 UpdateFromTexture(TextureClient * aTexture)80 virtual void UpdateFromTexture(TextureClient* aTexture) {} 81 Updated()82 virtual void Updated() { } 83 84 protected: 85 int32_t mFrameID; 86 }; 87 88 // Used for 2D canvases and WebGL canvas on non-GL systems where readback is requried. 89 class CanvasClient2D : public CanvasClient 90 { 91 public: CanvasClient2D(CompositableForwarder * aLayerForwarder,TextureFlags aFlags)92 CanvasClient2D(CompositableForwarder* aLayerForwarder, 93 TextureFlags aFlags) 94 : CanvasClient(aLayerForwarder, aFlags) 95 { 96 } 97 GetTextureInfo()98 TextureInfo GetTextureInfo() const override 99 { 100 return TextureInfo(CompositableType::IMAGE, mTextureFlags); 101 } 102 Clear()103 virtual void Clear() override 104 { 105 mBackBuffer = mFrontBuffer = nullptr; 106 } 107 108 virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) override; 109 110 virtual void UpdateFromTexture(TextureClient* aBuffer) override; 111 AddTextureClient(TextureClient * aTexture)112 virtual bool AddTextureClient(TextureClient* aTexture) override 113 { 114 return CanvasClient::AddTextureClient(aTexture); 115 } 116 OnDetach()117 virtual void OnDetach() override 118 { 119 mBackBuffer = mFrontBuffer = nullptr; 120 } 121 122 private: 123 already_AddRefed<TextureClient> 124 CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat, 125 gfx::IntSize aSize, 126 TextureFlags aFlags, 127 ClientCanvasLayer* aLayer); 128 129 RefPtr<TextureClient> mBackBuffer; 130 RefPtr<TextureClient> mFrontBuffer; 131 // We store this texture separately to make sure it is not written into 132 // in Update() if for some silly reason we end up alternating between 133 // UpdateFromTexture and Update. 134 // This code is begging for a cleanup. The situation described above should 135 // not be made possible. 136 RefPtr<TextureClient> mBufferProviderTexture; 137 }; 138 139 // Used for GL canvases where we don't need to do any readback, i.e., with a 140 // GL backend. 141 class CanvasClientSharedSurface : public CanvasClient 142 { 143 private: 144 RefPtr<SharedSurfaceTextureClient> mShSurfClient; 145 RefPtr<TextureClient> mReadbackClient; 146 RefPtr<TextureClient> mFront; 147 RefPtr<TextureClient> mNewFront; 148 149 void ClearSurfaces(); 150 151 public: 152 CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder, 153 TextureFlags aFlags); 154 155 ~CanvasClientSharedSurface(); 156 GetTextureInfo()157 virtual TextureInfo GetTextureInfo() const override { 158 return TextureInfo(CompositableType::IMAGE); 159 } 160 Clear()161 virtual void Clear() override { 162 ClearSurfaces(); 163 } 164 165 virtual void Update(gfx::IntSize aSize, 166 ClientCanvasLayer* aLayer) override; 167 void UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer); 168 169 virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) override; 170 171 virtual void Updated() override; 172 173 virtual void OnDetach() override; 174 }; 175 176 /** 177 * Used for OMT<canvas> uploads using the image bridge protocol. 178 * Actual CanvasClient is on the ImageBridgeChild thread, so we 179 * only forward its AsyncID here 180 */ 181 class CanvasClientBridge final : public CanvasClient 182 { 183 public: CanvasClientBridge(CompositableForwarder * aLayerForwarder,TextureFlags aFlags)184 CanvasClientBridge(CompositableForwarder* aLayerForwarder, 185 TextureFlags aFlags) 186 : CanvasClient(aLayerForwarder, aFlags) 187 , mAsyncID(0) 188 , mLayer(nullptr) 189 { 190 } 191 GetTextureInfo()192 TextureInfo GetTextureInfo() const override 193 { 194 return TextureInfo(CompositableType::IMAGE); 195 } 196 Update(gfx::IntSize aSize,ClientCanvasLayer * aLayer)197 virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) override 198 { 199 } 200 201 virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) override; 202 SetLayer(ShadowableLayer * aLayer)203 void SetLayer(ShadowableLayer* aLayer) 204 { 205 mLayer = aLayer; 206 } 207 208 protected: 209 uint64_t mAsyncID; 210 ShadowableLayer* mLayer; 211 }; 212 213 } // namespace layers 214 } // namespace mozilla 215 216 #endif 217