summaryrefslogtreecommitdiffstats
path: root/gfx/layers/AsyncCanvasRenderer.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/AsyncCanvasRenderer.h')
-rw-r--r--gfx/layers/AsyncCanvasRenderer.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/gfx/layers/AsyncCanvasRenderer.h b/gfx/layers/AsyncCanvasRenderer.h
new file mode 100644
index 000000000..404695de4
--- /dev/null
+++ b/gfx/layers/AsyncCanvasRenderer.h
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
+#define MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_
+
+#include "LayersTypes.h"
+#include "mozilla/gfx/Point.h" // for IntSize
+#include "mozilla/Mutex.h"
+#include "nsCOMPtr.h" // for nsCOMPtr
+
+class nsICanvasRenderingContextInternal;
+class nsIInputStream;
+class nsIThread;
+
+namespace mozilla {
+
+namespace gfx {
+class DataSourceSurface;
+}
+
+namespace gl {
+class GLContext;
+}
+
+namespace dom {
+class HTMLCanvasElement;
+}
+
+namespace layers {
+
+class CanvasClient;
+class TextureClient;
+
+/**
+ * Since HTMLCanvasElement and OffscreenCanvas are not thread-safe, we create
+ * AsyncCanvasRenderer which is thread-safe wrapper object for communicating
+ * among main, worker and ImageBridgeChild threads.
+ *
+ * Each HTMLCanvasElement object is responsible for creating
+ * AsyncCanvasRenderer object. Once Canvas is transfered to worker,
+ * OffscreenCanvas will keep reference pointer of this object.
+ *
+ * Sometimes main thread needs AsyncCanvasRenderer's result, such as layers
+ * fallback to BasicLayerManager or calling toDataURL in Javascript. Simply call
+ * GetSurface() in main thread will readback the result to mSurface.
+ *
+ * If layers backend is LAYERS_CLIENT, this object will pass to ImageBridgeChild
+ * for submitting frames to Compositor.
+ */
+class AsyncCanvasRenderer final
+{
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncCanvasRenderer)
+
+public:
+ AsyncCanvasRenderer();
+
+ void NotifyElementAboutAttributesChanged();
+ void NotifyElementAboutInvalidation();
+
+ void SetCanvasClient(CanvasClient* aClient);
+
+ void SetWidth(uint32_t aWidth)
+ {
+ mWidth = aWidth;
+ }
+
+ void SetHeight(uint32_t aHeight)
+ {
+ mHeight = aHeight;
+ }
+
+ void SetIsAlphaPremultiplied(bool aIsAlphaPremultiplied)
+ {
+ mIsAlphaPremultiplied = aIsAlphaPremultiplied;
+ }
+
+ // Active thread means the thread which spawns GLContext.
+ void SetActiveThread();
+ void ResetActiveThread();
+
+ // This will readback surface and return the surface
+ // in the DataSourceSurface.
+ // Can be called in main thread only.
+ already_AddRefed<gfx::DataSourceSurface> GetSurface();
+
+ // For SharedSurface_Basic case, before the frame sending to the compositor,
+ // we readback it to a texture client because SharedSurface_Basic cannot shared.
+ // We don't want to readback it again here, so just copy the content of that
+ // texture client here to avoid readback again.
+ void CopyFromTextureClient(TextureClient *aClient);
+
+ // Readback current WebGL's content and convert it to InputStream. This
+ // function called GetSurface implicitly and GetSurface handles only get
+ // called in the main thread. So this function can be called in main thread.
+ nsresult
+ GetInputStream(const char *aMimeType,
+ const char16_t *aEncoderOptions,
+ nsIInputStream **aStream);
+
+ gfx::IntSize GetSize() const
+ {
+ return gfx::IntSize(mWidth, mHeight);
+ }
+
+ uint64_t GetCanvasClientAsyncID() const
+ {
+ return mCanvasClientAsyncID;
+ }
+
+ CanvasClient* GetCanvasClient() const
+ {
+ return mCanvasClient;
+ }
+
+ already_AddRefed<nsIThread> GetActiveThread();
+
+ // The lifetime is controllered by HTMLCanvasElement.
+ // Only accessed in main thread.
+ dom::HTMLCanvasElement* mHTMLCanvasElement;
+
+ // Only accessed in active thread.
+ nsICanvasRenderingContextInternal* mContext;
+
+ // We need to keep a reference to the context around here, otherwise the
+ // canvas' surface texture destructor will deref and destroy it too early
+ // Only accessed in active thread.
+ RefPtr<gl::GLContext> mGLContext;
+private:
+
+ virtual ~AsyncCanvasRenderer();
+
+ // Readback current WebGL's content and return it as DataSourceSurface.
+ already_AddRefed<gfx::DataSourceSurface> UpdateTarget();
+
+ bool mIsAlphaPremultiplied;
+
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint64_t mCanvasClientAsyncID;
+
+ // The lifetime of this pointer is controlled by OffscreenCanvas
+ // Can be accessed in active thread and ImageBridge thread.
+ // But we never accessed it at the same time on both thread. So no
+ // need to protect this member.
+ CanvasClient* mCanvasClient;
+
+ // When backend is LAYER_BASIC and SharedSurface type is Basic.
+ // CanvasClient will readback the GLContext to a TextureClient
+ // in order to send frame to compositor. To avoid readback again,
+ // we copy from this TextureClient to this mSurfaceForBasic directly
+ // by calling CopyFromTextureClient().
+ RefPtr<gfx::DataSourceSurface> mSurfaceForBasic;
+
+ // Protect non thread-safe objects.
+ Mutex mMutex;
+
+ // Can be accessed in any thread, need protect by mutex.
+ nsCOMPtr<nsIThread> mActiveThread;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // MOZILLA_LAYERS_ASYNCCANVASRENDERER_H_